I am using Clang to parse some C++ code. I would like to print the name and mangled name for every FunctionDecl
that I encounter.
I can print the function name fairly easily by adding this to my RecursiveASTVisitor
:
bool VisitFunctionDecl(FunctionDecl* f) {
auto declName = f->getNameInfo().getName();
auto functionName = declName.getAsString();
std::cout << functionName << std::endl;
return true;
}
How can I also print the mangled name?
Working code I produced after following Sebastian's pointers:
const auto getMangledName = [&](FunctionDecl* decl) {
auto mangleContext = context.createMangleContext();
if (!mangleContext->shouldMangleDeclName(decl)) {
return decl->getNameInfo().getName().getAsString();
}
std::string mangledName;
llvm::raw_string_ostream ostream(mangledName);
mangleContext->mangleName(decl, ostream);
ostream.flush();
delete mangleContext;
return mangledName;
};
As I said, the way you would get a mangled C++ name is to take a function, compile it using the compiler and then using something like dumpbin to view it in the object file. If you don't like this then you could always write an application that gets a function to report its own name using the __FUNCDNAME__ macro.
Codes were as simple as the one shown below. The first name in the comment is the GCC mangled name (g++ 8.3) and the second name is the Clang mangled name (clang++ 9.0). So, at least given this small set of samples, there do not seem to be differences.
One can see C++ mangling as a concatenation of the method name with its parameters types. This is a simplification because other things are used to generate a mangled name, but it is the general idea. Once names are mangled, it is possible to resolve symbols at runtime by name without conflict.
This represents a decl that may have a name. Many decls have names such as ObjCMethodDecl, but not @class, etc. Note that not every NamedDecl is actually named (e.g., a struct might be anonymous), and not every name is an identifier. Kinds of explicit visibility. Do an LV computation for, ultimately, a type.
The mangled name is not part of the AST, since it depends on the ABI. To get a mangled name, you need to create an appropriate clang::MangleContext
subclass (from clang/AST/Mangle.h
). Currently there's MicrosoftMangleContext
for the Visual Studio-compatible mangling, and ItaniumMangleContext
for the common C++ ABI mangling.
In the most simple version, you then just call mangleName
, passing in a NamedDecl
whose name you want to mangle, and a raw_ostream
that the mangled name is written to.
For more complex things like lambdas, you may also have to call startNewFunction
at appropriate points, since their mangling depends on what function they are in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With