24 #include "llvm/ADT/StringExtras.h" 25 #include "llvm/IR/DataLayout.h" 26 #include "llvm/IR/Mangler.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/raw_ostream.h" 30 using namespace clang;
39 unsigned discriminator = Context.
getBlockId(BD,
true);
40 if (discriminator == 0)
41 Out <<
"__" << Outer <<
"_block_invoke";
43 Out <<
"__" << Outer <<
"_block_invoke_" << discriminator+1;
46 void MangleContext::anchor() { }
58 return FD->isExternC();
65 const llvm::Triple &Triple = TI.
getTriple();
66 if (!Triple.isOSWindows() ||
67 !(Triple.getArch() == llvm::Triple::x86 ||
68 Triple.getArch() == llvm::Triple::x86_64))
113 if (D->
hasAttr<AsmLabelAttr>())
122 if (
const AsmLabelAttr *ALA = D->
getAttr<AsmLabelAttr>()) {
127 if (!ALA->getIsLiteralLabel() || ALA->getLabel().startswith(
"llvm.")) {
128 Out << ALA->getLabel();
142 Out << ALA->getLabel();
164 Out <<
"__regcall3__";
183 assert(!Proto->isVariadic());
184 unsigned ArgWords = 0;
188 for (
const auto &AT : Proto->param_types())
199 unsigned discriminator =
getBlockId(BD,
false);
207 if (discriminator == 0)
208 Out <<
"_block_invoke";
210 Out <<
"_block_invoke_" << discriminator+1;
215 raw_ostream &ResStream) {
217 llvm::raw_svector_ostream Out(Buffer);
224 raw_ostream &ResStream) {
226 llvm::raw_svector_ostream Out(Buffer);
233 assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
236 llvm::raw_svector_ostream Stream(Buffer);
237 if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
240 assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) &&
241 "expected a NamedDecl or BlockDecl");
242 if (isa<BlockDecl>(DC))
243 for (; DC && isa<BlockDecl>(DC); DC = DC->
getParent())
245 assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
246 "expected a TranslationUnitDecl or a NamedDecl");
247 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
249 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
251 else if (
auto ND = dyn_cast<NamedDecl>(DC)) {
253 Stream << ND->getIdentifier()->getName();
271 assert (CD &&
"Missing container decl in GetNameForMethod");
274 OS << CID->getClassInterface()->getName();
275 OS <<
'(' << *CID <<
')';
287 llvm::raw_svector_ostream OS(Name);
290 Out << OS.str().size() << OS.str();
294 std::unique_ptr<MangleContext> MC;
299 : MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) {
305 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
306 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
307 if (FD->isDependentContext())
309 if (writeFuncOrVarName(FD, FrontendBufOS))
311 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
312 if (writeFuncOrVarName(VD, FrontendBufOS))
314 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
315 MC->mangleObjCMethodNameWithoutSize(MD, OS);
317 }
else if (
auto *
ID = dyn_cast<ObjCInterfaceDecl>(D)) {
318 writeObjCClassName(
ID, FrontendBufOS);
324 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
331 llvm::raw_string_ostream OS(Name);
345 return Kind == ObjCMetaclass ?
"_OBJC_METACLASS_" :
"_OBJC_CLASS_";
346 return Kind == ObjCMetaclass ?
"OBJC_METACLASS_$_" :
"OBJC_CLASS_$_";
351 if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
352 ClassName = OID->getObjCRuntimeNameAsString();
353 else if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
354 ClassName = OID->getObjCRuntimeNameAsString();
356 if (ClassName.empty())
359 auto Mangle = [&](
ObjCKind Kind, StringRef ClassName) -> std::string {
361 auto Prefix = getClassSymbolPrefix(Kind, OCD->
getASTContext());
362 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
363 return Mangled.str();
367 Mangle(ObjCClass, ClassName),
368 Mangle(ObjCMetaclass, ClassName),
373 if (
const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
374 return getAllManglings(OCD);
376 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
379 const NamedDecl *ND = cast<NamedDecl>(D);
382 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
384 std::vector<std::string> Manglings;
390 return CC == DefaultCC;
393 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
394 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Base));
396 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
397 if (!CD->getParent()->isAbstract())
398 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Complete));
400 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
401 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
404 }
else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
405 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Base));
406 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
407 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Complete));
409 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Deleting));
411 }
else if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
412 Manglings.emplace_back(
getName(ND));
414 if (
const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
415 for (
const auto &T : *TIV)
416 Manglings.emplace_back(getMangledThunk(MD, T));
423 bool writeFuncOrVarName(
const NamedDecl *D, raw_ostream &OS) {
424 if (MC->shouldMangleDeclName(D)) {
425 if (
const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
427 else if (
const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
430 MC->mangleName(D, OS);
446 std::string getMangledStructor(
const NamedDecl *ND,
unsigned StructorType) {
447 std::string FrontendBuf;
448 llvm::raw_string_ostream FOS(FrontendBuf);
450 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
451 MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
452 else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
453 MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
455 std::string BackendBuf;
456 llvm::raw_string_ostream BOS(BackendBuf);
458 llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
464 std::string FrontendBuf;
465 llvm::raw_string_ostream FOS(FrontendBuf);
467 MC->mangleThunk(MD, T, FOS);
469 std::string BackendBuf;
470 llvm::raw_string_ostream BOS(BackendBuf);
472 llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
484 return Impl->writeName(D, OS);
488 return Impl->getName(D);
492 return Impl->getAllManglings(D);
Defines the clang::ASTContext interface.
Represents a function declaration or definition.
A (possibly-)qualified type.
Module * getOwningModuleForLinkage(bool IgnoreLinkage=false) const
Get the module that owns this declaration for linkage purposes.
FunctionType - C99 6.7.5.3 - Function Declarators.
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream &)=0
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Defines the SourceManager interface.
std::vector< std::string > getAllManglings(const Decl *D)
virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, raw_ostream &)=0
Decl - This represents one declaration (or definition), e.g.
Defines the C++ template declaration subclasses.
const TargetInfo & getTargetInfo() const
Represents a C++ constructor within a class.
Default closure variant of a ctor.
ObjCMethodDecl - Represents an instance or class method declaration.
Defines the clang::Expr interface and subclasses for C++ expressions.
void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
static CCMangling getCallingConvMangling(const ASTContext &Context, const NamedDecl *ND)
One of these records is kept for each identifier that is lexed.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool writeName(const Decl *D, raw_ostream &OS)
Writes name for D to OS.
std::string getName(const Decl *D)
The this pointer adjustment as well as an optional return adjustment for a thunk. ...
bool shouldMangleDeclName(const NamedDecl *D)
ObjCContainerDecl - Represents a container for method declarations.
The Microsoft ABI is the ABI used by Microsoft Visual Studio (and compatible compilers).
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
Enums/classes describing ABI related information about constructors, destructors and thunks...
Represents an ObjC class declaration.
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
void mangleName(const NamedDecl *D, raw_ostream &)
bool writeName(const Decl *D, raw_ostream &OS)
Represents a prototype with parameter type info, e.g.
std::vector< std::string > getAllManglings(const ObjCContainerDecl *OCD)
Exposes information about the current target.
CXXDtorType
C++ destructor types.
ASTContext & getASTContext() const
bool isGNUFamily() const
Is this runtime basically of the GNU family of runtimes?
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Implementation(ASTContext &Ctx)
const T * castAs() const
Member-template castAs<specific type>.
Represents a C++ destructor within a class.
DeclContext * getDeclContext()
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
clang::ObjCRuntime ObjCRuntime
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isInstanceMethod() const
Selector getSelector() const
CallingConv
CallingConv - Specifies the calling convention that a function uses.
static StringRef getClassSymbolPrefix(ObjCKind Kind, const ASTContext &Context)
unsigned getBlockId(const BlockDecl *BD, bool Local)
ASTContext & getASTContext() const LLVM_READONLY
void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, const BlockDecl *BD, raw_ostream &Out)
virtual bool shouldMangleCXXName(const NamedDecl *D)=0
Represents a static or instance method of a struct/union/class.
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
std::vector< std::string > getAllManglings(const Decl *D)
virtual void mangleCXXName(const NamedDecl *D, raw_ostream &)=0
const llvm::DataLayout & getDataLayout() const
CXXCtorType
C++ constructor types.
StringRef getName() const
Return the actual identifier string.
void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID, raw_ostream &Out)
void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out)
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static std::string getName(const CallEvent &Call)
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &)
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
static void mangleFunctionBlock(MangleContext &Context, StringRef Outer, const BlockDecl *BD, raw_ostream &Out)
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
CallingConv getCallConv() const
Defines the clang::TargetInfo interface.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
This represents a decl that may have a name.
std::string getName(const Decl *D)
void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, const BlockDecl *BD, raw_ostream &Out)
const LangOptions & getLangOpts() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
ASTNameGenerator(ASTContext &Ctx)
bool hasExternalFormalLinkage() const
True if this decl has external linkage.
static bool isExternC(const NamedDecl *ND)