]> granicus.if.org Git - clang/commitdiff
Make RecursiveASTVisitor traverse function parameter types in a function
authorZhanyong Wan <wan@google.com>
Fri, 2 Jul 2010 21:02:30 +0000 (21:02 +0000)
committerZhanyong Wan <wan@google.com>
Fri, 2 Jul 2010 21:02:30 +0000 (21:02 +0000)
prototype declaration.  Reviewed by chandlerc and csilvers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107511 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/RecursiveASTVisitor.h

index e0a2a015d4f4d492d44d39ab99d39428d278321f..d1712ff1dfa2ac6e3279b4e5c8522dac08f333c6 100644 (file)
@@ -985,17 +985,34 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
   // so we have to do less work.
   Type *FuncType = D->getType().getTypePtr();
   if (FunctionProtoType *FuncProto = dyn_cast<FunctionProtoType>(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<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
-    TRY_TO(TraverseType(D->getType()));
     assert(!D->isThisDeclarationADefinition() && "Unexpected function type");
+    TRY_TO(TraverseType(D->getType()));
     return true;
   }