diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index d19d22ca04b4..028914cb67fd 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -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(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(Name) | Identifier) {} + + /// \brief Create an offsetof node that refers into a C++ base class. + explicit OffsetOfNode(const CXXBaseSpecifier *Base) + : Range(), Data(reinterpret_cast(Base) | OffsetOfNode::Base) {} + + /// \brief Determine what kind of offsetof node this is. + Kind getKind() const { return static_cast(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(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(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(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(Name) | Identifier) { } - - /// \brief Create an offsetof node that refers into a C++ base class. - explicit OffsetOfNode(const CXXBaseSpecifier *Base) - : Range(), Data(reinterpret_cast(Base) | OffsetOfNode::Base) {} - - /// \brief Determine what kind of offsetof node this is. - Kind getKind() const { - return static_cast(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(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(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 { 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) const { + return NumComps; + } + OffsetOfExpr(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, ArrayRef comps, ArrayRef exprs, @@ -1905,12 +1907,12 @@ public: const OffsetOfNode &getComponent(unsigned Idx) const { assert(Idx < NumComps && "Subscript out of range"); - return reinterpret_cast (this + 1)[Idx]; + return getTrailingObjects()[Idx]; } void setComponent(unsigned Idx, OffsetOfNode ON) { assert(Idx < NumComps && "Subscript out of range"); - reinterpret_cast (this + 1)[Idx] = ON; + getTrailingObjects()[Idx] = ON; } unsigned getNumComponents() const { @@ -1919,17 +1921,17 @@ public: Expr* getIndexExpr(unsigned Idx) { assert(Idx < NumExprs && "Subscript out of range"); - return reinterpret_cast( - reinterpret_cast(this+1) + NumComps)[Idx]; + return getTrailingObjects()[Idx]; } + const Expr *getIndexExpr(unsigned Idx) const { - return const_cast(this)->getIndexExpr(Idx); + assert(Idx < NumExprs && "Subscript out of range"); + return getTrailingObjects()[Idx]; } void setIndexExpr(unsigned Idx, Expr* E) { assert(Idx < NumComps && "Subscript out of range"); - reinterpret_cast( - reinterpret_cast(this+1) + NumComps)[Idx] = E; + getTrailingObjects()[Idx] = E; } unsigned getNumExpressions() const { @@ -1945,11 +1947,10 @@ public: // Iterators child_range children() { - Stmt **begin = - reinterpret_cast(reinterpret_cast(this + 1) - + NumComps); + Stmt **begin = reinterpret_cast(getTrailingObjects()); return child_range(begin, begin + NumExprs); } + friend TrailingObjects; }; /// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 7e58653efe18..a000a7de83bd 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1314,9 +1314,8 @@ OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type, ArrayRef comps, ArrayRef exprs, SourceLocation RParenLoc) { - void *Mem = C.Allocate(sizeof(OffsetOfExpr) + - sizeof(OffsetOfNode) * comps.size() + - sizeof(Expr*) * exprs.size()); + void *Mem = C.Allocate( + totalSizeToAlloc(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(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(); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6101485f4c25..c4c4398c3622 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -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(); 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); diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 7706d0e8f8dc..e55b2fc19a1a 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -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. diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 90bedcc1fe57..175a43abbf61 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -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; } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 442903862459..725d96f29877 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -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()->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; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9de32d55f26a..5d0c6057f54f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11189,7 +11189,6 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, bool DidWarnAboutNonPOD = false; QualType CurrentType = ArgTy; - typedef OffsetOfExpr::OffsetOfNode OffsetOfNode; SmallVector Comps; SmallVector Exprs; for (const OffsetOfComponent &OC : Components) { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index f5a732847276..e0a9653eb93b 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8063,16 +8063,15 @@ TreeTransform::TransformOffsetOfExpr(OffsetOfExpr *E) { // template code that we don't care. bool ExprChanged = false; typedef Sema::OffsetOfComponent Component; - typedef OffsetOfExpr::OffsetOfNode Node; SmallVector 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::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::TransformOffsetOfExpr(OffsetOfExpr *E) { break; - case Node::Base: + case OffsetOfNode::Base: // Will be recomputed during the rebuild. continue; } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 84622cf8ef74..4082dec48c0a 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -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(Record[Idx++]); + OffsetOfNode::Kind Kind = static_cast(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)); - break; - - case Node::Field: - E->setComponent(I, Node(Start, ReadDeclAs(Record, Idx), End)); + case OffsetOfNode::Array: + E->setComponent(I, OffsetOfNode(Start, Record[Idx++], End)); break; - case Node::Identifier: - E->setComponent(I, - Node(Start, - Reader.GetIdentifierInfo(F, Record, Idx), - End)); + case OffsetOfNode::Field: + E->setComponent( + I, OffsetOfNode(Start, ReadDeclAs(Record, Idx), End)); break; - - case Node::Base: { + + case OffsetOfNode::Identifier: + E->setComponent( + I, + OffsetOfNode(Start, Reader.GetIdentifierInfo(F, Record, Idx), End)); + break; + + 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; } } diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 849c6fa4ecf9..e52ed052d3bc 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -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; } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 477bf0902ba1..dbda13c23532 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -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: