Get name from RecordDecl

Hello all,

Currently, I’m using libTooling to generate the program’s AST, which later I translate to our own AST, but I’m having some trouble retrieving the name of this RecordDecl:

typedef struct
{
int __count;

union
{
int __wch;
char __wchb[4];
} __value;

} __mbstate_t;

To get the recordDecl name, I’m using two methods:

bool clang_c_convertert::get_tag_name(

const clang::RecordDecl& rd,
std::string &name)
{
name = get_decl_name(rd);

if(!name.empty())
return false;

// Try to get the name from typedef (if one exists)
if (const clang::TagDecl *tag = llvm::dyn_castclang::TagDecl(&rd))
{
if (const clang::TypedefNameDecl *tnd = rd.getTypedefNameForAnonDecl())
{
name = get_decl_name(*tnd);
return false;
}
else if (tag->getIdentifier())
{
name = get_decl_name(*tag);
return false;
}
}

assert(rd.isAnonymousStructOrUnion());

return get_anon_tag_name(rd, name); // This build’s a name based on the tag type
}

Where the method get_decl_name is:

std::string clang_c_convertert::get_decl_name(
const clang::NamedDecl &decl)
{
if(const clang::IdentifierInfo *identifier = decl.getIdentifier())
return identifier->getName().str();

std::string name;
llvm::raw_string_ostream rso(name);
decl.printName(rso);
return rso.str();
}

The problem is the inner union, which is not anonymous but I can’t get the name. The bold assertion always fails.

Is there a way to get the union name, in this case?

Btw, I get there when parsing a varDecl and calling varDecl.getType(). It returns a RecordType and I call .getDecl() to parse the union declaration.

Thank you,

Hi,

typedef struct
{
  int __count;

* union*
* {*
* int __wch;*
* char __wchb[4];*
* } __value;*

} __mbstate_t;

...

The problem is the inner union, which is not anonymous but I can't get the
name. The bold assertion always fails.

Have a look at the AST with 'clang++ -Xclang -ast-dump -fsyntax-only',
IIUC the union is anonymous, __value is the name of the member, not of
the union.

Regards,

Miklos

I thought so too but from the documentation:

/// isAnonymousStructOrUnion - Whether this is an anonymous struct
/// or union. To be an anonymous struct or union, it must have been
/// declared without a name and there must be no objects of this
/// type declared, e.g.,
/// @code
/// union { int i; float f; };
/// @endcode
/// is an anonymous union but neither of the following are:
/// @code
/// union X { int i; float f; };
/// union { int i; float f; } obj;
/// @endcode

So I thought that it would create a tag name using the field name, which doesn’t seem to be the case.

Anyway, I decided to follow the cope from TypePrinter and ignore a struct without name when generating the scope.

Thank you,