Not getting expected Decls (possible newbie mistake)

==Stuff.h==
namespace Stuff
{
template< typename A, int B >
class Thingy
{
public:
Thingy() {}

private:
int data;
};
}

==Stuff.cpp==
#include “Stuff.h”
Stuff::Thingy< double, 2 > gThing;
void funcy()
{
int i;
i++;
}

I tried to write an AST consumer that would iterate over the Decls in the HandleTranslationUnit method but when I ran it over the above code only got __builtin_va_list (as a TypedefDecl) and 2 VarDecls as for “Stuff”. I was expecting a RecordDecl for the Thingy class and decl for the class.

I don’t suppose someone would be able to tell me why I’m so far off base? (Or point me to the relevent documentation - I’m rather familiar with the ASTContext/ASTConsumer/Type/Decl/DeclContext Doxygen output at this point!)

Many thanks in advance - I suspect I’m missing something rather obvious!
Pascal

The top-level declarations are __builtin_va_list (injected by the compiler), Stuff, gThing, and funcy.

Thingy is not a top-level declaration; it's stored within the namespace 'Stuff'. You can iterate through the declarations within a namespace with decls_begin/decls_end; check out the DeclContext class for more information.

  - Doug

That was my first thought but when I did if(dyn_cast< NamespaceDecl >(pDecl)) { …code… }, I found that I wasn’t hitting my breakpoint inside the if-block. Also pDecl->getDeclKindName() returns “Var” for all instances of Stuff (I would have expected 1 for the declaration of gThing but not the namespace too).

I also tried iterating through all of the items in the DeclGroupRef in HandleTopLevelDecl(…) and trying to recurse down through all Decls that successfully dyn_cast< DeclContext >.

(And the __builtin_va_list disappears when I copied used the SourceLocation::isInvalid() check from RewriteObjC::HandleTopLevelSingleDec(…) suggested as an example previously.)

Pascal

For the sake of clarity here’s the complete source and the output:

HandleTopLevelDecl
Visiting Typedef __builtin_va_list - __builtin_va_list
HandleTopLevelDecl
Visiting Var Stuff - empty - canonical=Stuff - no definition
HandleTopLevelDecl
Visiting Var Stuff - empty - canonical=Stuff - no definition
HandleTranslationUnit
Visiting Typedef __builtin_va_list - __builtin_va_list
Visiting Var Stuff - empty - canonical=Stuff - no definition
Visiting Var Stuff - empty - canonical=Stuff - no definition
4 diagnostics generated.
Finished…

Analyze.zip (2.73 KB)

I hate to sound like I’m having a conversation with myself but I just thought I’d update this thread for the sake of anyone that has a similar problem in the future. I’ve found lots of previous threads useful myself so I wanted to make sure that I followed up properly.

It appears that the problem is that I wasn’t setting the language properly and the namespace keyword and Stuff::Thingy declaration weren’t being recognised as good C++.

One thing that helped me diagnose this was to iterate through the strings output from the diagnostics via the diagnostics buffer via the error_begin/end methods.

To solve this in the short term I did this:

CompilerInvocation *pInv = new CompilerInvocation()
pInv->getLangOpts().CPlusPlus = 1;
compiler_instance.setInvocation(pInv);

The next problem I found was that when I tried point to another file, the parser couldn’t find any include files. The solution to this problem is to parse the command line with full -I options included. A great example of how to do this can be found in:
tools/driver/cc1_main.cpp: cc1_main(…)

I hope someone (anyone) finds this useful.

Pascal