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() || !Triple.isX86())
111 if (D->
hasAttr<AsmLabelAttr>())
120 if (
const AsmLabelAttr *ALA = D->
getAttr<AsmLabelAttr>()) {
125 if (!ALA->getIsLiteralLabel() || ALA->getLabel().startswith(
"llvm.")) {
126 Out << ALA->getLabel();
140 Out << ALA->getLabel();
162 Out <<
"__regcall3__";
181 assert(!Proto->isVariadic());
182 unsigned ArgWords = 0;
186 for (
const auto &AT : Proto->param_types())
197 unsigned discriminator =
getBlockId(BD,
false);
205 if (discriminator == 0)
206 Out <<
"_block_invoke";
208 Out <<
"_block_invoke_" << discriminator+1;
213 raw_ostream &ResStream) {
215 llvm::raw_svector_ostream Out(Buffer);
222 raw_ostream &ResStream) {
224 llvm::raw_svector_ostream Out(Buffer);
231 assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
234 llvm::raw_svector_ostream Stream(Buffer);
235 if (
const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
238 assert((isa<NamedDecl>(DC) || isa<BlockDecl>(DC)) &&
239 "expected a NamedDecl or BlockDecl");
240 if (isa<BlockDecl>(DC))
241 for (; DC && isa<BlockDecl>(DC); DC = DC->
getParent())
243 assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
244 "expected a TranslationUnitDecl or a NamedDecl");
245 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
247 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
249 else if (
auto ND = dyn_cast<NamedDecl>(DC)) {
251 Stream << ND->getIdentifier()->getName();
269 assert (CD &&
"Missing container decl in GetNameForMethod");
272 OS << CID->getClassInterface()->getName();
273 OS <<
'(' << *CID <<
')';
285 llvm::raw_svector_ostream OS(Name);
288 Out << OS.str().size() << OS.str();
292 std::unique_ptr<MangleContext> MC;
297 : MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) {
303 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);
304 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
305 if (FD->isDependentContext())
307 if (writeFuncOrVarName(FD, FrontendBufOS))
309 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
310 if (writeFuncOrVarName(VD, FrontendBufOS))
312 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
313 MC->mangleObjCMethodNameWithoutSize(MD, OS);
315 }
else if (
auto *
ID = dyn_cast<ObjCInterfaceDecl>(D)) {
316 writeObjCClassName(
ID, FrontendBufOS);
322 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);
329 llvm::raw_string_ostream OS(Name);
343 return Kind == ObjCMetaclass ?
"_OBJC_METACLASS_" :
"_OBJC_CLASS_";
344 return Kind == ObjCMetaclass ?
"OBJC_METACLASS_$_" :
"OBJC_CLASS_$_";
349 if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
350 ClassName = OID->getObjCRuntimeNameAsString();
351 else if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
352 ClassName = OID->getObjCRuntimeNameAsString();
354 if (ClassName.empty())
357 auto Mangle = [&](
ObjCKind Kind, StringRef ClassName) -> std::string {
359 auto Prefix = getClassSymbolPrefix(Kind, OCD->
getASTContext());
360 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
361 return Mangled.str();
365 Mangle(ObjCClass, ClassName),
366 Mangle(ObjCMetaclass, ClassName),
371 if (
const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
372 return getAllManglings(OCD);
374 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
377 const NamedDecl *ND = cast<NamedDecl>(D);
380 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
382 std::vector<std::string> Manglings;
388 return CC == DefaultCC;
391 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
392 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Base));
394 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
395 if (!CD->getParent()->isAbstract())
396 Manglings.emplace_back(getMangledStructor(CD,
Ctor_Complete));
398 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
399 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
402 }
else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
403 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Base));
404 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
405 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Complete));
407 Manglings.emplace_back(getMangledStructor(DD,
Dtor_Deleting));
409 }
else if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
410 Manglings.emplace_back(
getName(ND));
412 if (
const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
413 for (
const auto &T : *TIV)
414 Manglings.emplace_back(getMangledThunk(MD, T));
421 bool writeFuncOrVarName(
const NamedDecl *D, raw_ostream &OS) {
422 if (MC->shouldMangleDeclName(D)) {
423 if (
const auto *CtorD = dyn_cast<CXXConstructorDecl>(D))
425 else if (
const auto *DtorD = dyn_cast<CXXDestructorDecl>(D))
428 MC->mangleName(D, OS);
444 std::string getMangledStructor(
const NamedDecl *ND,
unsigned StructorType) {
445 std::string FrontendBuf;
446 llvm::raw_string_ostream FOS(FrontendBuf);
448 if (
const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
449 MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
450 else if (
const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
451 MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
453 std::string BackendBuf;
454 llvm::raw_string_ostream BOS(BackendBuf);
456 llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
462 std::string FrontendBuf;
463 llvm::raw_string_ostream FOS(FrontendBuf);
465 MC->mangleThunk(MD, T, FOS);
467 std::string BackendBuf;
468 llvm::raw_string_ostream BOS(BackendBuf);
470 llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
482 return Impl->writeName(D, OS);
486 return Impl->getName(D);
490 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)