[cfe-dev] API for auto type deduction in libclang

Kevin Funk krf at gmx.de
Wed Jan 29 02:30:19 PST 2014


Am Dienstag, 28. Januar 2014, 21:00:44 schrieb Richard Smith:
> On Tue Jan 28 2014 at 3:43:30 AM, Kevin Funk <krf at gmx.de> wrote:
> > Am Sonntag, 26. Januar 2014, 13:00:24 schrieb Jacob Carlborg:
> > > On 2014-01-25 22:03, Kevin Funk wrote:
> > > > That doesn't work for me.
> > > > 
> > > > For testing we have a small wrapper binary that basically creates a
> > > > CXTranslationUnit and then traverses through the AST via
> > > > clang_visitChildren().
> > > > 
> > > > During the call to 'visit' it does the following (amongst other
> > 
> > things):
> > > > - auto location = clang_getCursorLocation(cursor)
> > > > - auto type = clang_getCursorType(cursor)
> > > > - auto typeString = clang_getTypeSpelling(type)
> > > > - now: auto canonicalTypeString =
> > > > 
> > > >      clang_getTypeSpelling(clang_getCanonicalType(type))
> > > > 
> > > > It outputs all the values of those variabes to stdout, and when I pass
> > > > "auto i = 5;" to it I get:
> > > > 
> > > > """
> > > > decl: "auto (canonical type: auto) i " of kind VarDecl (9) in
> > > > stdin.cpp at 1:6
> > > > 
> > > >    "int (canonical type: int) " of kind IntegerLiteral (106) in
> > > >    stdin.cpp at 1:10
> > > > 
> > > > """
> > > > 
> > > > So the 'canonical type' of VarDecl still resolves to 'auto', instead
> > > > of
> > > > 'int'. Sorry, if we're doing something completely wrong, but I don't
> > 
> > seem
> > 
> > > > to get this working as you suggest.
> > > 
> > > Ok, I see, you're using clang_getTypeSpelling. I created my tool before
> > > clang_getTypeSpelling was available. For aggregates, typedefs and a
> > > couple of other types I'm using the following code[1]:
> > > 
> > > auto cursor = clang_getTypeDeclaration(type);
> > > auto str = clang_getCursorSpelling(cursor);
> > > 
> > > For basic types like "int", "char" and so on, the above will return an
> > > empty string. For those types I use a big switch statement on the type
> > > kind and just returns a string representation [2].
> > > 
> > > [1]
> > > https://github.com/jacob-carlborg/dstep/blob/master/
> > 
> > dstep/translator/Type.d#
> > 
> > > L43
> > > 
> > > [2]
> > > https://github.com/jacob-carlborg/dstep/blob/master/
> > 
> > dstep/translator/Type.d#
> > 
> > > L248
> > 
> > Unfortunately, your source code doesn't help me, nor can I get it to work
> > using any combination of getTypeDeclaration, getCursorSpelling, and the
> > ones I
> > referred to earlier...
> > 
> > I wonder if there's some bug in Clang's type printers I'm experiencing
> > here.
> > 
> > Let's do some testing:
> > Test file: test.cpp, containing 'auto i = 5;'
> > 
> > $ clang -cc1 -std=c++11 -ast-dump test.cpp
> > (...)
> > `-VarDecl 0x1c2e5b0 <test.cpp:1:1, col:10> i 'int':'int'
> > 
> >   `-IntegerLiteral 0x1c2e608 <col:10> 'int' 5
> > 
> > => What I'd expect! ('auto' => 'int')
> > 
> > Next try: My clang-standalone-parser (basically emulating 'clang -cc1
> > -dump')
> > but using libclang only [1]:
> > 
> > $ ./clang-standalone-parser -std=c++11 test.cpp
> > test.cpp:1:6 (5, 0-10) kind: VarDecl type: auto display name: i (...)
> > 
> >   test.cpp:1:10 (9, 9-10) kind: IntegerLiteral type: int
> > 
> > => Not what I'd expect, 'auto' is not deduced
> > 
> > And the odd part here is: Breaking on the symbol
> > 'clang::AutoType::getDeducedType()' for both clang and
> > clang-standalone-parser
> > shows that *both* versions actually call that function when trying to find
> > a
> > string representation for the type 'auto'. But with
> > clang-standalone-parser,
> > 'clang::AutoType::getDeducedType()' always returns an null QualType.
> > 
> > Can someone make any sense out of this? Bug in Clang/LLVM? Note that the
> > backtrace towards the call of getDeducedType is slightly different for the
> > two
> > versions (see attached file). Maybe this is the reason?
> 
> I would expect that clang's dumper is using VarDecl->getType() and your
> standalone tool is using VarDecl->getTypeSourceInfo(). The former produces
> the type of the variable (which is 'int'); the latter produces the
> type-as-written (which is 'auto').
> 
> FWIW, we've been considering changing this for variables, but even if we
> did, the problem would persist for functions with 'auto' return types.

Hey,

But how do you explain that *both* versions actually call 
'clang::AutoType::getDeducedType' during pretty-printing this type, but only 
one version actually gets the actual type and the other doesn't? I fail to see 
the link why one behaves differently here.

It would be nice if someone with a deeper understanding of libclang internals 
could have a look at our small tool at [1] and check if we're doing something 
wrong. Or if that just *can't* work with the current API at hand.

Sorry if I'm missing something obvious.

[1] http://quickgit.kde.org/?p=kdev-clang.git&a=blob&h=dbad9e8942cc5e20fd005677fc32a5a0b54977ae&hb=1fa9eca7a9a58404c3ef687fcfa63800d459cff5&f=tests%2Fclang-standalone-parser.c

-- 
Kevin Funk



More information about the cfe-dev mailing list