With an AST field visitor of the following form:
bool VisitFieldDecl( FieldDecl * f )
{
RecordDecl * r = f->getParent() ;
TypeSourceInfo * t = f->getTypeSourceInfo() ;
TypeLoc TL = t->getTypeLoc() ;
if ( const ArrayTypeLoc *Arr = dyn_cast(&TL) )
{
TL = Arr->getElementLoc() ;
}
const QualType & q = TL.getType() ;
cout
<< r->getName().str()
<< " : " << q.getAsString() << endl ;
return true ;
}
I get a printout of
: type-dependence. Example:
struct Test
{
int a, b ;
} ;
gives:
Test : int
Test : int
For anonymous structs like:
struct TestA
{
struct {
int a, b ;
} m ;
} ;
I do get a “name” for the dependent type m:
TestA : struct
However, when the AST visitor is called for the a, b fields in this anonymous struct, my r->getName().str() call returns an empty string.
I’m guessing I could get the “name” above, if I could get the QualType from the ‘RecordDecl * r’ variable, but am unsure how to do so, because getTypeSourceInfo() doesn’t appear to be available to a RecordDecl object. How can I get the RecordDecl’s QualType?
You can try this:
const Type *RT = r->getTypeForDecl();
QualType QT = RT->getCanonicalTypeInternal();
- Yang
Thanks Yang,
That works nicely.
However, any idea why this test attempt doesn’t correctly identify the anonymous nature of the type:
string s ;
if ( r->isAnonymousStructOrUnion() )
{
const Type * RT = r->getTypeForDecl() ;
QualType QT = RT->getCanonicalTypeInternal() ;
s = QT.getAsString() ;
}
else
{
s = r->getName().str() ;
}
I can work around this by using the following instead:
string s = r->getName().str() ;
if ( “” == s )
// else removed.
but it seems like an odd thing to do (try to format the object as a string to test an attribute).
Peeter
Peeter Joot wrote:
Thanks Yang,
That works nicely.
However, any idea why this test attempt doesn't correctly identify the anonymous nature of the type:
string s ;
if ( r->isAnonymousStructOrUnion() )
{
const Type * RT = r->getTypeForDecl() ;
QualType QT = RT->getCanonicalTypeInternal() ;
s = QT.getAsString() ;
}
else
{
s = r->getName().str() ;
}
I can work around this by using the following instead:
string s = r->getName().str() ;
if ( "" == s )
// else removed.
but it seems like an odd thing to do (try to format the object as a string to test an attribute).
Peeter
I am sorry I don't know the reason. Maybe others have better ideas on it.
- Yang
Your testcase does not contain an "anonymous union" as defined by C++
[class.union].
-Eli
That's not the right way. getTypeForDecl is a cache, and
getCanonicalTypeInternal is internal. Use ASTContext::getRecordType.