[cfe-dev] Further AST spelunking

Kim Gräsman kim.grasman at gmail.com
Sun Mar 15 12:19:22 PDT 2015


Hi Peter,

This is the injected class name. I had the same question a few years back:
http://clang-developers.42468.n3.nabble.com/Nested-forward-declarations-of-self-td4028967.html

HTH,
- Kim

On Sun, Mar 15, 2015 at 7:55 PM, Peter Stirling
<peter at pjstirling.plus.com> wrote:
> Hi,
>
> Still working on my SWIG replacement (slowly).
>
> I re-wrote my walker this weekend to improve debugging and I've got a
> weirdness that I'd like explained:
>
> The [first child of a [CXXRecordDecl that is not a forward declaration]] is
> (apparently always) a second (empty) CXXRecordDecl that uses the same
> identifier and source location.
>
> For a file containing the following declarations:
>
> class A {};
> class B;
>
> My trace output is:
>
> walk CXXRecord A at
> /home/peter/Programming/llvm/ninja/../extra-dir/quaff/test.cc:23:1
>   walk CXXRecord A::A at
> /home/peter/Programming/llvm/ninja/../extra-dir/quaff/test.cc:23:1
> walk CXXRecord B at
> /home/peter/Programming/llvm/ninja/../extra-dir/quaff/test.cc:24:1
>
> So, as a forward declaration, B has no children (as expected), but A has
> this strange child.
>
> What purpose does this serve? Can I rely on it being that way into the
> future, and insert code that can automatically skip the first child (if
> there are any children)?
>
>
>
>  On 11/10/14 21:27, Peter Stirling wrote:
>
> Never-mind, CompilerInstance::getSema()
>
> On 11/10/14 20:17, Peter Stirling wrote:
>
> How do I get access to Sema, from a FrontendAction/ASTConsumer?
>
> On 09/10/14 21:40, Reid Kleckner wrote:
>
> On Thu, Oct 9, 2014 at 1:25 PM, Peter Stirling <peter at pjstirling.plus.com>
> wrote:
>>
>> I think you can compute this more directly with
>> inType->isIncompleteType().
>>
>>
>> Thanks for the suggestion, I hadn't seen that either. Unfortunately it
>> doesn't work, for the same cases as getDefinition(), these are (from my test
>> data):
>>
>>   std::fpos<__mbstate_t >
>>
>>  ... snip ...
>>
>>   std::initializer_list<TagLib::String >
>
>
> I think these are just uninstantiated templates. We don't instantiate
> templates when you declare a function that takes a template specialization
> by value, for example, this code compiles:
> template <typename T> struct MyVec;
> void f(MyVec<int> v);
>
> ... but if you add a call to f, it will fail because it cannot complete
> MyVec<int> by instantiation:
> void g(MyVec<int> &x) { f(x); }
>
> For your use case, you probably need to call RequireCompleteType at the
> appropriate point. You may need to wait until the end of the TU if there are
> some circular dependencies.
>>>
>>> I've also discovered that parsing code that calls a builtin function
>>> causes a no-argument, returns-int declaration to be inserted. It's been a
>>> while, but as I remember, in C this kind of declaration actually means that
>>> the function takes an unspecified number of arguments, but each one passed
>>> should be promoted to the size of an int (did they update this since
>>> pointers became much larger than ints?). In C++ it means something rather
>>> different. It seems a bit odd to me that builtin functions don't have the
>>> correct declaration inserted, since the compiler must have them on hand
>>> somewhere.
>>
>>
>> Yes, in C, this is a no-prototype, implicit int return function. I'm not
>> sure what kind of builtin function you're referring to. If the name starts
>> with __builtin_, then the compiler knows the prototype. If it's a libc
>> function like "fprintf()", then you will probably get a warning and the
>> implicit declaration you describe. In C++, you shouldn't get these implicit
>> declarations, it's just an error.
>>
>>
>> The functions that I've hit in my test data are:
>>   __atomic_fetch_add();
>>   __builtin_isfinite();
>>   __builtin_isinf();
>>   __builtin_isnan();
>>   __builtin_isnormal();
>>   __builtin_isgreater();
>>   __builtin_isgreaterequal();
>>   __builtin_isless();
>>   __builtin_islessequal();
>>   __builtin_islessgreater();
>>
>> For all of the above FunctionDecl::getBuiltinID() returns non-zero.
>
>
> These are actually supposed to be variadic, according to the builtins table:
> BUILTIN(__builtin_isunordered   , "i.", "nc")
>
> They have custom type checking:
> /// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater
> and
> /// friends.  This is declared to take (...), so we have to check
> everything.
> bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>



More information about the cfe-dev mailing list