[TrailingObjects] Convert OffsetOfExpr.
authorJames Y Knight <jyknight@google.com>
Tue, 29 Dec 2015 22:31:18 +0000 (22:31 +0000)
committerJames Y Knight <jyknight@google.com>
Tue, 29 Dec 2015 22:31:18 +0000 (22:31 +0000)
That necessitated moving the OffsetOfNode class out of OffsetOfExpr.

llvm-svn: 256590

clang/include/clang/AST/Expr.h
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/CodeGen/CGExprScalar.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/tools/libclang/CIndex.cpp

index d19d22c..028914c 100644 (file)
@@ -1749,6 +1749,99 @@ public:
   child_range children() { return child_range(&Val, &Val+1); }
 };
 
+/// Helper class for OffsetOfExpr.
+
+// __builtin_offsetof(type, identifier(.identifier|[expr])*)
+class OffsetOfNode {
+public:
+  /// \brief The kind of offsetof node we have.
+  enum Kind {
+    /// \brief An index into an array.
+    Array = 0x00,
+    /// \brief A field.
+    Field = 0x01,
+    /// \brief A field in a dependent type, known only by its name.
+    Identifier = 0x02,
+    /// \brief An implicit indirection through a C++ base class, when the
+    /// field found is in a base class.
+    Base = 0x03
+  };
+
+private:
+  enum { MaskBits = 2, Mask = 0x03 };
+
+  /// \brief The source range that covers this part of the designator.
+  SourceRange Range;
+
+  /// \brief The data describing the designator, which comes in three
+  /// different forms, depending on the lower two bits.
+  ///   - An unsigned index into the array of Expr*'s stored after this node
+  ///     in memory, for [constant-expression] designators.
+  ///   - A FieldDecl*, for references to a known field.
+  ///   - An IdentifierInfo*, for references to a field with a given name
+  ///     when the class type is dependent.
+  ///   - A CXXBaseSpecifier*, for references that look at a field in a
+  ///     base class.
+  uintptr_t Data;
+
+public:
+  /// \brief Create an offsetof node that refers to an array element.
+  OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
+               SourceLocation RBracketLoc)
+      : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) {}
+
+  /// \brief Create an offsetof node that refers to a field.
+  OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, SourceLocation NameLoc)
+      : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
+        Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) {}
+
+  /// \brief Create an offsetof node that refers to an identifier.
+  OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
+               SourceLocation NameLoc)
+      : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
+        Data(reinterpret_cast<uintptr_t>(Name) | Identifier) {}
+
+  /// \brief Create an offsetof node that refers into a C++ base class.
+  explicit OffsetOfNode(const CXXBaseSpecifier *Base)
+      : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
+
+  /// \brief Determine what kind of offsetof node this is.
+  Kind getKind() const { return static_cast<Kind>(Data & Mask); }
+
+  /// \brief For an array element node, returns the index into the array
+  /// of expressions.
+  unsigned getArrayExprIndex() const {
+    assert(getKind() == Array);
+    return Data >> 2;
+  }
+
+  /// \brief For a field offsetof node, returns the field.
+  FieldDecl *getField() const {
+    assert(getKind() == Field);
+    return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
+  }
+
+  /// \brief For a field or identifier offsetof node, returns the name of
+  /// the field.
+  IdentifierInfo *getFieldName() const;
+
+  /// \brief For a base class node, returns the base specifier.
+  CXXBaseSpecifier *getBase() const {
+    assert(getKind() == Base);
+    return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);
+  }
+
+  /// \brief Retrieve the source range that covers this offsetof node.
+  ///
+  /// For an array element node, the source range contains the locations of
+  /// the square brackets. For a field or identifier node, the source range
+  /// contains the location of the period (if there is one) and the
+  /// identifier.
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+};
+
 /// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
 /// offsetof(record-type, member-designator). For example, given:
 /// @code
@@ -1763,104 +1856,9 @@ public:
 /// @endcode
 /// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
 
