From: Eli Bendersky Date: Thu, 31 Jul 2014 18:04:56 +0000 (+0000) Subject: Exposes a C API to name mangling for a given cursor. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fe52a33b57905430aee0ada334ecbb79ec5a714c;p=clang Exposes a C API to name mangling for a given cursor. Inspired by https://gist.github.com/tritao/2766291, and was previously discussed on cfe-dev: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2014-June/037577.html Adding testing capability via c-index-test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214410 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 27655774f0..972f42e69a 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -3635,6 +3635,20 @@ CINDEX_LINKAGE CXString clang_Cursor_getRawCommentText(CXCursor C); */ CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C); +/** + * @} + */ + +/** \defgroup CINDEX_MANGLE Name Mangling API Functions + * + * @{ + */ + +/** + * \brief Retrieve the CXString representing the mangled name of the cursor. + */ +CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor); + /** * @} */ diff --git a/test/Index/print-mangled-name.cpp b/test/Index/print-mangled-name.cpp new file mode 100644 index 0000000000..5aeb57d04b --- /dev/null +++ b/test/Index/print-mangled-name.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-pch %s -o %t_linux.ast +// RUN: c-index-test -test-print-mangle %t_linux.ast | FileCheck %s --check-prefix=ITANIUM + +// RUN: %clang_cc1 -triple i686-pc-win32 -emit-pch %s -o %t_msft.ast +// RUN: c-index-test -test-print-mangle %t_msft.ast | 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 diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 07be22a5e9..b1d4a4d883 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -1362,6 +1362,19 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p, return CXChildVisit_Recurse; } +/******************************************************************************/ +/* Mangling testing. */ +/******************************************************************************/ + +static enum CXChildVisitResult PrintMangledName(CXCursor cursor, CXCursor p, + CXClientData d) { + CXString MangledName; + PrintCursor(cursor, NULL); + MangledName = clang_Cursor_getMangling(cursor); + printf(" [mangled=%s]\n", clang_getCString(MangledName)); + return CXChildVisit_Continue; +} + /******************************************************************************/ /* Bitwidth testing. */ /******************************************************************************/ @@ -4081,6 +4094,8 @@ int cindextest_main(int argc, const char **argv) { 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") == 0) + return perform_test_load_tu(argv[2], "all", NULL, PrintMangledName, NULL); else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) { if (argc > 2) return print_usrs(argv + 2, argv + argc); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 57bea9927d..0c1770d1b3 100644 --- a/tools/libclang/CIndex.cpp +++ b/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,31 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, return cxloc::translateSourceRange(Ctx, Loc); } +CXString clang_Cursor_getMangling(CXCursor C) { + 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 || !(isa(D) || isa(D))) + return cxstring::createEmpty(); + + const NamedDecl *ND = cast(D); + std::unique_ptr MC(ND->getASTContext().createMangleContext()); + + 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); diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 48eec25767..ad0d585c85 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -9,6 +9,7 @@ clang_CXXMethod_isVirtual clang_Cursor_getArgument clang_Cursor_getBriefCommentText clang_Cursor_getCommentRange +clang_Cursor_getMangling clang_Cursor_getParsedComment clang_Cursor_getRawCommentText clang_Cursor_getNumArguments