[cfe-dev] Missing FieldDecl from macro calls and template arguments

Adrien Chauve adrien.chauve at gmail.com
Fri Jun 17 13:03:35 PDT 2011


On Fri, Jun 17, 2011 at 07:39, Douglas Gregor <dgregor at apple.com> wrote:
>
> On Jun 16, 2011, at 1:14 PM, Adrien Chauve wrote:
>
>> On Thu, Jun 16, 2011 at 16:33, Douglas Gregor <dgregor at apple.com> wrote:
>>>
>>> On Jun 16, 2011, at 5:14 AM, Adrien Chauve wrote:
>>>
>>>> On Wed, Jun 15, 2011 at 23:22, Eli Friedman <eli.friedman at gmail.com> wrote:
>>>>> On Wed, Jun 15, 2011 at 2:12 PM, Adrien Chauve <adrien.chauve at gmail.com> wrote:
>>>>>> On Wed, Jun 15, 2011 at 22:13, Eli Friedman <eli.friedman at gmail.com> wrote:
>>>>>>> On Wed, Jun 15, 2011 at 12:58 PM, Adrien Chauve <adrien.chauve at gmail.com> wrote:
>>>>>>>> On Wed, Jun 15, 2011 at 21:53, Eli Friedman <eli.friedman at gmail.com> wrote:
>>>>>>>>> On Wed, Jun 15, 2011 at 12:27 PM, Adrien Chauve <adrien.chauve at gmail.com> wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> I've implemented an ASTConsumer deriving from RecursiveASTVisitor to
>>>>>>>>>> rename field names. The consumer implements VisitFieldDecl and
>>>>>>>>>> VisitMemberExpr,
>>>>>>>>>> but it seems that (at least) two kinds of expressions are not visited.
>>>>>>>>>>
>>>>>>>>>> 1- First, function arguments that are instance of templates, e.g.:
>>>>>>>>>>
>>>>>>>>>>    template<typename T>
>>>>>>>>>>    struct Foo
>>>>>>>>>>    {
>>>>>>>>>>        int bar;
>>>>>>>>>>
>>>>>>>>>>        void copy(const Foo<T>& other) {
>>>>>>>>>>            bar = other.bar;  /// bar is visited but not other.bar
>>>>>>>>>>        }
>>>>>>>>>>    };
>>>>>>>>>
>>>>>>>>> other.bar in this situation is a CXXDependentScopeMemberExpr, I think...
>>>>>>>>
>>>>>>>> Thanks I will definitely try that!

I tried this and it works well because for now I only need the name of
the member and the location.
But I tried as well to see if I could get the member declaration out
of the DeclarationName and I'm having a hard time... do I need to use
the IdentiferInfo, find a connection to an IdentifierResolver?

>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> If I write the same code but with a non-template Foo struct, all bar
>>>>>>>>>> member expressions are visited.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2- Code inside macros, e.g.:
>>>>>>>>>>
>>>>>>>>>>    Foo foo;
>>>>>>>>>>    foo.bar = 2; // bar is visited
>>>>>>>>>>    assert(foo.bar == 2); // bar is not visited
>>>>>>>>>>
>>>>>>>>>> Do I have to get the body of the macro from the Preprocessor and make
>>>>>>>>>> something with it?
>>>>>>>>>
>>>>>>>>> Are you sure you're compiling the given file with asserts enabled?
>>>>>>>>> The expression won't show up in the AST if it gets #define'ed out.
>>>>>>>>
>>>>>>>> I didn't disable asserts with -DNDEBUG, so are they not enabled by default?
>>>>>>>
>>>>>>> If you didn't define NDEBUG, they should be enabled... not sure what's
>>>>>>> going on here.  If the node is getting compiled, it should show up in
>>>>>>> the AST, though.  Maybe take a look at the output of -ast-dump?
>>>>>>>
>>>>>>
>>>>>> Thanks for the tip! I'm not really familiar with the output of
>>>>>> ast-dump but it looks really nice and assert is definitely there. I'm
>>>>>> going to investigate this. Maybe it's because I filtered out the
>>>>>> expressions based on their locations. If the expression inside an
>>>>>> assert is located in assert.h, that should answer my question. I
>>>>>> thought it would be located in the source file where assert is called.
>>>>>
>>>>> How exactly are you getting the source location?  There are multiple
>>>>> locations associated with an expression inside a macro instantiation.
>>>>>
>>>>> -Eli
>>>>>
>>>>
>>>> I use:
>>>>
>>>>     bool VisitMemberExpr(MemberExpr *Node)
>>>>     {
>>>>         SourceLocation loc = Node->getExprLoc();
>>>>        ...
>>>>     }
>>>>
>>>> By the way, I didn't get the difference between loc and:
>>>>
>>>>   instanciated_loc = my_src_manager.getInstatiationLoc(loc);
>>>
>>> As noted at
>>>
>>>  http://clang.llvm.org/docs/InternalsManual.html#SourceLocation
>>>
>>> a source location for a macro instantiation encodes both the spelling location (where the characters came from) and the instantiation location (where the macro was expanded).
>>>
>>>  - Doug
>>>
>>
>> Thanks! It works now. It was indeed a problem of
>> getInstanciationLocation/getSpellingLocation.
>>
>> If I summarize what I understood...
>>
>> Given a SourceLocation "loc" taken from an expression inside a macro call:
>>
>> - SourceManager::getInstanciationLoc(loc) gives where the macro was
>> expanded in the code after the preprocessing step
>> - SourceManager::getSpellingLocation(loc) gives where the characters
>> came from in the original source code before expansion (before
>> preprocessing)
>>
>> but "loc" itself contains a third location which is different from
>> instanciation and spelling locations. From my tests, I believe this is
>> where the macro is defined. Is it?
>
>
> IIRC, it's the location inside the token-pasted buffer for the macro instantiation.

I'm not sure to understand... at least this location is in the file
whre the macro is defined, not in the file where the macro is called?


Adrien




More information about the cfe-dev mailing list