summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/RecursiveASTVisitor.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/RecursiveASTVisitor.h')
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h325
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
OpenPOWER on IntegriCloud