-class OffsetOfExpr : public Expr {
-public:
-  // __builtin_offsetof(type, identifier(.identifier|[expr])*)
-  class OffsetOfNode {
-  public:
-    /// \brief The kind of offsetof node we have.
-    enum Kind {
-      /// \brief An index into an array.
-      Array = 0x00,
-      /// \brief A field.
-      Field = 0x01,
-      /// \brief A field in a dependent type, known only by its name.
-      Identifier = 0x02,
-      /// \brief An implicit indirection through a C++ base class, when the
-      /// field found is in a base class.
-      Base = 0x03
-    };
-
-  private:
-    enum { MaskBits = 2, Mask = 0x03 };
-
-    /// \brief The source range that covers this part of the designator.
-    SourceRange Range;
-
-    /// \brief The data describing the designator, which comes in three
-    /// different forms, depending on the lower two bits.
-    ///   - An unsigned index into the array of Expr*'s stored after this node
-    ///     in memory, for [constant-expression] designators.
-    ///   - A FieldDecl*, for references to a known field.
-    ///   - An IdentifierInfo*, for references to a field with a given name
-    ///     when the class type is dependent.
-    ///   - A CXXBaseSpecifier*, for references that look at a field in a
-    ///     base class.
-    uintptr_t Data;
-
-  public:
-    /// \brief Create an offsetof node that refers to an array element.
-    OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
-                 SourceLocation RBracketLoc)
-      : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) { }
-
-    /// \brief Create an offsetof node that refers to a field.
-    OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field,
-                 SourceLocation NameLoc)
-      : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
-        Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) { }
-
-    /// \brief Create an offsetof node that refers to an identifier.
-    OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
-                 SourceLocation NameLoc)
-      : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
-        Data(reinterpret_cast<uintptr_t>(Name) | Identifier) { }
-
-    /// \brief Create an offsetof node that refers into a C++ base class.
-    explicit OffsetOfNode(const CXXBaseSpecifier *Base)
-      : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
-
-    /// \brief Determine what kind of offsetof node this is.
-    Kind getKind() const {
-      return static_cast<Kind>(Data & Mask);
-    }
-
-    /// \brief For an array element node, returns the index into the array
-    /// of expressions.
-    unsigned getArrayExprIndex() const {
-      assert(getKind() == Array);
-      return Data >> 2;
-    }
-
-    /// \brief For a field offsetof node, returns the field.
-    FieldDecl *getField() const {
-      assert(getKind() == Field);
-      return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
-    }
-
-    /// \brief For a field or identifier offsetof node, returns the name of
-    /// the field.
-    IdentifierInfo *getFieldName() const;
-
-    /// \brief For a base class node, returns the base specifier.
-    CXXBaseSpecifier *getBase() const {
-      assert(getKind() == Base);
-      return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);
-    }
-
-    /// \brief Retrieve the source range that covers this offsetof node.
-    ///
-    /// For an array element node, the source range contains the locations of
-    /// the square brackets. For a field or identifier node, the source range
-    /// contains the location of the period (if there is one) and the
-    /// identifier.
-    SourceRange getSourceRange() const LLVM_READONLY { return Range; }
-    SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
-    SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
-  };
-
-private:
-
+class OffsetOfExpr final
+    : public Expr,
+      private llvm::TrailingObjects<OffsetOfExpr, OffsetOfNode, Expr *> {
   SourceLocation OperatorLoc, RParenLoc;
   // Base type;
   TypeSourceInfo *TSInfo;
@@ -1869,6 +1867,10 @@ private:
   // Number of sub-expressions (i.e. array subscript expressions).
   unsigned NumExprs;
 
+  size_t numTrailingObjects(OverloadToken<OffsetOfNode>) const {
+    return NumComps;
+  }
+
   OffsetOfExpr(const ASTContext &C, QualType type,
                SourceLocation OperatorLoc, TypeSourceInfo *tsi,
                ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
@@ -1905,12 +1907,12 @@ public:
 
   const OffsetOfNode &getComponent(unsigned Idx) const {
     assert(Idx < NumComps && "Subscript out of range");
-    return reinterpret_cast<const OffsetOfNode *> (this + 1)[Idx];
+    return getTrailingObjects<OffsetOfNode>()[Idx];
   }
 
   void setComponent(unsigned Idx, OffsetOfNode ON) {
     assert(Idx < NumComps && "Subscript out of range");
-    reinterpret_cast<OffsetOfNode *> (this + 1)[Idx] = ON;
+    getTrailingObjects<OffsetOfNode>()[Idx] = ON;
   }
 
   unsigned getNumComponents() const {
@@ -1919,17 +1921,17 @@ public:
 
   Expr* getIndexExpr(unsigned Idx) {
     assert(Idx < NumExprs && "Subscript out of range");
-    return reinterpret_cast<Expr **>(
-                    reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx];
+    return getTrailingObjects<Expr *>()[Idx];
   }
+
   const Expr *getIndexExpr(unsigned Idx) const {
-    return const_cast<OffsetOfExpr*>(this)->getIndexExpr(Idx);
+    assert(Idx < NumExprs && "Subscript out of range");
+    return getTrailingObjects<Expr *>()[Idx];
   }
 
   void setIndexExpr(unsigned Idx, Expr* E) {
     assert(Idx < NumComps && "Subscript out of range");
-    reinterpret_cast<Expr **>(
-                reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx] = E;
+    getTrailingObjects<Expr *>()[Idx] = E;
   }
 
   unsigned getNumExpressions() const {
@@ -1945,11 +1947,10 @@ public:
 
   // Iterators
   child_range children() {
-    Stmt **begin =
-      reinterpret_cast<Stmt**>(reinterpret_cast<OffsetOfNode*>(this + 1)
-                               + NumComps);
+    Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
     return child_range(begin, begin + NumExprs);
   }
+  friend TrailingObjects;
 };
 
 /// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
index 7e58653..a000a7d 100644 (file)
@@ -1314,9 +1314,8 @@ OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type,
                                    ArrayRef<OffsetOfNode> comps,
                                    ArrayRef<Expr*> exprs,
                                    SourceLocation RParenLoc) {
-  void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
-                         sizeof(OffsetOfNode) * comps.size() +
-                         sizeof(Expr*) * exprs.size());
+  void *Mem = C.Allocate(
+      totalSizeToAlloc<OffsetOfNode, Expr *>(comps.size(), exprs.size()));
 
   return new (Mem) OffsetOfExpr(C, type, OperatorLoc, tsi, comps, exprs,
                                 RParenLoc);
@@ -1324,9 +1323,8 @@ OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type,
 
 OffsetOfExpr *OffsetOfExpr::CreateEmpty(const ASTContext &C,
                                         unsigned numComps, unsigned numExprs) {
-  void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
-                         sizeof(OffsetOfNode) * numComps +
-                         sizeof(Expr*) * numExprs);
+  void *Mem =
+      C.Allocate(totalSizeToAlloc<OffsetOfNode, Expr *>(numComps, numExprs));
   return new (Mem) OffsetOfExpr(numComps, numExprs);
 }
 
@@ -1356,7 +1354,7 @@ OffsetOfExpr::OffsetOfExpr(const ASTContext &C, QualType type,
   }
 }
 
-IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const {
+IdentifierInfo *OffsetOfNode::getFieldName() const {
   assert(getKind() == Field || getKind() == Identifier);
   if (getKind() == Field)
     return getField()->getIdentifier();
index 6101485..c4c4398 100644 (file)
@@ -7617,9 +7617,9 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
     return Error(OOE);
   QualType CurrentType = OOE->getTypeSourceInfo()->getType();
   for (unsigned i = 0; i != n; ++i) {
-    OffsetOfExpr::OffsetOfNode ON = OOE->getComponent(i);
+    OffsetOfNode ON = OOE->getComponent(i);
     switch (ON.getKind()) {
-    case OffsetOfExpr::OffsetOfNode::Array: {
+    case OffsetOfNode::Array: {
       const Expr *Idx = OOE->getIndexExpr(ON.getArrayExprIndex());
       APSInt IdxResult;
       if (!EvaluateInteger(Idx, IdxResult, Info))
@@ -7633,7 +7633,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
       break;
     }
 
-    case OffsetOfExpr::OffsetOfNode::Field: {
+    case OffsetOfNode::Field: {
       FieldDecl *MemberDecl = ON.getField();
       const RecordType *RT = CurrentType->getAs<RecordType>();
       if (!RT)
@@ -7648,10 +7648,10 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
       break;
     }
 
-    case OffsetOfExpr::OffsetOfNode::Identifier:
+    case OffsetOfNode::Identifier:
       llvm_unreachable("dependent __builtin_offsetof");
 
-    case OffsetOfExpr::OffsetOfNode::Base: {
+    case OffsetOfNode::Base: {
       CXXBaseSpecifier *BaseSpec = ON.getBase();
       if (BaseSpec->isVirtual())
         return Error(OOE);
index 7706d0e..e55b2fc 100644 (file)
@@ -1305,8 +1305,8 @@ void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
   OS << ", ";
   bool PrintedSomething = false;
   for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
-    OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i);
-    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) {
+    OffsetOfNode ON = Node->getComponent(i);
+    if (ON.getKind() == OffsetOfNode::Array) {
       // Array node
       OS << "[";
       PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
@@ -1316,7 +1316,7 @@ void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
     }
 
     // Skip implicit base indirections.
-    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base)
+    if (ON.getKind() == OffsetOfNode::Base)
       continue;
 
     // Field or identifier node.
index 90bedcc..175a43a 100644 (file)
@@ -675,22 +675,22 @@ void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
   VisitType(S->getTypeSourceInfo()->getType());
   unsigned n = S->getNumComponents();
   for (unsigned i = 0; i < n; ++i) {
-    const OffsetOfExpr::OffsetOfNode& ON = S->getComponent(i);
+    const OffsetOfNode &ON = S->getComponent(i);
     ID.AddInteger(ON.getKind());
     switch (ON.getKind()) {
-    case OffsetOfExpr::OffsetOfNode::Array:
+    case OffsetOfNode::Array:
       // Expressions handled below.
       break;
 
-    case OffsetOfExpr::OffsetOfNode::Field:
+    case OffsetOfNode::Field:
       VisitDecl(ON.getField());
       break;
 
-    case OffsetOfExpr::OffsetOfNode::Identifier:
+    case OffsetOfNode::Identifier:
       ID.AddPointer(ON.getFieldName());
       break;
-        
-    case OffsetOfExpr::OffsetOfNode::Base:
+
+    case OffsetOfNode::Base:
       // These nodes are implicit, and therefore don't need profiling.
       break;
     }
index 4429038..725d96f 100644 (file)
@@ -1924,10 +1924,10 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
   llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
   QualType CurrentType = E->getTypeSourceInfo()->getType();
   for (unsigned i = 0; i != n; ++i) {
-    OffsetOfExpr::OffsetOfNode ON = E->getComponent(i);
+    OffsetOfNode ON = E->getComponent(i);
     llvm::Value *Offset = nullptr;
     switch (ON.getKind()) {
-    case OffsetOfExpr::OffsetOfNode::Array: {
+    case OffsetOfNode::Array: {
       // Compute the index
       Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
       llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
@@ -1947,7 +1947,7 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
       break;
     }
 
-    case OffsetOfExpr::OffsetOfNode::Field: {
+    case OffsetOfNode::Field: {
       FieldDecl *MemberDecl = ON.getField();
       RecordDecl *RD = CurrentType->getAs<RecordType>()->getDecl();
       const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
@@ -1973,10 +1973,10 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
       break;
     }
 
-    case OffsetOfExpr::OffsetOfNode::Identifier:
+    case OffsetOfNode::Identifier:
       llvm_unreachable("dependent __builtin_offsetof");
 
-    case OffsetOfExpr::OffsetOfNode::Base: {
+    case OffsetOfNode::Base: {
       if (ON.getBase()->isVirtual()) {
         CGF.ErrorUnsupported(E, "virtual base in offsetof");
         continue;
index 9de32d5..5d0c605 100644 (file)
@@ -11189,7 +11189,6 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
   
   bool DidWarnAboutNonPOD = false;
   QualType CurrentType = ArgTy;
-  typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
   SmallVector<OffsetOfNode, 4> Comps;
   SmallVector<Expr*, 4> Exprs;
   for (const OffsetOfComponent &OC : Components) {
index f5a7328..e0a9653 100644 (file)
@@ -8063,16 +8063,15 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
   // template code that we don't care.
   bool ExprChanged = false;
   typedef Sema::OffsetOfComponent Component;
-  typedef OffsetOfExpr::OffsetOfNode Node;
   SmallVector<Component, 4> Components;
   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
-    const Node &ON = E->getComponent(I);
+    const OffsetOfNode &ON = E->getComponent(I);
     Component Comp;
     Comp.isBrackets = true;
     Comp.LocStart = ON.getSourceRange().getBegin();
     Comp.LocEnd = ON.getSourceRange().getEnd();
     switch (ON.getKind()) {
-    case Node::Array: {
+    case OffsetOfNode::Array: {
       Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
       ExprResult Index = getDerived().TransformExpr(FromIndex);
       if (Index.isInvalid())
@@ -8084,8 +8083,8 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
       break;
     }
 
-    case Node::Field:
-    case Node::Identifier:
+    case OffsetOfNode::Field:
+    case OffsetOfNode::Identifier:
       Comp.isBrackets = false;
       Comp.U.IdentInfo = ON.getFieldName();
       if (!Comp.U.IdentInfo)
@@ -8093,7 +8092,7 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
 
       break;
 
-    case Node::Base:
+    case OffsetOfNode::Base:
       // Will be recomputed during the rebuild.
       continue;
     }
index 84622cf..4082dec 100644 (file)
@@ -550,7 +550,6 @@ void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
 }
 
 void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
-  typedef OffsetOfExpr::OffsetOfNode Node;
   VisitExpr(E);
   assert(E->getNumComponents() == Record[Idx]);
   ++Idx;
@@ -560,29 +559,29 @@ void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
   E->setRParenLoc(ReadSourceLocation(Record, Idx));
   E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
-    Node::Kind Kind = static_cast<Node::Kind>(Record[Idx++]);
+    OffsetOfNode::Kind Kind = static_cast<OffsetOfNode::Kind>(Record[Idx++]);
     SourceLocation Start = ReadSourceLocation(Record, Idx);
     SourceLocation End = ReadSourceLocation(Record, Idx);
     switch (Kind) {
-    case Node::Array:
-      E->setComponent(I, Node(Start, Record[Idx++], End));
+    case OffsetOfNode::Array:
+      E->setComponent(I, OffsetOfNode(Start, Record[Idx++], End));
       break;
-        
-    case Node::Field:
-      E->setComponent(I, Node(Start, ReadDeclAs<FieldDecl>(Record, Idx), End));
+
+    case OffsetOfNode::Field:
+      E->setComponent(
+          I, OffsetOfNode(Start, ReadDeclAs<FieldDecl>(Record, Idx), End));
       break;
 
-    case Node::Identifier:
-      E->setComponent(I, 
-                      Node(Start, 
-                           Reader.GetIdentifierInfo(F, Record, Idx),
-                           End));
+    case OffsetOfNode::Identifier:
+      E->setComponent(
+          I,
+          OffsetOfNode(Start, Reader.GetIdentifierInfo(F, Record, Idx), End));
       break;
-        
-    case Node::Base: {
+
+    case OffsetOfNode::Base: {
       CXXBaseSpecifier *Base = new (Reader.getContext()) CXXBaseSpecifier();
       *Base = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
-      E->setComponent(I, Node(Base));
+      E->setComponent(I, OffsetOfNode(Base));
       break;
     }
     }
index 849c6fa..e52ed05 100644 (file)
@@ -484,24 +484,24 @@ void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
   Writer.AddSourceLocation(E->getRParenLoc(), Record);
   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
-    const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
+    const OffsetOfNode &ON = E->getComponent(I);
     Record.push_back(ON.getKind()); // FIXME: Stable encoding
     Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
     Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
     switch (ON.getKind()) {
-    case OffsetOfExpr::OffsetOfNode::Array:
+    case OffsetOfNode::Array:
       Record.push_back(ON.getArrayExprIndex());
       break;
-        
-    case OffsetOfExpr::OffsetOfNode::Field:
+
+    case OffsetOfNode::Field:
       Writer.AddDeclRef(ON.getField(), Record);
       break;
-        
-    case OffsetOfExpr::OffsetOfNode::Identifier:
+
+    case OffsetOfNode::Identifier:
       Writer.AddIdentifierRef(ON.getFieldName(), Record);
       break;
-        
-    case OffsetOfExpr::OffsetOfNode::Base:
+
+    case OffsetOfNode::Base:
       Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
       break;
     }
index 477bf09..dbda13c 100644 (file)
@@ -2434,7 +2434,6 @@ void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
 void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
   // Visit the components of the offsetof expression.
   for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
-    typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
     const OffsetOfNode &Node = E->getComponent(I-1);
     switch (Node.getKind()) {
     case OffsetOfNode::Array: