Author: compnerd Date: Wed Nov 11 21:57:22 2015 New Revision: 252853 URL: http://llvm.org/viewvc/llvm-project?rev=252853&view=rev Log: libclang: add clang_Cursor_getCXXManglings
This function permits the mangling of a C++ 'structor. Depending on the ABI and the declaration, the declaration may contain more than one associated symbol for a given declaration. This allows the consumer to retrieve all of the associated symbols for the declaration the cursor points to. Added: cfe/trunk/test/Index/print-cxx-manglings.cpp Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/tools/c-index-test/c-index-test.c cfe/trunk/tools/libclang/CIndex.cpp cfe/trunk/tools/libclang/libclang.exports Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=252853&r1=252852&r2=252853&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Wed Nov 11 21:57:22 2015 @@ -3863,6 +3863,12 @@ CINDEX_LINKAGE CXString clang_Cursor_get CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor); /** + * \brief Retrieve the CXStrings representing the mangled symbols of the C++ + * constructor or destructor at the cursor. + */ +CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor); + +/** * @} */ Added: cfe/trunk/test/Index/print-cxx-manglings.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-cxx-manglings.cpp?rev=252853&view=auto ============================================================================== --- cfe/trunk/test/Index/print-cxx-manglings.cpp (added) +++ cfe/trunk/test/Index/print-cxx-manglings.cpp Wed Nov 11 21:57:22 2015 @@ -0,0 +1,66 @@ +// REQUIRES: x86-registered-target + +// RUN: c-index-test -write-pch %t.itanium.ast -target i686-pc-linux-gnu -fdeclspec %s +// RUN: c-index-test -test-print-manglings %t.itanium.ast | FileCheck --check-prefix=ITANIUM %s + +// RUN: c-index-test -write-pch %t.macho.ast -target i686-apple-darwin -fdeclspec %s +// RUN: c-index-test -test-print-manglings %t.macho.ast | FileCheck --check-prefix=MACHO %s + +// RUN: c-index-test -write-pch %t.msvc.ast -target i686-pc-windows %s +// RUN: c-index-test -test-print-manglings %t.msvc.ast | FileCheck --check-prefix=MSVC %s + +struct s { + s(int); + ~s(); + int m(int); +}; + +// ITANIUM: CXXConstructor=s{{.*}}[mangled=_ZN1sC2Ei] [mangled=_ZN1sC1Ei] +// ITANIUM: CXXDestructor=~s{{.*}}[mangled=_ZN1sD2Ev] [mangled=_ZN1sD1Ev] [mangled=_ZN1sD0Ev] + +// MACHO: CXXConstructor=s{{.*}}[mangled=__ZN1sC2Ei] [mangled=__ZN1sC1Ei] +// MACHO: CXXDestructor=~s{{.*}}[mangled=__ZN1sD2Ev] [mangled=__ZN1sD1Ev] [mangled=__ZN1sD0Ev] + +// MSVC: CXXConstructor=s{{.*}}[mangled=??0s@@QAE@H@Z] +// MSVC: CXXDestructor=~s{{.*}}[mangled=??1s@@QAE@XZ] + +struct t { + t(int); + virtual ~t(); + int m(int); +}; + +// ITANIUM: CXXConstructor=t{{.*}}[mangled=_ZN1tC2Ei] [mangled=_ZN1tC1Ei] +// ITANIUM: CXXDestructor=~t{{.*}}[mangled=_ZN1tD2Ev] [mangled=_ZN1tD1Ev] + +// MACHO: CXXConstructor=t{{.*}}[mangled=__ZN1tC2Ei] [mangled=__ZN1tC1Ei] +// MACHO: CXXDestructor=~t{{.*}}[mangled=__ZN1tD2Ev] [mangled=__ZN1tD1Ev] + +// MSVC: CXXConstructor=t{{.*}}[mangled=??0t@@QAE@H@Z] +// MSVC: CXXDestructor=~t{{.*}}[mangled=??1t@@UAE@XZ] + +struct u { + u(); + virtual ~u(); + virtual int m(int) = 0; +}; + +// ITANIUM: CXXConstructor=u{{.*}}[mangled=_ZN1uC2Ev] +// ITANIUM: CXXDestructor=~u{{.*}}[mangled=_ZN1uD2Ev] [mangled=_ZN1uD1Ev] + +// MACHO: CXXConstructor=u{{.*}}[mangled=__ZN1uC2Ev] +// MACHO: CXXDestructor=~u{{.*}}[mangled=__ZN1uD2Ev] [mangled=__ZN1uD1Ev] + +// MSVC: CXXConstructor=u{{.*}}[mangled=??0u@@QAE@XZ] +// MSVC: CXXDestructor=~u{{.*}}[mangled=??1u@@UAE@XZ] + +struct v { + __declspec(dllexport) v(int = 0); +}; + +// ITANIUM: CXXConstructor=v{{.*}}[mangled=_ZN1vC2Ei] [mangled=_ZN1vC1Ei] + +// MACHO: CXXConstructor=v{{.*}}[mangled=__ZN1vC2Ei] [mangled=__ZN1vC1Ei] + +// MSVC: CXXConstructor=v{{.*}}[mangled=??0v@@QAE@H@Z] [mangled=??_Fv@@QAEXXZ] + Modified: cfe/trunk/tools/c-index-test/c-index-test.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=252853&r1=252852&r2=252853&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/c-index-test.c (original) +++ cfe/trunk/tools/c-index-test/c-index-test.c Wed Nov 11 21:57:22 2015 @@ -1441,6 +1441,25 @@ static enum CXChildVisitResult PrintMang return CXChildVisit_Continue; } +static enum CXChildVisitResult PrintManglings(CXCursor cursor, CXCursor p, + CXClientData d) { + unsigned I, E; + CXStringSet *Manglings = NULL; + if (clang_isUnexposed(clang_getCursorKind(cursor))) + return CXChildVisit_Recurse; + if (!clang_isDeclaration(clang_getCursorKind(cursor))) + return CXChildVisit_Recurse; + if (clang_getCursorKind(cursor) == CXCursor_ParmDecl) + return CXChildVisit_Continue; + PrintCursor(cursor, NULL); + Manglings = clang_Cursor_getCXXManglings(cursor); + for (I = 0, E = Manglings->Count; I < E; ++I) + printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I])); + clang_disposeStringSet(Manglings); + printf("\n"); + return CXChildVisit_Recurse; +} + /******************************************************************************/ /* Bitwidth testing. */ /******************************************************************************/ @@ -4163,6 +4182,8 @@ int cindextest_main(int argc, const char 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 > 2 && strcmp(argv[1], "-test-print-manglings") == 0) + return perform_test_load_tu(argv[2], "all", NULL, PrintManglings, NULL); else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) { if (argc > 2) return print_usrs(argv + 2, argv + argc); Modified: cfe/trunk/tools/libclang/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=252853&r1=252852&r2=252853&view=diff ============================================================================== --- cfe/trunk/tools/libclang/CIndex.cpp (original) +++ cfe/trunk/tools/libclang/CIndex.cpp Wed Nov 11 21:57:22 2015 @@ -3911,6 +3911,75 @@ CXString clang_Cursor_getMangling(CXCurs return cxstring::createDup(FinalBufOS.str()); } +static std::string getMangledStructor(std::unique_ptr<MangleContext> &M, + std::unique_ptr<llvm::DataLayout> &DL, + const NamedDecl *ND, + unsigned StructorType) { + std::string FrontendBuf; + llvm::raw_string_ostream FOS(FrontendBuf); + + if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) + M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS); + else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) + M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS); + + std::string BackendBuf; + llvm::raw_string_ostream BOS(BackendBuf); + + llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); + + return BOS.str(); +} + +CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) { + if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind)) + return nullptr; + + const Decl *D = getCursorDecl(C); + if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D))) + return nullptr; + + const NamedDecl *ND = cast<NamedDecl>(D); + + ASTContext &Ctx = ND->getASTContext(); + std::unique_ptr<MangleContext> M(Ctx.createMangleContext()); + std::unique_ptr<llvm::DataLayout> DL( + new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString())); + + std::vector<std::string> Manglings; + + auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { + auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, + /*IsCSSMethod=*/true); + auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv(); + return CC == DefaultCC; + }; + + if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) { + Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base)); + + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) + if (!CD->getParent()->isAbstract()) + Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete)); + + if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) + if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor()) + if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0)) + Manglings.emplace_back(getMangledStructor(M, DL, CD, + Ctor_DefaultClosure)); + } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) { + Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base)); + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) { + Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete)); + + if (!DD->isVirtual()) + Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting)); + } + } + + return cxstring::createSet(Manglings); +} + CXString clang_getCursorDisplayName(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getCursorSpelling(C); Modified: cfe/trunk/tools/libclang/libclang.exports URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=252853&r1=252852&r2=252853&view=diff ============================================================================== --- cfe/trunk/tools/libclang/libclang.exports (original) +++ cfe/trunk/tools/libclang/libclang.exports Wed Nov 11 21:57:22 2015 @@ -15,6 +15,7 @@ clang_Cursor_getTemplateArgumentValue clang_Cursor_getTemplateArgumentUnsignedValue clang_Cursor_getBriefCommentText clang_Cursor_getCommentRange +clang_Cursor_getCXXManglings clang_Cursor_getMangling clang_Cursor_getParsedComment clang_Cursor_getRawCommentText _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits