[cfe-dev] Getting the pointer to an out-of-class VarDecl

Mihai Draghicioiu mihai.draghicioiu at gmail.com
Tue Sep 30 03:37:11 PDT 2014


Ah, I've figured out why this happens, it's because I call TraverseDecl
from ASTConsumer::HandleTopLevelDecl(), so the full AST isn't traversed at
this point. So now I need to figure out how to traverse the AST only after
fully parsing it....

class MyASTConsumer : public ASTConsumer {
  public:
virtual bool HandleTopLevelDecl(DeclGroupRef d) {
typedef DeclGroupRef::iterator iter;
MyRecursiveASTVisitor rv;
for (iter b = d.begin(), e = d.end(); b != e; ++b) {
rv.TraverseDecl(*b);
}
return true;
}
};

On Tue, Sep 30, 2014 at 12:34 PM, Mihai Draghicioiu <
mihai.draghicioiu at gmail.com> wrote:

> > There is a helper like getDefiningDecl which will get the second vardecl
> if you've already parsed it.
>
> Can you be more specific please? I can't find this helper method in any
> class.
>
>
> > A redeclaration chain contains all redeclarations, that's the idea, it
> is a circular singly-linked list.
> > You should be able to traverse the chain
> with getFirstDecl(), getMostRecentDecl() and friends from Redeclarable.h.
> I am able to traverse the chain, but if I traverse it inside
> VisitVarDecl() or TraverseVarDecl(), upon the first VarDecl, the list only
> contains itself, and uopn the second VarDecl, the list contains both.
>
> The code I used to test is this:
>
> void printSourceRange(SourceRange r) {
> llvm::outs()
> << r.getBegin().printToString(ci.getSourceManager())
> << "---"
> << r.getEnd().printToString(ci.getSourceManager());
> }
>
> bool TraverseVarDecl(VarDecl *d) {
> llvm::outs() << "VarDecl " << d->getName() << " @";
> printSourceRange(d->getSourceRange());
> llvm::outs() << "\n";
> llvm::outs() << "first decl @";
> printSourceRange(d->getFirstDecl()->getSourceRange());
> llvm::outs() << "\n";
> llvm::outs() << "most recent decl @";
> printSourceRange(d->getMostRecentDecl()->getSourceRange());
> llvm::outs() << "\n";
> for(auto r: d->redecls()) {
> llvm::outs() << "redecl " << d->getName() << " @";
> printSourceRange(r->getSourceRange());
> llvm::outs() << "\n";
> }
> return true;
> }
>
> Output looks like this:
>
> VarDecl poop @foo.cpp:2:2---foo.cpp:2:13
> first decl @foo.cpp:2:2---foo.cpp:2:13
> most recent decl @foo.cpp:2:2---foo.cpp:2:13
> redecl poop @foo.cpp:2:2---foo.cpp:2:13
>
> VarDecl poop @foo.cpp:5:1---foo.cpp:5:17
> first decl @foo.cpp:2:2---foo.cpp:2:13
> most recent decl @foo.cpp:5:1---foo.cpp:5:17
> redecl poop @foo.cpp:5:1---foo.cpp:5:17
> redecl poop @foo.cpp:2:2---foo.cpp:2:13
>
> As you can see, the only reference to the VarDecl at foo.cpp:5:1 i get is
> upon the second call of TraverseVarDecl, and I want to get it at the first
> call.
>
> Am I misunderstanding something, or doing something wrong? It looks like
> the two VarDecls have two different lists of redeclarations, which do not
> correspond.
>
> Thanks.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140930/e92fc7f2/attachment.html>


More information about the cfe-dev mailing list