[cfe-dev] libclang: "Spelling" for built-in types?

David Röthlisberger david at rothlis.net
Sat Jun 9 07:05:23 PDT 2012


On 1 Jun 2012, at 14:58, Jacob Carlborg wrote:
> On 2012-06-01 12:38, David Röthlisberger wrote:
>> Hi,
>> 
>> Using the libclang python bindings, how do I retrieve the name ("spelling") of a built-in type?
>> 
>> I'll clarify with an example. For this source code "type.cpp":
>> 
>>     struct S { };
>>     S s;
>>     int i;
>> 
>> I obtain 2 Cursor objects "cs" and "ci" for the above variables "s" and "i":
>> 
>>     import clang.cindex
>>     index = clang.cindex.Index.create()
>>     tu = index.parse("type.cpp")
>>     cursors = tu.cursor.get_children()
>>     c = cursors.next()
>>     while c.spelling != "s":
>>         c = cursors.next()
>>     cs = c
>>     ci = cursors.next()
>> 
>> I can get the name of the user-defined type S:
>> 
>>     cs.type.get_declaration().spelling
>> 
>> which returns "S". But how do I get the type of "i"? Trying the same as the above:
>> 
>>     ci.type.get_declaration().spelling
>> 
>> returns None (python's null). The closest I've found is:
>> 
>>     ci.type.kind.spelling
>> 
>> which returns "Int". For other types it will return strings like "UChar", "Char16", "LongLong", or "Pointer". What I want is "int", "char", "int*", etc -- the way the type would be written in the source code.
>> 
>> Is this information available and I just haven't found it?
>> 
>> If not currently exposed by libclang, how hard would it be to add this information? And how would I go about it? (I don't want to reverse-engineer from the TypeKind.spelling†, and in some cases I couldn't if I wanted -- e.g. "Pointer" doesn't give me enough information.)
>> 
>> Thanks very much!
>> Dave.
>> 
>> † clang_getTypeKindSpelling: https://github.com/llvm-mirror/clang/blob/25bd2793/tools/libclang/CXType.cpp#L380
>> and its python binding: https://github.com/llvm-mirror/clang/blob/a63ef1f6/bindings/python/clang/cindex.py#L1218
> 
> I have a big switch statement, used on type.kind, for the built-in types.
> 
> If it's a pointer you can do the same as above but append a star "*". I 
> don't know if there's a better way, I would prefer that "spelling" 
> worked on built-in types as well.


Thanks Jacob. I was afraid that would be the case. Is your code publicly
available, and if so, can you share a link to it?

I've found BuiltinType::getName in clang/lib/AST/Type.cpp, which does a
switch statement mapping from the enum values like "UChar" to a string
like "unsigned char".

To anyone else familiar with clang internals, could I please have your
thoughts on the following addition to libclang (I know next to nothing
about the clang & libclang internals, so any guidance is greatly
appreciated):

A new function: CXString clang_getTypeSpelling(CXType)

What it does:
1. For builtin types, returns a string like "unsigned char" (see
   BuiltinType::getName in clang/lib/AST/Type.cpp).
2. For more complex types (pointers, templates) recurses over the type's
   components, constructing a string like "int*" or "map<int, int>".
3. For user-defined types, returns
   clang_getCursorSpelling(clang_getTypeDeclaration(type)).

Justification: Prevent different libclang clients from implementing the
same functionality over and over.
The existing clang_getTypeKindSpelling operates on a CXTypeKind, which
is just an enum and lacks the information for 2 & 3 above.

Thanks,
Dave.





More information about the cfe-dev mailing list