From: Zhanyong Wan Date: Fri, 2 Jul 2010 21:02:30 +0000 (+0000) Subject: Make RecursiveASTVisitor traverse function parameter types in a function X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=234faa72224a038e3259ad82d4214174850b8b75;p=clang Make RecursiveASTVisitor traverse function parameter types in a function prototype declaration. Reviewed by chandlerc and csilvers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107511 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index e0a2a015d4..d1712ff1df 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -985,17 +985,34 @@ bool RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) { // so we have to do less work. Type *FuncType = D->getType().getTypePtr(); if (FunctionProtoType *FuncProto = dyn_cast(FuncType)) { - // Don't call Traverse*, or the result type and parameter types - // will be double counted. - TRY_TO(WalkUpFromFunctionProtoType(FuncProto)); + 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(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 - TRY_TO(TraverseType(D->getType())); assert(!D->isThisDeclarationADefinition() && "Unexpected function type"); + TRY_TO(TraverseType(D->getType())); return true; }