clang  3.9.0
CodegenNameGenerator.cpp
Go to the documentation of this file.
1 //===- CodegenNameGenerator.cpp - Codegen name generation -----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Determines the name that the symbol will get for code generation.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/Mangle.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/Mangler.h"
23 #include "llvm/Support/raw_ostream.h"
24 
25 using namespace clang;
26 using namespace clang::index;
27 
29  std::unique_ptr<MangleContext> MC;
30  llvm::DataLayout DL;
31 
33  : MC(Ctx.createMangleContext()),
34  DL(Ctx.getTargetInfo().getDataLayout()) {}
35 
36  bool writeName(const Decl *D, raw_ostream &OS) {
37  // First apply frontend mangling.
38  SmallString<128> FrontendBuf;
39  llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
40  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
41  if (FD->isDependentContext())
42  return true;
43  if (writeFuncOrVarName(FD, FrontendBufOS))
44  return true;
45  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
46  if (writeFuncOrVarName(VD, FrontendBufOS))
47  return true;
48  } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
49  MC->mangleObjCMethodNameWithoutSize(MD, OS);
50  return false;
51  } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
52  writeObjCClassName(ID, FrontendBufOS);
53  } else {
54  return true;
55  }
56 
57  // Now apply backend mangling.
58  llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
59  return false;
60  }
61 
62  std::string getName(const Decl *D) {
63  std::string Name;
64  {
65  llvm::raw_string_ostream OS(Name);
66  writeName(D, OS);
67  }
68  return Name;
69  }
70 
71  std::vector<std::string> getAllManglings(const Decl *D) {
72  if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
73  return {};
74 
75  const NamedDecl *ND = cast<NamedDecl>(D);
76 
77  ASTContext &Ctx = ND->getASTContext();
78  std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
79 
80  std::vector<std::string> Manglings;
81 
82  auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
83  auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
84  /*IsCSSMethod=*/true);
85  auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
86  return CC == DefaultCC;
87  };
88 
89  if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
90  Manglings.emplace_back(getMangledStructor(CD, Ctor_Base));
91 
92  if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
93  if (!CD->getParent()->isAbstract())
94  Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete));
95 
96  if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
97  if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
98  if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
99  Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure));
100  } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
101  Manglings.emplace_back(getMangledStructor(DD, Dtor_Base));
102  if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
103  Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete));
104  if (DD->isVirtual())
105  Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting));
106  }
107  } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
108  Manglings.emplace_back(getName(ND));
109  if (MD->isVirtual())
110  if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
111  for (const auto &T : *TIV)
112  Manglings.emplace_back(getMangledThunk(MD, T));
113  }
114 
115  return Manglings;
116  }
117 
118 private:
119  bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) {
120  if (MC->shouldMangleDeclName(D)) {
121  if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
122  MC->mangleCXXCtor(CtorD, Ctor_Complete, OS);
123  else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
124  MC->mangleCXXDtor(DtorD, Dtor_Complete, OS);
125  else
126  MC->mangleName(D, OS);
127  return false;
128  } else {
129  IdentifierInfo *II = D->getIdentifier();
130  if (!II)
131  return true;
132  OS << II->getName();
133  return false;
134  }
135  }
136 
137  void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
138  OS << getClassSymbolPrefix();
139  OS << D->getObjCRuntimeNameAsString();
140  }
141 
142  static StringRef getClassSymbolPrefix() {
143  return "OBJC_CLASS_$_";
144  }
145 
146  std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {
147  std::string FrontendBuf;
148  llvm::raw_string_ostream FOS(FrontendBuf);
149 
150  if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
151  MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
152  else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
153  MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
154 
155  std::string BackendBuf;
156  llvm::raw_string_ostream BOS(BackendBuf);
157 
158  llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
159 
160  return BOS.str();
161  }
162 
163  std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) {
164  std::string FrontendBuf;
165  llvm::raw_string_ostream FOS(FrontendBuf);
166 
167  MC->mangleThunk(MD, T, FOS);
168 
169  std::string BackendBuf;
170  llvm::raw_string_ostream BOS(BackendBuf);
171 
172  llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
173 
174  return BOS.str();
175  }
176 };
177 
179  : Impl(new Implementation(Ctx)) {
180 }
181 
183 }
184 
185 bool CodegenNameGenerator::writeName(const Decl *D, raw_ostream &OS) {
186  return Impl->writeName(D, OS);
187 }
188 
189 std::string CodegenNameGenerator::getName(const Decl *D) {
190  return Impl->getName(D);
191 }
192 
193 std::vector<std::string> CodegenNameGenerator::getAllManglings(const Decl *D) {
194  return Impl->getAllManglings(D);
195 }
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Definition: DeclObjC.cpp:1465
Defines the clang::ASTContext interface.
Complete object ctor.
Definition: ABI.h:26
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Definition: Decl.h:232
Default closure variant of a ctor.
Definition: ABI.h:30
One of these records is kept for each identifier that is lexed.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
The this pointer adjustment as well as an optional return adjustment for a thunk. ...
Definition: ABI.h:179
Base object ctor.
Definition: ABI.h:27
Deleting dtor.
Definition: ABI.h:35
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.
Definition: DeclObjC.h:1091
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3073
StringRef getName() const
Return the actual identifier string.
Base object dtor.
Definition: ABI.h:37
const std::string ID
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.
Definition: DeclCXX.h:1736
Complete object dtor.
Definition: ABI.h:36
std::vector< std::string > getAllManglings(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
CallingConv getDefaultCallingConvention(bool isVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current target.
Defines the clang::TargetInfo interface.
NamedDecl - This represents a decl with a name.
Definition: Decl.h:213