From: Argyrios Kyrtzidis Date: Sun, 14 Feb 2016 22:30:14 +0000 (+0000) Subject: [index] Factor libclang's functionality to determing the mangled name of symbols... X-Git-Tag: llvmorg-3.9.0-rc1~14136 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca741cef3e41a09943709ca052791048301cdd60;p=platform%2Fupstream%2Fllvm.git [index] Factor libclang's functionality to determing the mangled name of symbols into the clangIndex library. llvm-svn: 260858 --- diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h index bf4b23c..d489746 100644 --- a/clang/include/clang/AST/Mangle.h +++ b/clang/include/clang/AST/Mangle.h @@ -124,6 +124,7 @@ public: void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out); + void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &); void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; diff --git a/clang/include/clang/Index/CodegenNameGenerator.h b/clang/include/clang/Index/CodegenNameGenerator.h new file mode 100644 index 0000000..e8dc196 --- /dev/null +++ b/clang/include/clang/Index/CodegenNameGenerator.h @@ -0,0 +1,52 @@ +//===- CodegenNameGenerator.h - Codegen name generation -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Determines the name that the symbol will get for code generation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H +#define LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H + +#include "clang/Basic/LLVM.h" +#include +#include +#include + +namespace clang { + class ASTContext; + class Decl; + +namespace index { + +class CodegenNameGenerator { +public: + explicit CodegenNameGenerator(ASTContext &Ctx); + ~CodegenNameGenerator(); + + /// \returns true on failure to produce a name for the given decl, false on + /// success. + bool writeName(const Decl *D, raw_ostream &OS); + + /// Version of \c writeName function that returns a string. + std::string getName(const Decl *D); + + /// This can return multiple mangled names when applicable, e.g. for C++ + /// constructors/destructors. + std::vector getAllManglings(const Decl *D); + +private: + struct Implementation; + std::unique_ptr Impl; +}; + +} // namespace index +} // namespace clang + +#endif // LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H diff --git a/clang/include/clang/Index/IndexDataConsumer.h b/clang/include/clang/Index/IndexDataConsumer.h index cb00345..3154370 100644 --- a/clang/include/clang/Index/IndexDataConsumer.h +++ b/clang/include/clang/Index/IndexDataConsumer.h @@ -13,6 +13,7 @@ #include "clang/Index/IndexSymbol.h" namespace clang { + class ASTContext; class DeclContext; class Expr; class FileID; @@ -33,6 +34,8 @@ public: virtual ~IndexDataConsumer() {} + virtual void initialize(ASTContext &Ctx) {} + /// \returns true to continue indexing, or false to abort. virtual bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, ArrayRef Relations, diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp index b1193ca..7a9cf18 100644 --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -254,11 +254,8 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, mangleFunctionBlock(*this, Buffer, BD, Out); } -void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, - raw_ostream &Out) { - SmallString<64> Name; - llvm::raw_svector_ostream OS(Name); - +void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, + raw_ostream &OS) { const ObjCContainerDecl *CD = dyn_cast(MD->getDeclContext()); assert (CD && "Missing container decl in GetNameForMethod"); @@ -268,6 +265,13 @@ void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, OS << ' '; MD->getSelector().print(OS); OS << ']'; - +} + +void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, + raw_ostream &Out) { + SmallString<64> Name; + llvm::raw_svector_ostream OS(Name); + + mangleObjCMethodNameWithoutSize(MD, OS); Out << OS.str().size() << OS.str(); } diff --git a/clang/lib/Index/CMakeLists.txt b/clang/lib/Index/CMakeLists.txt index cb2b931..7e39e49 100644 --- a/clang/lib/Index/CMakeLists.txt +++ b/clang/lib/Index/CMakeLists.txt @@ -3,14 +3,15 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangIndex + CodegenNameGenerator.cpp CommentToXML.cpp - USRGeneration.cpp IndexBody.cpp IndexDecl.cpp IndexingAction.cpp IndexingContext.cpp IndexSymbol.cpp IndexTypeSourceInfo.cpp + USRGeneration.cpp ADDITIONAL_HEADERS IndexingContext.h diff --git a/clang/lib/Index/CodegenNameGenerator.cpp b/clang/lib/Index/CodegenNameGenerator.cpp new file mode 100644 index 0000000..d663cc3 --- /dev/null +++ b/clang/lib/Index/CodegenNameGenerator.cpp @@ -0,0 +1,197 @@ +//===- CodegenNameGenerator.cpp - Codegen name generation -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Determines the name that the symbol will get for code generation. +// +//===----------------------------------------------------------------------===// + +#include "clang/Index/CodegenNameGenerator.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/VTableBuilder.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Mangler.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; +using namespace clang::index; + +struct CodegenNameGenerator::Implementation { + std::unique_ptr MC; + llvm::DataLayout DL; + + Implementation(ASTContext &Ctx) + : MC(Ctx.createMangleContext()), + DL(Ctx.getTargetInfo().getDataLayoutString()) {} + + bool writeName(const Decl *D, raw_ostream &OS) { + // First apply frontend mangling. + SmallString<128> FrontendBuf; + llvm::raw_svector_ostream FrontendBufOS(FrontendBuf); + if (auto *FD = dyn_cast(D)) { + if (FD->isDependentContext()) + return true; + if (writeFuncOrVarName(FD, FrontendBufOS)) + return true; + } else if (auto *VD = dyn_cast(D)) { + if (writeFuncOrVarName(VD, FrontendBufOS)) + return true; + } else if (auto *MD = dyn_cast(D)) { + MC->mangleObjCMethodNameWithoutSize(MD, OS); + return false; + } else if (auto *ID = dyn_cast(D)) { + writeObjCClassName(ID, FrontendBufOS); + } else { + return true; + } + + // Now apply backend mangling. + llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL); + return false; + } + + std::string getName(const Decl *D) { + std::string Name; + { + llvm::raw_string_ostream OS(Name); + writeName(D, OS); + } + return Name; + } + + std::vector getAllManglings(const Decl *D) { + if (!(isa(D) || isa(D))) + return {}; + + const NamedDecl *ND = cast(D); + + ASTContext &Ctx = ND->getASTContext(); + std::unique_ptr M(Ctx.createMangleContext()); + std::unique_ptr DL( + new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString())); + + std::vector Manglings; + + auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { + auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, + /*IsCSSMethod=*/true); + auto CC = MD->getType()->getAs()->getCallConv(); + return CC == DefaultCC; + }; + + if (const auto *CD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getMangledStructor(CD, Ctor_Base)); + + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) + if (!CD->getParent()->isAbstract()) + Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete)); + + if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) + if (CD->hasAttr() && CD->isDefaultConstructor()) + if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0)) + Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure)); + } else if (const auto *DD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getMangledStructor(DD, Dtor_Base)); + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) { + Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete)); + if (DD->isVirtual()) + Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting)); + } + } else if (const auto *MD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getName(ND)); + if (MD->isVirtual()) + if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) + for (const auto &T : *TIV) + Manglings.emplace_back(getMangledThunk(MD, T)); + } + + return Manglings; + } + +private: + bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) { + if (MC->shouldMangleDeclName(D)) { + if (const auto *CtorD = dyn_cast(D)) + MC->mangleCXXCtor(CtorD, Ctor_Complete, OS); + else if (const auto *DtorD = dyn_cast(D)) + MC->mangleCXXDtor(DtorD, Dtor_Complete, OS); + else + MC->mangleName(D, OS); + return false; + } else { + IdentifierInfo *II = D->getIdentifier(); + if (!II) + return true; + OS << II->getName(); + return false; + } + } + + void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) { + OS << getClassSymbolPrefix(); + OS << D->getObjCRuntimeNameAsString(); + } + + static StringRef getClassSymbolPrefix() { + return "OBJC_CLASS_$_"; + } + + std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) { + std::string FrontendBuf; + llvm::raw_string_ostream FOS(FrontendBuf); + + if (const auto *CD = dyn_cast_or_null(ND)) + MC->mangleCXXCtor(CD, static_cast(StructorType), FOS); + else if (const auto *DD = dyn_cast_or_null(ND)) + MC->mangleCXXDtor(DD, static_cast(StructorType), FOS); + + std::string BackendBuf; + llvm::raw_string_ostream BOS(BackendBuf); + + llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); + + return BOS.str(); + } + + std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) { + std::string FrontendBuf; + llvm::raw_string_ostream FOS(FrontendBuf); + + MC->mangleThunk(MD, T, FOS); + + std::string BackendBuf; + llvm::raw_string_ostream BOS(BackendBuf); + + llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); + + return BOS.str(); + } +}; + +CodegenNameGenerator::CodegenNameGenerator(ASTContext &Ctx) + : Impl(new Implementation(Ctx)) { +} + +CodegenNameGenerator::~CodegenNameGenerator() { +} + +bool CodegenNameGenerator::writeName(const Decl *D, raw_ostream &OS) { + return Impl->writeName(D, OS); +} + +std::string CodegenNameGenerator::getName(const Decl *D) { + return Impl->getName(D); +} + +std::vector CodegenNameGenerator::getAllManglings(const Decl *D) { + return Impl->getAllManglings(D); +} diff --git a/clang/lib/Index/IndexingAction.cpp b/clang/lib/Index/IndexingAction.cpp index 46c96a3..d744293 100644 --- a/clang/lib/Index/IndexingAction.cpp +++ b/clang/lib/Index/IndexingAction.cpp @@ -50,6 +50,7 @@ public: protected: void Initialize(ASTContext &Context) override { IndexCtx.setASTContext(Context); + IndexCtx.getDataConsumer().initialize(Context); } bool HandleTopLevelDecl(DeclGroupRef DG) override { @@ -170,5 +171,6 @@ void index::indexASTUnit(ASTUnit &Unit, IndexingOptions Opts) { IndexingContext IndexCtx(Opts, *DataConsumer); IndexCtx.setASTContext(Unit.getASTContext()); + DataConsumer->initialize(Unit.getASTContext()); indexTranslationUnit(Unit, IndexCtx); } diff --git a/clang/test/Index/Core/index-source.m b/clang/test/Index/Core/index-source.m index 42c2350..b5a86fb 100644 --- a/clang/test/Index/Core/index-source.m +++ b/clang/test/Index/Core/index-source.m @@ -1,8 +1,8 @@ // RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s @interface Base -// CHECK: [[@LINE-1]]:12 | objc-class/ObjC | Base | c:objc(cs)Base | Decl | rel: 0 +// CHECK: [[@LINE-1]]:12 | objc-class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Decl | rel: 0 -(void)meth; -// CHECK: [[@LINE-1]]:1 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | Decl/Dyn/RelChild | rel: 1 +// CHECK: [[@LINE-1]]:1 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Decl/Dyn/RelChild | rel: 1 // CHECK-NEXT: RelChild | Base | c:objc(cs)Base @end diff --git a/clang/tools/c-index-test/core_main.cpp b/clang/tools/c-index-test/core_main.cpp index c56d66f..e37b342 100644 --- a/clang/tools/c-index-test/core_main.cpp +++ b/clang/tools/c-index-test/core_main.cpp @@ -14,6 +14,7 @@ #include "clang/Index/IndexingAction.h" #include "clang/Index/IndexDataConsumer.h" #include "clang/Index/USRGeneration.h" +#include "clang/Index/CodegenNameGenerator.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" @@ -60,11 +61,16 @@ namespace { class PrintIndexDataConsumer : public IndexDataConsumer { raw_ostream &OS; + std::unique_ptr CGNameGen; public: PrintIndexDataConsumer(raw_ostream &OS) : OS(OS) { } + void initialize(ASTContext &Ctx) override { + CGNameGen.reset(new CodegenNameGenerator(Ctx)); + } + bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, ArrayRef Relations, FileID FID, unsigned Offset, @@ -82,6 +88,10 @@ public: printSymbolNameAndUSR(D, Ctx, OS); OS << " | "; + if (CGNameGen->writeName(D, OS)) + OS << ""; + OS << " | "; + printSymbolRoles(Roles, OS); OS << " | "; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 6f28005..1526900 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -22,17 +22,15 @@ #include "CXType.h" #include "CursorVisitor.h" #include "clang/AST/Attr.h" -#include "clang/AST/Mangle.h" #include "clang/AST/StmtVisitor.h" -#include "clang/AST/VTableBuilder.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticCategories.h" #include "clang/Basic/DiagnosticIDs.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Index/CodegenNameGenerator.h" #include "clang/Index/CommentToXML.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Lexer.h" @@ -43,8 +41,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Format.h" @@ -3976,59 +3972,6 @@ static SourceLocation getLocationFromExpr(const Expr *E) { return E->getLocStart(); } -static std::string getMangledStructor(std::unique_ptr &M, - std::unique_ptr &DL, - const NamedDecl *ND, - unsigned StructorType) { - std::string FrontendBuf; - llvm::raw_string_ostream FOS(FrontendBuf); - - if (const auto *CD = dyn_cast_or_null(ND)) - M->mangleCXXCtor(CD, static_cast(StructorType), FOS); - else if (const auto *DD = dyn_cast_or_null(ND)) - M->mangleCXXDtor(DD, static_cast(StructorType), FOS); - - std::string BackendBuf; - llvm::raw_string_ostream BOS(BackendBuf); - - llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); - - return BOS.str(); -} - -static std::string getMangledName(std::unique_ptr &M, - std::unique_ptr &DL, - const NamedDecl *ND) { - std::string FrontendBuf; - llvm::raw_string_ostream FOS(FrontendBuf); - - M->mangleName(ND, FOS); - - std::string BackendBuf; - llvm::raw_string_ostream BOS(BackendBuf); - - llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); - - return BOS.str(); -} - -static std::string getMangledThunk(std::unique_ptr &M, - std::unique_ptr &DL, - const CXXMethodDecl *MD, - const ThunkInfo &T) { - std::string FrontendBuf; - llvm::raw_string_ostream FOS(FrontendBuf); - - M->mangleThunk(MD, T, FOS); - - std::string BackendBuf; - llvm::raw_string_ostream BOS(BackendBuf); - - llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); - - return BOS.str(); -} - extern "C" { unsigned clang_visitChildren(CXCursor parent, @@ -4377,29 +4320,9 @@ CXString clang_Cursor_getMangling(CXCursor C) { if (!D || !(isa(D) || isa(D))) return cxstring::createEmpty(); - // First apply frontend mangling. - const NamedDecl *ND = cast(D); - ASTContext &Ctx = ND->getASTContext(); - std::unique_ptr MC(Ctx.createMangleContext()); - - std::string FrontendBuf; - llvm::raw_string_ostream FrontendBufOS(FrontendBuf); - if (MC->shouldMangleDeclName(ND)) { - MC->mangleName(ND, FrontendBufOS); - } else { - ND->printName(FrontendBufOS); - } - - // Now apply backend mangling. - std::unique_ptr DL( - new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString())); - - std::string FinalBuf; - llvm::raw_string_ostream FinalBufOS(FinalBuf); - llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()), - *DL); - - return cxstring::createDup(FinalBufOS.str()); + ASTContext &Ctx = D->getASTContext(); + index::CodegenNameGenerator CGNameGen(Ctx); + return cxstring::createDup(CGNameGen.getName(D)); } CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) { @@ -4410,49 +4333,9 @@ CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) { if (!(isa(D) || isa(D))) return nullptr; - const NamedDecl *ND = cast(D); - - ASTContext &Ctx = ND->getASTContext(); - std::unique_ptr M(Ctx.createMangleContext()); - std::unique_ptr DL( - new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString())); - - std::vector Manglings; - - auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { - auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, - /*IsCSSMethod=*/true); - auto CC = MD->getType()->getAs()->getCallConv(); - return CC == DefaultCC; - }; - - if (const auto *CD = dyn_cast_or_null(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() && 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(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)); - } - } else if (const auto *MD = dyn_cast_or_null(ND)) { - Manglings.emplace_back(getMangledName(M, DL, ND)); - if (MD->isVirtual()) - if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) - for (const auto &T : *TIV) - Manglings.emplace_back(getMangledThunk(M, DL, MD, T)); - } - + ASTContext &Ctx = D->getASTContext(); + index::CodegenNameGenerator CGNameGen(Ctx); + std::vector Manglings = CGNameGen.getAllManglings(D); return cxstring::createSet(Manglings); }