Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -3639,6 +3639,25 @@ * @} */ +/** \defgroup CINDEX_MANGLE Name Mangling API Functions + * + * @{ + */ + +/** + * \brief Represents the different available ABIs for name mangling. + */ +typedef enum { CXMangleABI_Itanium = 0, CXMangleABI_Microsoft = 1 } CXMangleABI; + +/** + * \brief Retrieve the CXString representing the mangled name of the cursor. + */ +CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor, CXMangleABI); + +/** + * @} + */ + /** * \defgroup CINDEX_MODULE Module introspection * Index: test/Index/print-mangled-name.cpp =================================================================== --- /dev/null +++ test/Index/print-mangled-name.cpp @@ -0,0 +1,20 @@ +// RUN: c-index-test -test-print-mangle-itanium %s | FileCheck %s --check-prefix=ITANIUM +// RUN: c-index-test -test-print-mangle-microsoft %s | FileCheck %s --check-prefix=MICROSOFT + +int foo(int, int); +// ITANIUM: mangled=_Z3fooii +// MICROSOFT: mangled=?foo@@YAHHH + +int foo(float, int); +// ITANIUM: mangled=_Z3foofi +// MICROSOFT: mangled=?foo@@YAHMH + +struct S { + int x, y; +}; +// ITANIUM: StructDecl{{.*}}mangled=] +// MICROSOFT: StructDecl{{.*}}mangled=] + +int foo(S, S&); +// ITANIUM: mangled=_Z3foo1SRS +// MICROSOFT: mangled=?foo@@YAHUS Index: tools/c-index-test/c-index-test.c =================================================================== --- tools/c-index-test/c-index-test.c +++ tools/c-index-test/c-index-test.c @@ -1363,6 +1363,29 @@ } /******************************************************************************/ +/* Mangling testing. */ +/******************************************************************************/ + +static void PrintMangledName(CXCursor cursor, CXMangleABI ABI) { + CXString MangledName; + PrintCursor(cursor, NULL); + MangledName = clang_Cursor_getMangling(cursor, ABI); + printf(" [mangled=%s]\n", clang_getCString(MangledName)); +} + +static enum CXChildVisitResult PrintMangleItanium(CXCursor cursor, CXCursor p, + CXClientData d) { + PrintMangledName(cursor, CXMangleABI_Itanium); + return CXChildVisit_Continue; +} + +static enum CXChildVisitResult PrintMangleMicrosoft(CXCursor cursor, CXCursor p, + CXClientData d) { + PrintMangledName(cursor, CXMangleABI_Microsoft); + return CXChildVisit_Continue; +} + +/******************************************************************************/ /* Bitwidth testing. */ /******************************************************************************/ @@ -4081,6 +4104,12 @@ else if (argc > 2 && strcmp(argv[1], "-test-print-bitwidth") == 0) return perform_test_load_source(argc - 2, argv + 2, "all", PrintBitWidth, 0); + else if (argc > 2 && strcmp(argv[1], "-test-print-mangle-itanium") == 0) + return perform_test_load_source(argc - 2, argv + 2, "all", + PrintMangleItanium, 0); + else if (argc > 2 && strcmp(argv[1], "-test-print-mangle-microsoft") == 0) + return perform_test_load_source(argc - 2, argv + 2, "all", + PrintMangleMicrosoft, 0); else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) { if (argc > 2) return print_usrs(argv + 2, argv + argc); Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -22,6 +22,7 @@ #include "CXType.h" #include "CursorVisitor.h" #include "clang/AST/Attr.h" +#include "clang/AST/Mangle.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticCategories.h" @@ -3667,6 +3668,44 @@ return cxloc::translateSourceRange(Ctx, Loc); } +CXString clang_Cursor_getMangling(CXCursor C, CXMangleABI ABI) { + if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind)) + return cxstring::createEmpty(); + + const Decl *D = getCursorDecl(C); + // Mangling only works for functions and variables. + if (!D || !(llvm::isa(D) || llvm::isa(D))) + return cxstring::createEmpty(); + + const NamedDecl *ND = llvm::cast(D); + ASTContext &Context = ND->getASTContext(); + std::unique_ptr MC; + + switch (ABI) { + default: + llvm_unreachable("Unknown mangling ABI"); + break; + case CXMangleABI_Itanium: + MC.reset(ItaniumMangleContext::create(Context, Context.getDiagnostics())); + break; + case CXMangleABI_Microsoft: + MC.reset(MicrosoftMangleContext::create(Context, Context.getDiagnostics())); + break; + } + + std::string Buf; + llvm::raw_string_ostream OS(Buf); + MC->mangleName(ND, OS); + OS.flush(); + + // The Microsoft mangler may insert a special character in the beginning to + // prevent further mangling. We can strip that for display purposes. + if (Buf[0] == '\x01') { + Buf.erase(0, 1); + } + return cxstring::createDup(Buf); +} + CXString clang_getCursorDisplayName(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getCursorSpelling(C); Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -9,6 +9,7 @@ clang_Cursor_getArgument clang_Cursor_getBriefCommentText clang_Cursor_getCommentRange +clang_Cursor_getMangling clang_Cursor_getParsedComment clang_Cursor_getRawCommentText clang_Cursor_getNumArguments