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

Douglas Gregor dgregor at apple.com
Thu Jun 16 22:39:32 PDT 2011


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!
>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 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.

	- Doug



More information about the cfe-dev mailing list