21 #include "llvm/IR/DataLayout.h" 22 #include "llvm/IR/Mangler.h" 23 #include "llvm/Support/raw_ostream.h" 25 using namespace clang;
29 std::unique_ptr<MangleContext>
MC;
33 : MC(Ctx.createMangleContext()),
34 DL(Ctx.getTargetInfo().getDataLayout()) {}
39 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
40 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
41 if (FD->isDependentContext())
43 if (writeFuncOrVarName(FD, FrontendBufOS))
45 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
46 if (writeFuncOrVarName(VD, FrontendBufOS))
48 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
49 MC->mangleObjCMethodNameWithoutSize(MD, OS);
51 }
else if (
auto *
ID = dyn_cast<ObjCInterfaceDecl>(D)) {
52 writeObjCClassName(
ID, FrontendBufOS);
58 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(),
DL);
65 llvm::raw_string_ostream OS(Name);
78 if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
79 ClassName = OID->getObjCRuntimeNameAsString();
80 else if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
81 ClassName = OID->getObjCRuntimeNameAsString();
83 if (ClassName.empty())
86 auto Mangle = [&](
ObjCKind Kind, StringRef ClassName) -> std::string {
88 auto Prefix = getClassSymbolPrefix(Kind, OCD->
getASTContext());
89 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
100 if (
const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
103 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
106 const NamedDecl *ND = cast<NamedDecl>(D);
109 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
111 std::vector<std::string> Manglings;
117 return CC == DefaultCC;
120 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
121 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Base));
123 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
124 if (!CD->getParent()->isAbstract())
125 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Complete));
127 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
128 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
131 }
else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
132 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Base));
133 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
134 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Complete));
136 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Deleting));
138 }
else if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
139 Manglings.emplace_back(
getName(ND));
141 if (
const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
142 for (
const auto &T : *TIV)
143 Manglings.emplace_back(getMangledThunk(MD, T));
150 bool writeFuncOrVarName(
const NamedDecl *D, raw_ostream &OS) {
151 if (MC->shouldMangleDeclName(D)) {
152 if (
const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
154 else if (
const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
157 MC->mangleName(D, OS);
175 return Kind ==
ObjCMetaclass ?
"_OBJC_METACLASS_" :
"_OBJC_CLASS_";
176 return Kind ==
ObjCMetaclass ?
"OBJC_METACLASS_$_" :
"OBJC_CLASS_$_";
180 std::string FrontendBuf;
181 llvm::raw_string_ostream FOS(FrontendBuf);
183 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
184 MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
185 else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
186 MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
188 std::string BackendBuf;
189 llvm::raw_string_ostream BOS(BackendBuf);
191 llvm::Mangler::getNameWithPrefix(BOS, FOS.str(),
DL);
197 std::string FrontendBuf;
198 llvm::raw_string_ostream FOS(FrontendBuf);
200 MC->mangleThunk(MD, T, FOS);
202 std::string BackendBuf;
203 llvm::raw_string_ostream BOS(BackendBuf);
205 llvm::Mangler::getNameWithPrefix(BOS, FOS.str(),
DL);
219 return Impl->writeName(D, OS);
223 return Impl->getName(D);
227 return Impl->getAllManglings(D);
Defines the clang::ASTContext interface.
std::string getName(const Decl *D)
CodegenNameGenerator(ASTContext &Ctx)
Decl - This represents one declaration (or definition), e.g.
Default closure variant of a ctor.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
The this pointer adjustment as well as an optional return adjustment for a thunk. ...
ObjCContainerDecl - Represents a container for method declarations.
std::vector< std::string > getAllManglings(const ObjCContainerDecl *OCD)
std::vector< std::string > getAllManglings(const Decl *D)
This can return multiple mangled names when applicable, e.g.
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
bool writeName(const Decl *D, raw_ostream &OS)
Represents an ObjC class declaration.
Represents a prototype with parameter type info, e.g.
bool isGNUFamily() const
Is this runtime basically of the GNU family of runtimes?
std::unique_ptr< MangleContext > MC
clang::ObjCRuntime ObjCRuntime
ASTContext & getASTContext() const LLVM_READONLY
std::string getName(const Decl *D)
Version of writeName function that returns a string.
Represents a static or instance method of a struct/union/class.
bool writeName(const Decl *D, raw_ostream &OS)
StringRef getName() const
Return the actual identifier string.
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current target.
Dataflow Directional Tag Classes.
std::vector< std::string > getAllManglings(const Decl *D)
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Defines the clang::TargetInfo interface.
Implementation(ASTContext &Ctx)
This represents a decl that may have a name.
const LangOptions & getLangOpts() const