diff options
-rw-r--r-- | clang/include/clang-c/Index.h | 6 | ||||
-rw-r--r-- | clang/test/Index/print-cxx-manglings.cpp | 66 | ||||
-rw-r--r-- | clang/tools/c-index-test/c-index-test.c | 21 | ||||
-rw-r--r-- | clang/tools/libclang/CIndex.cpp | 69 | ||||
-rw-r--r-- | clang/tools/libclang/libclang.exports | 1 |
5 files changed, 163 insertions, 0 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index cd5eb4e4d22..fd8fb130f84 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -3863,6 +3863,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C); 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); + +/** * @} */ diff --git a/clang/test/Index/print-cxx-manglings.cpp b/clang/test/Index/print-cxx-manglings.cpp new file mode 100644 index 00000000000..05b86473a24 --- /dev/null +++ b/clang/test/Index/print-cxx-manglings.cpp @@ -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] + diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index 26ef5f204b6..8181642d71b 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -1441,6 +1441,25 @@ static enum CXChildVisitResult PrintMangledName(CXCursor cursor, CXCursor p, 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 **argv) { 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); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index ac6f98de40e..6bd90e53ba9 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3911,6 +3911,75 @@ CXString clang_Cursor_getMangling(CXCursor C) { 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); diff --git a/clang/tools/libclang/libclang.exports b/clang/tools/libclang/libclang.exports index 352ba5766ae..6f6e18523ba 100644 --- a/clang/tools/libclang/libclang.exports +++ b/clang/tools/libclang/libclang.exports @@ -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 |