8

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;
};
sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
  • 1
    I know it's been ages, but your working code leaks the mangle context if the early return is taken. You should capture it in a smart pointer. – Sebastian Redl Jul 30 '21 at 11:24

1 Answers1

9

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.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • 1
    Also, there are a lot of small details here and there: several variants for constructors and destructors, thunks for virtual methods. clang::index::CodegenNameGenerator might be used as a reference here. – Anton Korobeynikov Nov 22 '16 at 14:48