[cfe-dev] (no subject)

Eli Friedman eli.friedman at gmail.com
Tue Dec 18 19:04:40 PST 2012


On Tue, Dec 18, 2012 at 6:48 PM, Peeter Joot <peeter.joot at gmail.com> wrote:
> I'd like to record all typedef references, but weed out the old style C tag
> typedefs like these:
>
> typedef struct foo
> {
>    unsigned char m;
>    unsigned char n;
> } foo;
>
> I'd done that with the following ugly code using string compares:
>
>    // Find typedefs:
>    bool VisitTypedefDecl( TypedefDecl * t )
>    {
>       const QualType & q = t->getUnderlyingType() ;
>
>       const Type * tt = q.getTypePtr() ;
>       string theUnderlyingType = q.getAsString( ) ;
>       string typeDefinitionName = t->getName().str() ;
>       string * pName = NULL ;
>
>       if ( tt->isStructureType() && (("struct " + typeDefinitionName) ==
> theUnderlyingType ) )
>       {
>          pName = &typeDefinitionName ;
>       }
>       else if ( tt->isClassType() && (("class " + typeDefinitionName) ==
> theUnderlyingType ) )
>       {
>          pName = &typeDefinitionName ;
>       }
>       else if ( tt->isUnionType() && (("union " + typeDefinitionName) ==
> theUnderlyingType ) )
>       {
>          pName = &typeDefinitionName ;
>       }
>       else
>       {
>          insertIntoMap( typeDefinitionName, q, pName ) ;
>       }
>
>       return true ;
>    }
>
> This does two things:
> 1) effectively strips off the 'struct', 'union', 'class' from
> theUnderlyingType.
> 2) uses ugly string comparisions to see if we have 'typedef
> {struct|class|union} NNN NNN'.
>
> Are there cleaner ways to do each of the above tasks?

For the first, you can use something like
T->castAs<RecordType>()->getDecl()->getName() to grab the name of a
struct/class/union, as opposed to pretty-printing the type and doing
string manipulation on the result.   Might want to be careful that you
don't unintentionally strip qualifiers or anything like that.

For the second, you're fundamentally stuck with a string comparison:
there isn't any other way to distinguish "typedef struct X {} X;" or
"typedef struct Y {} X;".  I mean, you could compare IdentifierInfo*s
instead, but that's basically the same thing.

-Eli



More information about the cfe-dev mailing list