[cfe-dev] Further AST spelunking
Peter Stirling
peter at pjstirling.plus.com
Sun Mar 15 11:55:37 PDT 2015
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 <mailto: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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150315/862b3853/attachment.html>
More information about the cfe-dev
mailing list