diff options
Diffstat (limited to 'include/clang/AST/RecursiveASTVisitor.h')
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 325 |
1 files changed, 178 insertions, 147 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 232e47b..921b799 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -143,6 +143,10 @@ public: /// \brief Return whether this visitor should recurse into /// template instantiations. bool shouldVisitTemplateInstantiations() const { return false; } + + /// \brief Return whether this visitor should recurse into the types of + /// TypeLocs. + bool shouldWalkTypesOfTypeLocs() const { return true; } /// \brief Recursively visit a statement or expression, by /// dispatching to Traverse*() based on the argument's dynamic type. @@ -211,7 +215,7 @@ public: /// be overridden for clients that need access to the name. /// /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseConstructorInitializer(CXXBaseOrMemberInitializer *Init); + bool TraverseConstructorInitializer(CXXCtorInitializer *Init); // ---- Methods on Stmts ---- @@ -368,7 +372,7 @@ private: bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); bool TraverseClassInstantiations(ClassTemplateDecl* D, Decl *Pattern); bool TraverseFunctionInstantiations(FunctionTemplateDecl* D) ; - bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, + bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, unsigned Count); bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL); bool TraverseRecordHelper(RecordDecl *D); @@ -393,7 +397,7 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) { if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { switch (BinOp->getOpcode()) { #define OPERATOR(NAME) \ - case BO_##NAME: DISPATCH(Bin##PtrMemD, BinaryOperator, S); + case BO_##NAME: DISPATCH(Bin##NAME, BinaryOperator, S); BINOP_LIST() #undef OPERATOR @@ -438,7 +442,8 @@ bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) { switch (T->getTypeClass()) { #define ABSTRACT_TYPE(CLASS, BASE) #define TYPE(CLASS, BASE) \ - case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, T.getTypePtr()); + case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \ + const_cast<Type*>(T.getTypePtr())); #include "clang/AST/TypeNodes.def" } @@ -531,7 +536,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( return getDerived().TraverseType(Arg.getAsType()); case TemplateArgument::Template: - return getDerived().TraverseTemplateName(Arg.getAsTemplate()); + case TemplateArgument::TemplateExpansion: + return getDerived().TraverseTemplateName( + Arg.getAsTemplateOrTemplatePattern()); case TemplateArgument::Expression: return getDerived().TraverseStmt(Arg.getAsExpr()); @@ -566,7 +573,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( } case TemplateArgument::Template: - return getDerived().TraverseTemplateName(Arg.getAsTemplate()); + case TemplateArgument::TemplateExpansion: + return getDerived().TraverseTemplateName( + Arg.getAsTemplateOrTemplatePattern()); case TemplateArgument::Expression: return getDerived().TraverseStmt(ArgLoc.getSourceExpression()); @@ -592,7 +601,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments( template<typename Derived> bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( - CXXBaseOrMemberInitializer *Init) { + CXXCtorInitializer *Init) { // FIXME: recurse on TypeLoc of the base initializer if isBaseInitializer()? if (Init->isWritten()) TRY_TO(TraverseStmt(Init->getInit())); @@ -706,10 +715,15 @@ DEF_TRAVERSE_TYPE(DecltypeType, { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPE(AutoType, { + TRY_TO(TraverseType(T->getDeducedType())); + }) + DEF_TRAVERSE_TYPE(RecordType, { }) DEF_TRAVERSE_TYPE(EnumType, { }) DEF_TRAVERSE_TYPE(TemplateTypeParmType, { }) DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { }) +DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { }) DEF_TRAVERSE_TYPE(TemplateSpecializationType, { TRY_TO(TraverseTemplateName(T->getTemplateName())); @@ -718,6 +732,14 @@ DEF_TRAVERSE_TYPE(TemplateSpecializationType, { DEF_TRAVERSE_TYPE(InjectedClassNameType, { }) +DEF_TRAVERSE_TYPE(AttributedType, { + TRY_TO(TraverseType(T->getModifiedType())); + }) + +DEF_TRAVERSE_TYPE(ParenType, { + TRY_TO(TraverseType(T->getInnerType())); + }) + DEF_TRAVERSE_TYPE(ElaboratedType, { if (T->getQualifier()) { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); @@ -734,6 +756,10 @@ DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, { TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); }) +DEF_TRAVERSE_TYPE(PackExpansionType, { + TRY_TO(TraverseType(T->getPattern())); + }) + DEF_TRAVERSE_TYPE(ObjCInterfaceType, { }) DEF_TRAVERSE_TYPE(ObjCObjectType, { @@ -752,14 +778,15 @@ DEF_TRAVERSE_TYPE(ObjCObjectPointerType, { // ----------------- TypeLoc traversal ----------------- // This macro makes available a variable TL, the passed-in TypeLoc. -// It calls WalkUpFrom* for the Type in the given TypeLoc, in addition -// to WalkUpFrom* for the TypeLoc itself, such that existing clients -// that override the WalkUpFrom*Type() and/or Visit*Type() methods +// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc, +// in addition to WalkUpFrom* for the TypeLoc itself, such that existing +// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods // continue to work. #define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \ template<typename Derived> \ bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \ - TRY_TO(WalkUpFrom##TYPE(TL.getTypePtr())); \ + if (getDerived().shouldWalkTypesOfTypeLocs()) \ + TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr()))); \ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ { CODE; } \ return true; \ @@ -867,22 +894,16 @@ DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, { TRY_TO(TraverseTypeLoc(TL.getResultLoc())); }) -// FIXME: location of arguments, exception specifications (attributes?) -// Note that we have the ParmVarDecl's here. Do we want to use them? +// FIXME: location of exception specifications (attributes?) DEF_TRAVERSE_TYPELOC(FunctionProtoType, { TRY_TO(TraverseTypeLoc(TL.getResultLoc())); - FunctionProtoType *T = TL.getTypePtr(); -/* + const FunctionProtoType *T = TL.getTypePtr(); + for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { TRY_TO(TraverseDecl(TL.getArg(I))); } -*/ - for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(), - AEnd = T->arg_type_end(); - A != AEnd; ++A) { - TRY_TO(TraverseType(*A)); - } + for (FunctionProtoType::exception_iterator E = T->exception_begin(), EEnd = T->exception_end(); E != EEnd; ++E) { @@ -906,10 +927,15 @@ DEF_TRAVERSE_TYPELOC(DecltypeType, { TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPELOC(AutoType, { + TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); + }) + DEF_TRAVERSE_TYPELOC(RecordType, { }) DEF_TRAVERSE_TYPELOC(EnumType, { }) DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { }) DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { }) +DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { }) // FIXME: use the loc for the template name? DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, { @@ -921,6 +947,14 @@ DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, { DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { }) +DEF_TRAVERSE_TYPELOC(ParenType, { + TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); + }) + +DEF_TRAVERSE_TYPELOC(AttributedType, { + TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); + }) + // FIXME: use the sourceloc on qualifier? DEF_TRAVERSE_TYPELOC(ElaboratedType, { if (TL.getTypePtr()->getQualifier()) { @@ -941,6 +975,10 @@ DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, { } }) +DEF_TRAVERSE_TYPELOC(PackExpansionType, { + TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); + }) + DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { }) DEF_TRAVERSE_TYPELOC(ObjCObjectType, { @@ -1001,11 +1039,18 @@ DEF_TRAVERSE_DECL(FileScopeAsmDecl, { }) DEF_TRAVERSE_DECL(FriendDecl, { - TRY_TO(TraverseDecl(D->getFriendDecl())); + // Friend is either decl or a type. + if (D->getFriendType()) + TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); + else + TRY_TO(TraverseDecl(D->getFriendDecl())); }) DEF_TRAVERSE_DECL(FriendTemplateDecl, { - TRY_TO(TraverseDecl(D->getFriendDecl())); + if (D->getFriendType()) + TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); + else + TRY_TO(TraverseDecl(D->getFriendDecl())); for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) { TemplateParameterList *TPL = D->getTemplateParameterList(I); for (TemplateParameterList::iterator ITPL = TPL->begin(), @@ -1051,6 +1096,11 @@ DEF_TRAVERSE_DECL(NamespaceAliasDecl, { return true; }) +DEF_TRAVERSE_DECL(LabelDecl, { + // There is no code in a LabelDecl. +}) + + DEF_TRAVERSE_DECL(NamespaceDecl, { // Code in an unnamed namespace shows up automatically in // decls_begin()/decls_end(). Thus we don't need to recurse on @@ -1082,7 +1132,9 @@ DEF_TRAVERSE_DECL(ObjCProtocolDecl, { }) DEF_TRAVERSE_DECL(ObjCMethodDecl, { - // FIXME: implement + // We don't traverse nodes in param_begin()/param_end(), as they + // appear in decls_begin()/decls_end() and thus are handled. + TRY_TO(TraverseStmt(D->getBody())); }) DEF_TRAVERSE_DECL(ObjCPropertyDecl, { @@ -1175,7 +1227,7 @@ DEF_TRAVERSE_DECL(ClassTemplateDecl, { if (D->isThisDeclarationADefinition()) TRY_TO(TraverseClassInstantiations(D, D)); } - + // Note that getInstantiatedFromMemberTemplate() is just a link // from a template instantiation back to the template from which // it was instantiated, and thus should not be traversed. @@ -1208,10 +1260,10 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations( assert(false && "Unknown specialization kind."); } } - + return true; } - + DEF_TRAVERSE_DECL(FunctionTemplateDecl, { TRY_TO(TraverseDecl(D->getTemplatedDecl())); TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); @@ -1251,7 +1303,7 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { }) DEF_TRAVERSE_DECL(TypedefDecl, { - TRY_TO(TraverseType(D->getUnderlyingType())); + TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); // We shouldn't traverse D->getTypeForDecl(); it's a result of // declaring the typedef, not something that was written in the // source. @@ -1282,11 +1334,7 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper( RecordDecl *D) { // We shouldn't traverse D->getTypeForDecl(); it's a result of // declaring the type, not something that was written in the source. - // - // The anonymous struct or union object is the variable or field - // whose type is the anonymous struct or union. We shouldn't - // traverse D->getAnonymousStructOrUnionObject(), as it's not - // something that is explicitly written in the source. + TRY_TO(TraverseNestedNameSpecifier(D->getQualifier())); return true; } @@ -1380,6 +1428,8 @@ DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, { TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier())); }) +DEF_TRAVERSE_DECL(IndirectFieldDecl, {}) + template<typename Derived> bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) { TRY_TO(TraverseNestedNameSpecifier(D->getQualifier())); @@ -1412,47 +1462,11 @@ template<typename Derived> bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { TRY_TO(TraverseNestedNameSpecifier(D->getQualifier())); - // Visit the function type itself, which can be either - // FunctionNoProtoType or FunctionProtoType, or a typedef. If it's - // not a Function*ProtoType, then it can't have a body or arguments, - // so we have to do less work. - Type *FuncType = D->getType().getTypePtr(); - if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(FuncType)) { - if (D->isThisDeclarationADefinition()) { - // Don't call Traverse*, or the result type and parameter types - // will be double counted. - TRY_TO(WalkUpFromFunctionProtoType(FuncProto)); - } else { - // This works around a bug in Clang that does not add the parameters - // to decls_begin/end for function declarations (as opposed to - // definitions): - // http://llvm.org/PR7442 - // We work around this here by traversing the function type. - // This isn't perfect because we don't traverse the default - // values, if any. It also may not interact great with - // templates. But it's the best we can do until the bug is - // fixed. - // FIXME: replace the entire 'if' statement with - // TRY_TO(WalkUpFromFunctionProtoType(FuncProto)); - // when the bug is fixed. - TRY_TO(TraverseFunctionProtoType(FuncProto)); - return true; - } - } else if (FunctionNoProtoType *FuncNoProto = - dyn_cast<FunctionNoProtoType>(FuncType)) { - // Don't call Traverse*, or the result type will be double - // counted. - TRY_TO(WalkUpFromFunctionNoProtoType(FuncNoProto)); - } else { // a typedef type, or who knows what - assert(!D->isThisDeclarationADefinition() && "Unexpected function type"); - TRY_TO(TraverseType(D->getType())); - return true; - } - - TRY_TO(TraverseType(D->getResultType())); - // If we're an explicit template specialization, iterate over the - // template args that were explicitly specified. + // template args that were explicitly specified. If we were doing + // this in typing order, we'd do it between the return type and + // the function args, but both are handled by the FunctionTypeLoc + // above, so we have to choose one side. I've decided to do before. if (const FunctionTemplateSpecializationInfo *FTSI = D->getTemplateSpecializationInfo()) { if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared && @@ -1467,28 +1481,11 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { } } - for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); - } - - if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(FuncType)) { - if (D->isThisDeclarationADefinition()) { - // This would be visited if we called TraverseType(D->getType()) - // above, but we don't (at least, not in the - // declaration-is-a-definition case), in order to avoid duplicate - // visiting for parameters. (We need to check parameters here, - // rather than letting D->getType() do it, so we visit default - // parameter values). So we need to re-do some of the work the - // type would do. - for (FunctionProtoType::exception_iterator - E = FuncProto->exception_begin(), - EEnd = FuncProto->exception_end(); - E != EEnd; ++E) { - TRY_TO(TraverseType(*E)); - } - } - } + // Visit the function type itself, which can be either + // FunctionNoProtoType or FunctionProtoType, or a typedef. This + // also covers the return type and the function parameters, + // including exception specifications. + TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { // Constructor initializers. @@ -1554,7 +1551,7 @@ DEF_TRAVERSE_DECL(ImplicitParamDecl, { DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, { // A non-type template parameter, e.g. "S" in template<int S> class Foo ... - TRY_TO(TraverseVarHelper(D)); + TRY_TO(TraverseDeclaratorHelper(D)); TRY_TO(TraverseStmt(D->getDefaultArgument())); }) @@ -1577,12 +1574,11 @@ DEF_TRAVERSE_DECL(ParmVarDecl, { // ----------------- Stmt traversal ----------------- // // For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating -// over the children defined in child_begin/child_end (every stmt -// defines these, though sometimes the range is empty). Each -// individual Traverse* method only needs to worry about children -// other than those. To see what child_begin()/end() does for a given -// class, see, e.g., -// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html +// over the children defined in children() (every stmt defines these, +// though sometimes the range is empty). Each individual Traverse* +// method only needs to worry about children other than those. To see +// what children() does for a given class, see, e.g., +// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html // This macro makes available a variable S, the passed-in stmt. #define DEF_TRAVERSE_STMT(STMT, CODE) \ @@ -1590,9 +1586,8 @@ template<typename Derived> \ bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \ TRY_TO(WalkUpFrom##STMT(S)); \ { CODE; } \ - for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end(); \ - C != CEnd; ++C) { \ - TRY_TO(TraverseStmt(*C)); \ + for (Stmt::child_range range = S->children(); range; ++range) { \ + TRY_TO(TraverseStmt(*range)); \ } \ return true; \ } @@ -1608,12 +1603,12 @@ DEF_TRAVERSE_STMT(AsmStmt, { for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { TRY_TO(TraverseStmt(S->getClobber(I))); } - // child_begin()/end() iterates over inputExpr and outputExpr. + // children() iterates over inputExpr and outputExpr. }) DEF_TRAVERSE_STMT(CXXCatchStmt, { TRY_TO(TraverseDecl(S->getExceptionDecl())); - // child_begin()/end() iterates over the handler block. + // children() iterates over the handler block. }) DEF_TRAVERSE_STMT(DeclStmt, { @@ -1621,11 +1616,11 @@ DEF_TRAVERSE_STMT(DeclStmt, { I != E; ++I) { TRY_TO(TraverseDecl(*I)); } - // Suppress the default iteration over child_begin/end by + // Suppress the default iteration over children() by // returning. Here's why: A DeclStmt looks like 'type var [= // initializer]'. The decls above already traverse over the // initializers, so we don't have to do it again (which - // child_begin/end would do). + // children() would do). return true; }) @@ -1652,17 +1647,16 @@ DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { }) DEF_TRAVERSE_STMT(ObjCAtTryStmt, { }) DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { }) DEF_TRAVERSE_STMT(ReturnStmt, { }) -DEF_TRAVERSE_STMT(SwitchCase, { }) DEF_TRAVERSE_STMT(SwitchStmt, { }) DEF_TRAVERSE_STMT(WhileStmt, { }) DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, { + TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); if (S->hasExplicitTemplateArgs()) { TRY_TO(TraverseTemplateArgumentLocsHelper( S->getTemplateArgs(), S->getNumTemplateArgs())); } - TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); }) DEF_TRAVERSE_STMT(DeclRefExpr, { @@ -1695,27 +1689,27 @@ DEF_TRAVERSE_STMT(ImplicitCastExpr, { }) DEF_TRAVERSE_STMT(CStyleCastExpr, { - TRY_TO(TraverseType(S->getTypeAsWritten())); + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, { - TRY_TO(TraverseType(S->getTypeAsWritten())); + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) DEF_TRAVERSE_STMT(CXXConstCastExpr, { - TRY_TO(TraverseType(S->getTypeAsWritten())); + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) DEF_TRAVERSE_STMT(CXXDynamicCastExpr, { - TRY_TO(TraverseType(S->getTypeAsWritten())); + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, { - TRY_TO(TraverseType(S->getTypeAsWritten())); + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) DEF_TRAVERSE_STMT(CXXStaticCastExpr, { - TRY_TO(TraverseType(S->getTypeAsWritten())); + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) // InitListExpr is a tricky one, because we want to do all our work on @@ -1729,9 +1723,8 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) { S = Syn; TRY_TO(WalkUpFromInitListExpr(S)); // All we need are the default actions. FIXME: use a helper function. - for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end(); - C != CEnd; ++C) { - TRY_TO(TraverseStmt(*C)); + for (Stmt::child_range range = S->children(); range; ++range) { + TRY_TO(TraverseStmt(*range)); } return true; } @@ -1739,12 +1732,12 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) { DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { // This is called for code like 'return T()' where T is a built-in // (i.e. non-class) type. - if (!S->isImplicit()) - TRY_TO(TraverseType(S->getType())); + TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); }) DEF_TRAVERSE_STMT(CXXNewExpr, { - TRY_TO(TraverseType(S->getAllocatedType())); + // The child-iterator will pick up the other arguments. + TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc())); }) DEF_TRAVERSE_STMT(OffsetOfExpr, { @@ -1769,15 +1762,43 @@ DEF_TRAVERSE_STMT(CXXTypeidExpr, { TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); }) -DEF_TRAVERSE_STMT(TypesCompatibleExpr, { - TRY_TO(TraverseTypeLoc(S->getArgTInfo1()->getTypeLoc())); - TRY_TO(TraverseTypeLoc(S->getArgTInfo2()->getTypeLoc())); +DEF_TRAVERSE_STMT(CXXUuidofExpr, { + // The child-iterator will pick up the arg if it's an expression, + // but not if it's a type. + if (S->isTypeOperand()) + TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); }) DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, { - TRY_TO(TraverseType(S->getQueriedType())); + TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc())); + }) + +DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, { + TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc())); + TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc())); + }) + +DEF_TRAVERSE_STMT(VAArgExpr, { + // The child-iterator will pick up the expression argument. + TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { + // This is called for code like 'return T()' where T is a class type. + TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); + }) + +DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { + // This is called for code like 'T()', where T is a template argument. + TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); + }) + +// These expressions all might take explicit template arguments. +// We traverse those if so. FIXME: implement these. +DEF_TRAVERSE_STMT(CXXConstructExpr, { }) +DEF_TRAVERSE_STMT(CallExpr, { }) +DEF_TRAVERSE_STMT(CXXMemberCallExpr, { }) + // These exprs (most of them), do not need any action except iterating // over the children. DEF_TRAVERSE_STMT(AddrLabelExpr, { }) @@ -1790,53 +1811,64 @@ DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { }) DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { }) DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { }) DEF_TRAVERSE_STMT(CXXDeleteExpr, { }) -DEF_TRAVERSE_STMT(CXXExprWithTemporaries, { }) +DEF_TRAVERSE_STMT(ExprWithCleanups, { }) DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { }) -DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { }) +DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { + TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); + if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo()) + TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc())); + if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo()) + TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc())); +}) DEF_TRAVERSE_STMT(CXXThisExpr, { }) DEF_TRAVERSE_STMT(CXXThrowExpr, { }) -DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { }) DEF_TRAVERSE_STMT(DesignatedInitExpr, { }) DEF_TRAVERSE_STMT(ExtVectorElementExpr, { }) DEF_TRAVERSE_STMT(GNUNullExpr, { }) DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { }) DEF_TRAVERSE_STMT(ObjCEncodeExpr, { }) -DEF_TRAVERSE_STMT(ObjCImplicitSetterGetterRefExpr, { }) DEF_TRAVERSE_STMT(ObjCIsaExpr, { }) DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { }) DEF_TRAVERSE_STMT(ObjCMessageExpr, { }) DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { }) DEF_TRAVERSE_STMT(ObjCProtocolExpr, { }) DEF_TRAVERSE_STMT(ObjCSelectorExpr, { }) -DEF_TRAVERSE_STMT(ObjCSuperExpr, { }) DEF_TRAVERSE_STMT(ParenExpr, { }) DEF_TRAVERSE_STMT(ParenListExpr, { }) DEF_TRAVERSE_STMT(PredefinedExpr, { }) DEF_TRAVERSE_STMT(ShuffleVectorExpr, { }) DEF_TRAVERSE_STMT(StmtExpr, { }) -DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { }) -DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { }) -DEF_TRAVERSE_STMT(VAArgExpr, { - // The child-iterator will pick up the expression argument. - TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc())); - }) -DEF_TRAVERSE_STMT(CXXConstructExpr, { }) - -DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { - // This is called for code like 'return T()' where T is a class type. - TRY_TO(TraverseType(S->getType())); - }) +DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { + TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); + if (S->hasExplicitTemplateArgs()) { + TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), + S->getNumTemplateArgs())); + } +}) + +DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { + TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); + if (S->hasExplicitTemplateArgs()) { + TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), + S->getNumTemplateArgs())); + } +}) -DEF_TRAVERSE_STMT(CallExpr, { }) -DEF_TRAVERSE_STMT(CXXMemberCallExpr, { }) DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { }) +DEF_TRAVERSE_STMT(OpaqueValueExpr, { }) +DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { }) // These operators (all of them) do not need any action except // iterating over the children. +DEF_TRAVERSE_STMT(BinaryConditionalOperator, { }) DEF_TRAVERSE_STMT(ConditionalOperator, { }) DEF_TRAVERSE_STMT(UnaryOperator, { }) DEF_TRAVERSE_STMT(BinaryOperator, { }) DEF_TRAVERSE_STMT(CompoundAssignOperator, { }) +DEF_TRAVERSE_STMT(CXXNoexceptExpr, { }) +DEF_TRAVERSE_STMT(PackExpansionExpr, { }) +DEF_TRAVERSE_STMT(SizeOfPackExpr, { }) +DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { }) // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, { }) @@ -1861,7 +1893,6 @@ DEF_TRAVERSE_STMT(ObjCStringLiteral, { }) // http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html // http://clang.llvm.org/doxygen/classclang_1_1SizeOfAlignOfExpr.html // http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html -// http://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html // Every class that has getQualifier. #undef DEF_TRAVERSE_STMT |