1 //===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Implements generic name mangling support for blocks and Objective-C.
11 //===----------------------------------------------------------------------===//
12 #include "clang/AST/Attr.h"
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclCXX.h"
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/ExprCXX.h"
19 #include "clang/AST/Mangle.h"
20 #include "clang/AST/VTableBuilder.h"
21 #include "clang/Basic/ABI.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "clang/Basic/TargetInfo.h"
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/Format.h"
29 #include "llvm/Support/raw_ostream.h"
31 using namespace clang
;
33 // FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
34 // much to be desired. Come up with a better mangling scheme.
36 static void mangleFunctionBlock(MangleContext
&Context
,
40 unsigned discriminator
= Context
.getBlockId(BD
, true);
41 if (discriminator
== 0)
42 Out
<< "__" << Outer
<< "_block_invoke";
44 Out
<< "__" << Outer
<< "_block_invoke_" << discriminator
+1;
47 void MangleContext::anchor() { }
58 static bool isExternC(const NamedDecl
*ND
) {
59 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(ND
))
60 return FD
->isExternC();
61 if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(ND
))
62 return VD
->isExternC();
66 static CCMangling
getCallingConvMangling(const ASTContext
&Context
,
67 const NamedDecl
*ND
) {
68 const TargetInfo
&TI
= Context
.getTargetInfo();
69 const llvm::Triple
&Triple
= TI
.getTriple();
71 // On wasm, the argc/argv form of "main" is renamed so that the startup code
72 // can call it with the correct function signature.
74 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(ND
))
75 if (FD
->isMain() && FD
->getNumParams() == 2)
76 return CCM_WasmMainArgcArgv
;
78 if (!Triple
.isOSWindows() || !Triple
.isX86())
81 if (Context
.getLangOpts().CPlusPlus
&& !isExternC(ND
) &&
82 TI
.getCXXABI() == TargetCXXABI::Microsoft
)
85 const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(ND
);
88 QualType T
= FD
->getType();
90 const FunctionType
*FT
= T
->castAs
<FunctionType
>();
92 CallingConv CC
= FT
->getCallConv();
100 case CC_X86VectorCall
:
105 bool MangleContext::shouldMangleDeclName(const NamedDecl
*D
) {
106 const ASTContext
&ASTContext
= getASTContext();
108 CCMangling CC
= getCallingConvMangling(ASTContext
, D
);
112 // If the declaration has an owning module for linkage purposes that needs to
113 // be mangled, we must mangle its name.
114 if (!D
->hasExternalFormalLinkage() && D
->getOwningModuleForLinkage())
117 // C functions with internal linkage have to be mangled with option
118 // -funique-internal-linkage-names.
119 if (!getASTContext().getLangOpts().CPlusPlus
&&
120 isUniqueInternalLinkageDecl(D
))
123 // In C, functions with no attributes never need to be mangled. Fastpath them.
124 if (!getASTContext().getLangOpts().CPlusPlus
&& !D
->hasAttrs())
127 // Any decl can be declared with __asm("foo") on it, and this takes precedence
128 // over all other naming in the .o file.
129 if (D
->hasAttr
<AsmLabelAttr
>())
132 // Declarations that don't have identifier names always need to be mangled.
133 if (isa
<MSGuidDecl
>(D
))
136 return shouldMangleCXXName(D
);
139 void MangleContext::mangleName(GlobalDecl GD
, raw_ostream
&Out
) {
140 const ASTContext
&ASTContext
= getASTContext();
141 const NamedDecl
*D
= cast
<NamedDecl
>(GD
.getDecl());
143 // Any decl can be declared with __asm("foo") on it, and this takes precedence
144 // over all other naming in the .o file.
145 if (const AsmLabelAttr
*ALA
= D
->getAttr
<AsmLabelAttr
>()) {
146 // If we have an asm name, then we use it as the mangling.
148 // If the label isn't literal, or if this is an alias for an LLVM intrinsic,
149 // do not add a "\01" prefix.
150 if (!ALA
->getIsLiteralLabel() || ALA
->getLabel().startswith("llvm.")) {
151 Out
<< ALA
->getLabel();
155 // Adding the prefix can cause problems when one file has a "foo" and
156 // another has a "\01foo". That is known to happen on ELF with the
157 // tricks normally used for producing aliases (PR9177). Fortunately the
158 // llvm mangler on ELF is a nop, so we can just avoid adding the \01
160 StringRef UserLabelPrefix
=
161 getASTContext().getTargetInfo().getUserLabelPrefix();
164 llvm::DataLayout(getASTContext().getTargetInfo().getDataLayoutString())
166 assert((UserLabelPrefix
.empty() && !GlobalPrefix
) ||
167 (UserLabelPrefix
.size() == 1 && UserLabelPrefix
[0] == GlobalPrefix
));
169 if (!UserLabelPrefix
.empty())
170 Out
<< '\01'; // LLVM IR Marker for __asm("foo")
172 Out
<< ALA
->getLabel();
176 if (auto *GD
= dyn_cast
<MSGuidDecl
>(D
))
177 return mangleMSGuidDecl(GD
, Out
);
179 CCMangling CC
= getCallingConvMangling(ASTContext
, D
);
181 if (CC
== CCM_WasmMainArgcArgv
) {
182 Out
<< "__main_argc_argv";
186 bool MCXX
= shouldMangleCXXName(D
);
187 const TargetInfo
&TI
= Context
.getTargetInfo();
188 if (CC
== CCM_Other
|| (MCXX
&& TI
.getCXXABI() == TargetCXXABI::Microsoft
)) {
189 if (const ObjCMethodDecl
*OMD
= dyn_cast
<ObjCMethodDecl
>(D
))
190 mangleObjCMethodNameAsSourceName(OMD
, Out
);
192 mangleCXXName(GD
, Out
);
199 else if (CC
== CCM_Fast
)
201 else if (CC
== CCM_RegCall
) {
202 if (getASTContext().getLangOpts().RegCall4
)
203 Out
<< "__regcall4__";
205 Out
<< "__regcall3__";
209 Out
<< D
->getIdentifier()->getName();
210 else if (const ObjCMethodDecl
*OMD
= dyn_cast
<ObjCMethodDecl
>(D
))
211 mangleObjCMethodNameAsSourceName(OMD
, Out
);
213 mangleCXXName(GD
, Out
);
215 const FunctionDecl
*FD
= cast
<FunctionDecl
>(D
);
216 const FunctionType
*FT
= FD
->getType()->castAs
<FunctionType
>();
217 const FunctionProtoType
*Proto
= dyn_cast
<FunctionProtoType
>(FT
);
218 if (CC
== CCM_Vector
)
225 assert(!Proto
->isVariadic());
226 unsigned ArgWords
= 0;
227 if (const CXXMethodDecl
*MD
= dyn_cast
<CXXMethodDecl
>(FD
))
228 if (MD
->isImplicitObjectMemberFunction())
230 uint64_t DefaultPtrWidth
= TI
.getPointerWidth(LangAS::Default
);
231 for (const auto &AT
: Proto
->param_types()) {
232 // If an argument type is incomplete there is no way to get its size to
233 // correctly encode into the mangling scheme.
234 // Follow GCCs behaviour by simply breaking out of the loop.
235 if (AT
->isIncompleteType())
237 // Size should be aligned to pointer size.
238 ArgWords
+= llvm::alignTo(ASTContext
.getTypeSize(AT
), DefaultPtrWidth
) /
241 Out
<< ((DefaultPtrWidth
/ 8) * ArgWords
);
244 void MangleContext::mangleMSGuidDecl(const MSGuidDecl
*GD
, raw_ostream
&Out
) {
245 // For now, follow the MSVC naming convention for GUID objects on all
247 MSGuidDecl::Parts P
= GD
->getParts();
248 Out
<< llvm::format("_GUID_%08" PRIx32
"_%04" PRIx32
"_%04" PRIx32
"_",
249 P
.Part1
, P
.Part2
, P
.Part3
);
251 for (uint8_t C
: P
.Part4And5
) {
252 Out
<< llvm::format("%02" PRIx8
, C
);
258 void MangleContext::mangleGlobalBlock(const BlockDecl
*BD
,
261 unsigned discriminator
= getBlockId(BD
, false);
263 if (shouldMangleDeclName(ID
))
266 Out
<< ID
->getIdentifier()->getName();
269 if (discriminator
== 0)
270 Out
<< "_block_invoke";
272 Out
<< "_block_invoke_" << discriminator
+1;
275 void MangleContext::mangleCtorBlock(const CXXConstructorDecl
*CD
,
276 CXXCtorType CT
, const BlockDecl
*BD
,
277 raw_ostream
&ResStream
) {
278 SmallString
<64> Buffer
;
279 llvm::raw_svector_ostream
Out(Buffer
);
280 mangleName(GlobalDecl(CD
, CT
), Out
);
281 mangleFunctionBlock(*this, Buffer
, BD
, ResStream
);
284 void MangleContext::mangleDtorBlock(const CXXDestructorDecl
*DD
,
285 CXXDtorType DT
, const BlockDecl
*BD
,
286 raw_ostream
&ResStream
) {
287 SmallString
<64> Buffer
;
288 llvm::raw_svector_ostream
Out(Buffer
);
289 mangleName(GlobalDecl(DD
, DT
), Out
);
290 mangleFunctionBlock(*this, Buffer
, BD
, ResStream
);
293 void MangleContext::mangleBlock(const DeclContext
*DC
, const BlockDecl
*BD
,
295 assert(!isa
<CXXConstructorDecl
>(DC
) && !isa
<CXXDestructorDecl
>(DC
));
297 SmallString
<64> Buffer
;
298 llvm::raw_svector_ostream
Stream(Buffer
);
299 if (const ObjCMethodDecl
*Method
= dyn_cast
<ObjCMethodDecl
>(DC
)) {
300 mangleObjCMethodNameAsSourceName(Method
, Stream
);
302 assert((isa
<NamedDecl
>(DC
) || isa
<BlockDecl
>(DC
)) &&
303 "expected a NamedDecl or BlockDecl");
304 if (isa
<BlockDecl
>(DC
))
305 for (; DC
&& isa
<BlockDecl
>(DC
); DC
= DC
->getParent())
306 (void) getBlockId(cast
<BlockDecl
>(DC
), true);
307 assert((isa
<TranslationUnitDecl
>(DC
) || isa
<NamedDecl
>(DC
)) &&
308 "expected a TranslationUnitDecl or a NamedDecl");
309 if (const auto *CD
= dyn_cast
<CXXConstructorDecl
>(DC
))
310 mangleCtorBlock(CD
, /*CT*/ Ctor_Complete
, BD
, Out
);
311 else if (const auto *DD
= dyn_cast
<CXXDestructorDecl
>(DC
))
312 mangleDtorBlock(DD
, /*DT*/ Dtor_Complete
, BD
, Out
);
313 else if (auto ND
= dyn_cast
<NamedDecl
>(DC
)) {
314 if (!shouldMangleDeclName(ND
) && ND
->getIdentifier())
315 Stream
<< ND
->getIdentifier()->getName();
317 // FIXME: We were doing a mangleUnqualifiedName() before, but that's
318 // a private member of a class that will soon itself be private to the
319 // Itanium C++ ABI object. What should we do now? Right now, I'm just
320 // calling the mangleName() method on the MangleContext; is there a
322 mangleName(ND
, Stream
);
326 mangleFunctionBlock(*this, Buffer
, BD
, Out
);
329 void MangleContext::mangleObjCMethodName(const ObjCMethodDecl
*MD
,
331 bool includePrefixByte
,
332 bool includeCategoryNamespace
) {
333 if (getASTContext().getLangOpts().ObjCRuntime
.isGNUFamily()) {
334 // This is the mangling we've always used on the GNU runtimes, but it
335 // has obvious collisions in the face of underscores within class
336 // names, category names, and selectors; maybe we should improve it.
338 OS
<< (MD
->isClassMethod() ? "_c_" : "_i_")
339 << MD
->getClassInterface()->getName() << '_';
341 if (includeCategoryNamespace
) {
342 if (auto category
= MD
->getCategory())
343 OS
<< category
->getName();
347 auto selector
= MD
->getSelector();
348 for (unsigned slotIndex
= 0,
349 numArgs
= selector
.getNumArgs(),
350 slotEnd
= std::max(numArgs
, 1U);
351 slotIndex
!= slotEnd
; ++slotIndex
) {
352 if (auto name
= selector
.getIdentifierInfoForSlot(slotIndex
))
353 OS
<< name
->getName();
355 // Replace all the positions that would've been ':' with '_'.
356 // That's after each slot except that a unary selector doesn't
365 // \01+[ContainerName(CategoryName) SelectorName]
366 if (includePrefixByte
) {
369 OS
<< (MD
->isInstanceMethod() ? '-' : '+') << '[';
370 if (const auto *CID
= MD
->getCategory()) {
371 OS
<< CID
->getClassInterface()->getName();
372 if (includeCategoryNamespace
) {
373 OS
<< '(' << *CID
<< ')';
375 } else if (const auto *CD
=
376 dyn_cast
<ObjCContainerDecl
>(MD
->getDeclContext())) {
379 llvm_unreachable("Unexpected ObjC method decl context");
382 MD
->getSelector().print(OS
);
386 void MangleContext::mangleObjCMethodNameAsSourceName(const ObjCMethodDecl
*MD
,
388 SmallString
<64> Name
;
389 llvm::raw_svector_ostream
OS(Name
);
391 mangleObjCMethodName(MD
, OS
, /*includePrefixByte=*/false,
392 /*includeCategoryNamespace=*/true);
393 Out
<< OS
.str().size() << OS
.str();
396 class ASTNameGenerator::Implementation
{
397 std::unique_ptr
<MangleContext
> MC
;
401 explicit Implementation(ASTContext
&Ctx
)
402 : MC(Ctx
.createMangleContext()),
403 DL(Ctx
.getTargetInfo().getDataLayoutString()) {}
405 bool writeName(const Decl
*D
, raw_ostream
&OS
) {
406 // First apply frontend mangling.
407 SmallString
<128> FrontendBuf
;
408 llvm::raw_svector_ostream
FrontendBufOS(FrontendBuf
);
409 if (auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
410 if (FD
->isDependentContext())
412 if (writeFuncOrVarName(FD
, FrontendBufOS
))
414 } else if (auto *VD
= dyn_cast
<VarDecl
>(D
)) {
415 if (writeFuncOrVarName(VD
, FrontendBufOS
))
417 } else if (auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
418 MC
->mangleObjCMethodName(MD
, OS
, /*includePrefixByte=*/false,
419 /*includeCategoryNamespace=*/true);
421 } else if (auto *ID
= dyn_cast
<ObjCInterfaceDecl
>(D
)) {
422 writeObjCClassName(ID
, FrontendBufOS
);
427 // Now apply backend mangling.
428 llvm::Mangler::getNameWithPrefix(OS
, FrontendBufOS
.str(), DL
);
432 std::string
getName(const Decl
*D
) {
435 llvm::raw_string_ostream
OS(Name
);
446 static StringRef
getClassSymbolPrefix(ObjCKind Kind
,
447 const ASTContext
&Context
) {
448 if (Context
.getLangOpts().ObjCRuntime
.isGNUFamily())
449 return Kind
== ObjCMetaclass
? "_OBJC_METACLASS_" : "_OBJC_CLASS_";
450 return Kind
== ObjCMetaclass
? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";
453 std::vector
<std::string
> getAllManglings(const ObjCContainerDecl
*OCD
) {
455 if (const auto *OID
= dyn_cast
<ObjCInterfaceDecl
>(OCD
))
456 ClassName
= OID
->getObjCRuntimeNameAsString();
457 else if (const auto *OID
= dyn_cast
<ObjCImplementationDecl
>(OCD
))
458 ClassName
= OID
->getObjCRuntimeNameAsString();
460 if (ClassName
.empty())
463 auto Mangle
= [&](ObjCKind Kind
, StringRef ClassName
) -> std::string
{
464 SmallString
<40> Mangled
;
465 auto Prefix
= getClassSymbolPrefix(Kind
, OCD
->getASTContext());
466 llvm::Mangler::getNameWithPrefix(Mangled
, Prefix
+ ClassName
, DL
);
467 return std::string(Mangled
.str());
471 Mangle(ObjCClass
, ClassName
),
472 Mangle(ObjCMetaclass
, ClassName
),
476 std::vector
<std::string
> getAllManglings(const Decl
*D
) {
477 if (const auto *OCD
= dyn_cast
<ObjCContainerDecl
>(D
))
478 return getAllManglings(OCD
);
480 if (!(isa
<CXXRecordDecl
>(D
) || isa
<CXXMethodDecl
>(D
)))
483 const NamedDecl
*ND
= cast
<NamedDecl
>(D
);
485 ASTContext
&Ctx
= ND
->getASTContext();
486 std::unique_ptr
<MangleContext
> M(Ctx
.createMangleContext());
488 std::vector
<std::string
> Manglings
;
490 auto hasDefaultCXXMethodCC
= [](ASTContext
&C
, const CXXMethodDecl
*MD
) {
491 auto DefaultCC
= C
.getDefaultCallingConvention(/*IsVariadic=*/false,
492 /*IsCXXMethod=*/true);
493 auto CC
= MD
->getType()->castAs
<FunctionProtoType
>()->getCallConv();
494 return CC
== DefaultCC
;
497 if (const auto *CD
= dyn_cast_or_null
<CXXConstructorDecl
>(ND
)) {
498 Manglings
.emplace_back(getMangledStructor(CD
, Ctor_Base
));
500 if (Ctx
.getTargetInfo().getCXXABI().isItaniumFamily())
501 if (!CD
->getParent()->isAbstract())
502 Manglings
.emplace_back(getMangledStructor(CD
, Ctor_Complete
));
504 if (Ctx
.getTargetInfo().getCXXABI().isMicrosoft())
505 if (CD
->hasAttr
<DLLExportAttr
>() && CD
->isDefaultConstructor())
506 if (!(hasDefaultCXXMethodCC(Ctx
, CD
) && CD
->getNumParams() == 0))
507 Manglings
.emplace_back(getMangledStructor(CD
, Ctor_DefaultClosure
));
508 } else if (const auto *DD
= dyn_cast_or_null
<CXXDestructorDecl
>(ND
)) {
509 Manglings
.emplace_back(getMangledStructor(DD
, Dtor_Base
));
510 if (Ctx
.getTargetInfo().getCXXABI().isItaniumFamily()) {
511 Manglings
.emplace_back(getMangledStructor(DD
, Dtor_Complete
));
513 Manglings
.emplace_back(getMangledStructor(DD
, Dtor_Deleting
));
515 } else if (const auto *MD
= dyn_cast_or_null
<CXXMethodDecl
>(ND
)) {
516 Manglings
.emplace_back(getName(ND
));
518 if (const auto *TIV
= Ctx
.getVTableContext()->getThunkInfo(MD
))
519 for (const auto &T
: *TIV
)
520 Manglings
.emplace_back(getMangledThunk(MD
, T
));
527 bool writeFuncOrVarName(const NamedDecl
*D
, raw_ostream
&OS
) {
528 if (MC
->shouldMangleDeclName(D
)) {
530 if (const auto *CtorD
= dyn_cast
<CXXConstructorDecl
>(D
))
531 GD
= GlobalDecl(CtorD
, Ctor_Complete
);
532 else if (const auto *DtorD
= dyn_cast
<CXXDestructorDecl
>(D
))
533 GD
= GlobalDecl(DtorD
, Dtor_Complete
);
534 else if (D
->hasAttr
<CUDAGlobalAttr
>())
535 GD
= GlobalDecl(cast
<FunctionDecl
>(D
));
538 MC
->mangleName(GD
, OS
);
541 IdentifierInfo
*II
= D
->getIdentifier();
549 void writeObjCClassName(const ObjCInterfaceDecl
*D
, raw_ostream
&OS
) {
550 OS
<< getClassSymbolPrefix(ObjCClass
, D
->getASTContext());
551 OS
<< D
->getObjCRuntimeNameAsString();
554 std::string
getMangledStructor(const NamedDecl
*ND
, unsigned StructorType
) {
555 std::string FrontendBuf
;
556 llvm::raw_string_ostream
FOS(FrontendBuf
);
559 if (const auto *CD
= dyn_cast_or_null
<CXXConstructorDecl
>(ND
))
560 GD
= GlobalDecl(CD
, static_cast<CXXCtorType
>(StructorType
));
561 else if (const auto *DD
= dyn_cast_or_null
<CXXDestructorDecl
>(ND
))
562 GD
= GlobalDecl(DD
, static_cast<CXXDtorType
>(StructorType
));
563 MC
->mangleName(GD
, FOS
);
565 std::string BackendBuf
;
566 llvm::raw_string_ostream
BOS(BackendBuf
);
568 llvm::Mangler::getNameWithPrefix(BOS
, FOS
.str(), DL
);
573 std::string
getMangledThunk(const CXXMethodDecl
*MD
, const ThunkInfo
&T
) {
574 std::string FrontendBuf
;
575 llvm::raw_string_ostream
FOS(FrontendBuf
);
577 MC
->mangleThunk(MD
, T
, FOS
);
579 std::string BackendBuf
;
580 llvm::raw_string_ostream
BOS(BackendBuf
);
582 llvm::Mangler::getNameWithPrefix(BOS
, FOS
.str(), DL
);
588 ASTNameGenerator::ASTNameGenerator(ASTContext
&Ctx
)
589 : Impl(std::make_unique
<Implementation
>(Ctx
)) {}
591 ASTNameGenerator::~ASTNameGenerator() {}
593 bool ASTNameGenerator::writeName(const Decl
*D
, raw_ostream
&OS
) {
594 return Impl
->writeName(D
, OS
);
597 std::string
ASTNameGenerator::getName(const Decl
*D
) {
598 return Impl
->getName(D
);
601 std::vector
<std::string
> ASTNameGenerator::getAllManglings(const Decl
*D
) {
602 return Impl
->getAllManglings(D
);