CXXRecordDecl Name

I am attempting to get the name of a CXXRecordDecl that I have identified with an AST matcher. I am using Class->getName().str() to get the class name.

namespace N {
class SomeNonInterface {
virtual void func1() = 0;
virtual void func2() {}
};
}

It works great for the above code. Gives me “SomeNonInterface” as the name.

class N::BaseClass1 {
public:
BaseClass1(int i);
BaseClass1(const BaseClass1 &right);
virtual ~BaseClass1();
BaseClass1 &operator=(const BaseClass1 &right);
};

For the above code it gives me “” as the name.

How would I get the class name so that it works in all cases, even if the name in the declaration/definition is namespace qualified? Or…did I hit a case that isn’t legal?

Try getDeclName(), getNameAsString(), or others. getName() only works if the name is a simple identifier:

/// getName - Get the name of identifier for this declaration as a StringRef.
/// This requires that the declaration have a name and that it be a simple
/// identifier.
StringRef getName() const {
assert(Name.isIdentifier() && “Name is not a simple identifier”);
return getIdentifier() ? getIdentifier()->getName() : “”;
}

If I have this code then everything works. If I get rid of the forward declaration, then any method returns an empty string. Is the forward declaration mandatory when defining the class like this?

namespace N {
class BaseClass1;
}
class N::BaseClass1 {
public:
BaseClass1(int i);
BaseClass1(const BaseClass1 &right);
virtual ~BaseClass1();
BaseClass1 &operator=(const BaseClass1 &right);
}

I found my answer in 9p11 in the standard. Seems that without the forward declaration it is invalid.

If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set of that namespace (i.e., not merely inherited or introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration.

Could you file a bug report for this Daniel?

Why? The AST is invalid, and Clang diagnoses it.

$ cat t.cpp
namespace N { };
struct N::A { };

$ clang -c t.cpp

t.cpp:2:11: error: no struct named ‘A’ in namespace ‘N’
struct N::A { };

I thought no error was reported? I’m not surprised that getName returns an empty string for invalid code :slight_smile:

There probably was an error, but I missed it. I am working on a clang-tidy module, and sometimes it gets quite a bit of noise on the output.