clang: lib/AST/Mangle.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

23#include "llvm/ADT/StringExtras.h"

24#include "llvm/IR/DataLayout.h"

25#include "llvm/IR/Mangler.h"

26#include "llvm/Support/ErrorHandling.h"

27#include "llvm/Support/Format.h"

28#include "llvm/Support/raw_ostream.h"

29

30using namespace clang;

31

34 std::optional CategoryName,

35 StringRef MethodName) {

36

37 if (includePrefixByte)

38 OS << "\01";

40 OS << '[';

41 OS << ClassName;

42 if (CategoryName)

43 OS << "(" << *CategoryName << ")";

44 OS << " ";

45 OS << MethodName;

46 OS << ']';

47}

48

49

50

51

53 StringRef Outer,

55 raw_ostream &Out) {

56 unsigned discriminator = Context.getBlockId(BD, true);

57 if (discriminator == 0)

58 Out << "__" << Outer << "_block_invoke";

59 else

60 Out << "__" << Outer << "_block_invoke_" << discriminator+1;

61}

62

63void MangleContext::anchor() { }

64

73

75 if (const FunctionDecl *FD = dyn_cast(ND))

76 return FD->isExternC();

77 if (const VarDecl *VD = dyn_cast(ND))

78 return VD->isExternC();

79 return false;

80}

81

84 const TargetInfo &TI = Context.getTargetInfo();

85 const llvm::Triple &Triple = TI.getTriple();

86

87

88

89 if (Triple.isWasm())

90 if (const FunctionDecl *FD = dyn_cast(ND))

91 if (FD->isMain() && FD->getNumParams() == 2)

93

96

97 if (Context.getLangOpts().CPlusPlus && isExternC(ND) &&

98 TI.getCXXABI() == TargetCXXABI::Microsoft)

100

101 const FunctionDecl *FD = dyn_cast(ND);

102 if (!FD)

105

107

109 switch (CC) {

110 default:

118 }

119}

120

123

126 return true;

127

128

129

131 return true;

132

133

134

137 return true;

138

139

141 return false;

142

143

144

145 if (D->hasAttr())

146 return true;

147

148

150 return true;

151

153}

154

156

157

158

159

160

161

162

163

164

165

166

167

169 llvm::raw_ostream &Out) {

171

173

174 if (auto *Ctor = llvm::dyn_castclang::CXXConstructorDecl(GD.getDecl())) {

175 Out << "C";

176 if (Ctor->getInheritedConstructor().getConstructor())

177 Out << "I";

179 } else if (llvm::isaclang::CXXDestructorDecl(GD.getDecl())) {

181 }

182

184}

185

189

190

191

192 if (const AsmLabelAttr *ALA = D->getAttr()) {

193

194

195

196

197 if (ALA->getLabel().starts_with("llvm.")) {

198 Out << ALA->getLabel();

199 return;

200 }

201

202

203

204

205

206

207 StringRef UserLabelPrefix =

209#ifndef NDEBUG

210 char GlobalPrefix =

211 llvm::DataLayout(getASTContext().getTargetInfo().getDataLayoutString())

212 .getGlobalPrefix();

213 assert((UserLabelPrefix.empty() && !GlobalPrefix) ||

214 (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix));

215#endif

216 if (!UserLabelPrefix.empty())

217 Out << '\01';

218

221 else

222 Out << ALA->getLabel();

223

224 return;

225 }

226

227 if (auto *GD = dyn_cast(D))

229

231

233 Out << "__main_argc_argv";

234 return;

235 }

236

238 const TargetInfo &TI = Context.getTargetInfo();

239 if (CC == CCM_Other || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {

240 if (const ObjCMethodDecl *OMD = dyn_cast(D))

242 else

244 return;

245 }

246

247 Out << '\01';

249 Out << '_';

251 Out << '@';

254 Out << "__regcall4__";

255 else

256 Out << "__regcall3__";

257 }

258

259 if (!MCXX)

261 else if (const ObjCMethodDecl *OMD = dyn_cast(D))

263 else

265

268 const FunctionProtoType *Proto = dyn_cast(FT);

270 Out << '@';

271 Out << '@';

272 if (!Proto) {

273 Out << '0';

274 return;

275 }

276 assert(!Proto->isVariadic());

277 unsigned ArgWords = 0;

278 if (const CXXMethodDecl *MD = dyn_cast(FD))

279 if (MD->isImplicitObjectMemberFunction())

280 ++ArgWords;

282 for (const auto &AT : Proto->param_types()) {

283

284

285

286 if (AT->isIncompleteType())

287 break;

288

290 DefaultPtrWidth;

291 }

292 Out << ((DefaultPtrWidth / 8) * ArgWords);

293}

294

296 raw_ostream &Out) const {

297

298

300 Out << llvm::format("_GUID_%08" PRIx32 "_%04" PRIx32 "_%04" PRIx32 "_",

302 unsigned I = 0;

304 Out << llvm::format("%02" PRIx8, C);

305 if (++I == 2)

306 Out << "_";

307 }

308}

309

312 raw_ostream &Out) {

313 unsigned discriminator = getBlockId(BD, false);

314 if (ID) {

317 else {

318 Out << ID->getIdentifier()->getName();

319 }

320 }

321 if (discriminator == 0)

322 Out << "_block_invoke";

323 else

324 Out << "_block_invoke_" << discriminator+1;

325}

326

329 raw_ostream &ResStream) {

331 llvm::raw_svector_ostream Out(Buffer);

334}

335

338 raw_ostream &ResStream) {

340 llvm::raw_svector_ostream Out(Buffer);

343}

344

346 raw_ostream &Out) {

348

350 llvm::raw_svector_ostream Stream(Buffer);

353 } else {

355 "expected a NamedDecl or BlockDecl");

356 for (; isa_and_nonnull(DC); DC = DC->getParent())

359 "expected a TranslationUnitDecl or a NamedDecl");

360 if (const auto *CD = dyn_cast(DC))

362 else if (const auto *DD = dyn_cast(DC))

364 else if (auto ND = dyn_cast(DC)) {

366 Stream << ND->getIdentifier()->getName();

367 else {

368

369

370

371

372

374 }

375 }

376 }

378}

379

381 raw_ostream &OS,

382 bool includePrefixByte,

383 bool includeCategoryNamespace) const {

385

386

387

388

391

392 if (includeCategoryNamespace) {

394 OS << category->getName();

395 }

396 OS << '_';

397

399 for (unsigned slotIndex = 0,

400 numArgs = selector.getNumArgs(),

401 slotEnd = std::max(numArgs, 1U);

402 slotIndex != slotEnd; ++slotIndex) {

403 if (auto name = selector.getIdentifierInfoForSlot(slotIndex))

404 OS << name->getName();

405

406

407

408

409 if (numArgs)

410 OS << '_';

411 }

412

413 return;

414 }

415

416

417 auto CategoryName = std::optional();

418 StringRef ClassName = "";

419 if (const auto *CID = MD->getCategory()) {

420 if (const auto *CI = CID->getClassInterface()) {

421 ClassName = CI->getName();

422 if (includeCategoryNamespace) {

423 CategoryName = CID->getName();

424 }

425 }

426 } else if (const auto *CD =

428 ClassName = CD->getName();

429 } else {

430 llvm_unreachable("Unexpected ObjC method decl context");

431 }

432 std::string MethodName;

433 llvm::raw_string_ostream MethodNameOS(MethodName);

436 ClassName, CategoryName, MethodName);

437}

438

440 raw_ostream &Out) const {

442 llvm::raw_svector_ostream OS(Name);

443

445 true);

446 Out << OS.str().size() << OS.str();

447}

448

450 std::unique_ptr MC;

451 llvm::DataLayout DL;

452

453public:

455 : MC(Ctx.createMangleContext()),

456 DL(Ctx.getTargetInfo().getDataLayoutString()) {}

457

459

461 llvm::raw_svector_ostream FrontendBufOS(FrontendBuf);

462 if (auto *FD = dyn_cast(D)) {

463 if (FD->isDependentContext())

464 return true;

465 if (writeFuncOrVarName(FD, FrontendBufOS))

466 return true;

467 } else if (auto *VD = dyn_cast(D)) {

468 if (writeFuncOrVarName(VD, FrontendBufOS))

469 return true;

470 } else if (auto *MD = dyn_cast(D)) {

471 MC->mangleObjCMethodName(MD, OS, false,

472 true);

473 return false;

474 } else if (auto *ID = dyn_cast(D)) {

475 writeObjCClassName(ID, FrontendBufOS);

476 } else {

477 return true;

478 }

479

480

481 llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL);

482 return false;

483 }

484

486 std::string Name;

487 {

488 llvm::raw_string_ostream OS(Name);

490 }

491 return Name;

492 }

493

498

501 if (Context.getLangOpts().ObjCRuntime.isGNUFamily())

502 return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_";

503 return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";

504 }

505

507 StringRef ClassName;

508 if (const auto *OID = dyn_cast(OCD))

509 ClassName = OID->getObjCRuntimeNameAsString();

510 else if (const auto *OID = dyn_cast(OCD))

511 ClassName = OID->getObjCRuntimeNameAsString();

512

513 if (ClassName.empty())

514 return {};

515

516 auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string {

519 llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);

520 return std::string(Mangled);

521 };

522

523 return {

526 };

527 }

528

530 if (const auto *OCD = dyn_cast(D))

532

534 return {};

535

537

540

541 std::vectorstd::string Manglings;

542

544 auto DefaultCC = C.getDefaultCallingConvention(false,

545 true);

546 auto CC = MD->getType()->castAs<FunctionProtoType>()->getCallConv();

547 return CC == DefaultCC;

548 };

549

550 if (const auto *CD = dyn_cast_or_null(ND)) {

551 Manglings.emplace_back(getMangledStructor(CD, Ctor_Base));

552

554 if (!CD->getParent()->isAbstract())

555 Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete));

556

558 if (CD->hasAttr() && CD->isDefaultConstructor())

561 } else if (const auto *DD = dyn_cast_or_null(ND)) {

562 Manglings.emplace_back(getMangledStructor(DD, Dtor_Base));

564 Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete));

565 if (DD->isVirtual())

566 Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting));

567 }

568 } else if (const auto *MD = dyn_cast_or_null(ND)) {

569 Manglings.emplace_back(getName(ND));

570 if (MD->isVirtual()) {

572 for (const auto &T : *TIV) {

573 std::string ThunkName;

574 std::string ContextualizedName =

575 getMangledThunk(MD, T, false);

577 ThunkName = getMangledThunk(MD, T, true);

578 else

579 ThunkName = ContextualizedName;

580 Manglings.emplace_back(ThunkName);

581 }

582 }

583 }

584 }

585

586 return Manglings;

587 }

588

589private:

590 bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) {

591 if (MC->shouldMangleDeclName(D)) {

593 if (const auto *CtorD = dyn_cast(D))

595 else if (const auto *DtorD = dyn_cast(D))

597 else if (const FunctionDecl *FD = dyn_cast(D)) {

599 } else

601 MC->mangleName(GD, OS);

602 return false;

603 } else {

605 if (!II)

606 return true;

608 return false;

609 }

610 }

611

612 void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {

615 }

616

617 std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {

618 std::string FrontendBuf;

619 llvm::raw_string_ostream FOS(FrontendBuf);

620

621 GlobalDecl GD;

622 if (const auto *CD = dyn_cast_or_null(ND))

623 GD = GlobalDecl(CD, static_cast<CXXCtorType>(StructorType));

624 else if (const auto *DD = dyn_cast_or_null(ND))

625 GD = GlobalDecl(DD, static_cast<CXXDtorType>(StructorType));

626 MC->mangleName(GD, FOS);

627

628 std::string BackendBuf;

629 llvm::raw_string_ostream BOS(BackendBuf);

630

631 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);

632

633 return BackendBuf;

634 }

635

636 std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T,

637 bool ElideOverrideInfo) {

638 std::string FrontendBuf;

639 llvm::raw_string_ostream FOS(FrontendBuf);

640

641 MC->mangleThunk(MD, T, ElideOverrideInfo, FOS);

642

643 std::string BackendBuf;

644 llvm::raw_string_ostream BOS(BackendBuf);

645

646 llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);

647

648 return BackendBuf;

649 }

650};

651

654

656

658 return Impl->writeName(D, OS);

659}

660

662 return Impl->getName(D);

663}

664

666 return Impl->getAllManglings(D);

667}

Enums/classes describing ABI related information about constructors, destructors and thunks.

Defines the clang::ASTContext interface.

static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

CCMangling

Definition Mangle.cpp:65

@ CCM_Fast

Definition Mangle.cpp:67

@ CCM_Vector

Definition Mangle.cpp:69

@ CCM_Std

Definition Mangle.cpp:70

@ CCM_WasmMainArgcArgv

Definition Mangle.cpp:71

@ CCM_RegCall

Definition Mangle.cpp:68

@ CCM_Other

Definition Mangle.cpp:66

static llvm::StringRef g_lldb_func_call_label_prefix

Definition Mangle.cpp:155

static void emitLLDBAsmLabel(llvm::StringRef label, GlobalDecl GD, llvm::raw_ostream &Out)

Given an LLDB function call label, this function prints the label into Out, together with the structo...

Definition Mangle.cpp:168

static void mangleFunctionBlock(MangleContext &Context, StringRef Outer, const BlockDecl *BD, raw_ostream &Out)

Definition Mangle.cpp:52

static bool isExternC(const NamedDecl *ND)

Definition Mangle.cpp:74

static CCMangling getCallingConvMangling(const ASTContext &Context, const NamedDecl *ND)

Definition Mangle.cpp:82

Definition Mangle.cpp:449

std::string getName(const Decl *D)

Definition Mangle.cpp:485

ObjCKind

Definition Mangle.cpp:494

@ ObjCClass

Definition Mangle.cpp:495

@ ObjCMetaclass

Definition Mangle.cpp:496

std::vector< std::string > getAllManglings(const Decl *D)

Definition Mangle.cpp:529

static StringRef getClassSymbolPrefix(ObjCKind Kind, const ASTContext &Context)

Definition Mangle.cpp:499

bool writeName(const Decl *D, raw_ostream &OS)

Definition Mangle.cpp:458

Implementation(ASTContext &Ctx)

Definition Mangle.cpp:454

std::vector< std::string > getAllManglings(const ObjCContainerDecl *OCD)

Definition Mangle.cpp:506

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

MangleContext * createMangleContext(const TargetInfo *T=nullptr)

If T is null pointer, assume the target in ASTContext.

bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl, StringRef MangledName)

VTableContextBase * getVTableContext()

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

const TargetInfo & getTargetInfo() const

std::string getName(const Decl *D)

Definition Mangle.cpp:661

ASTNameGenerator(ASTContext &Ctx)

Definition Mangle.cpp:652

bool writeName(const Decl *D, raw_ostream &OS)

Writes name for D to OS.

Definition Mangle.cpp:657

std::vector< std::string > getAllManglings(const Decl *D)

Definition Mangle.cpp:665

~ASTNameGenerator()

Definition Mangle.cpp:655

Represents a block literal declaration, which is like an unnamed FunctionDecl.

Represents a C++ constructor within a class.

Represents a C++ destructor within a class.

Represents a static or instance method of a struct/union/class.

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

Decl - This represents one declaration (or definition), e.g.

ASTContext & getASTContext() const LLVM_READONLY

DeclContext * getDeclContext()

Module * getOwningModuleForLinkage() const

Get the module that owns this declaration for linkage purposes.

Represents a function declaration or definition.

Represents a prototype with parameter type info, e.g.

FunctionType - C99 6.7.5.3 - Function Declarators.

CallingConv getCallConv() const

GlobalDecl - represents a global declaration.

CXXCtorType getCtorType() const

CXXDtorType getDtorType() const

const Decl * getDecl() const

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

Parts getParts() const

Get the decomposed parts of this declaration.

MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...

void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out)

Definition Mangle.cpp:345

unsigned getBlockId(const BlockDecl *BD, bool Local)

void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, const BlockDecl *BD, raw_ostream &Out)

Definition Mangle.cpp:327

ASTContext & getASTContext() const

void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID, raw_ostream &Out)

Definition Mangle.cpp:310

virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND)

bool shouldMangleDeclName(const NamedDecl *D)

Definition Mangle.cpp:121

virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &) const

Definition Mangle.cpp:295

void mangleName(GlobalDecl GD, raw_ostream &)

Definition Mangle.cpp:186

virtual void mangleCXXName(GlobalDecl GD, raw_ostream &)=0

virtual bool shouldMangleCXXName(const NamedDecl *D)=0

void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, const BlockDecl *BD, raw_ostream &Out)

Definition Mangle.cpp:336

void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS, bool includePrefixByte=true, bool includeCategoryNamespace=true) const

Definition Mangle.cpp:380

void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD, raw_ostream &) const

Definition Mangle.cpp:439

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

bool hasExternalFormalLinkage() const

True if this decl has external linkage.

ObjCContainerDecl - Represents a container for method declarations.

StringRef getObjCRuntimeNameAsString() const

Produce a name to be used for class's metadata.

ObjCMethodDecl - Represents an instance or class method declaration.

Selector getSelector() const

bool isInstanceMethod() const

ObjCCategoryDecl * getCategory()

If this method is declared or implemented in a category, return that category.

bool isClassMethod() const

ObjCInterfaceDecl * getClassInterface()

The basic abstraction for the target Objective-C runtime.

bool isGNUFamily() const

Is this runtime basically of the GNU family of runtimes?

A (possibly-)qualified type.

void print(llvm::raw_ostream &OS) const

Prints the full selector name (e.g. "foo:bar:").

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

bool isItaniumFamily() const

Does this ABI generally fall into the Itanium family of ABIs?

Exposes information about the current target.

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

uint64_t getPointerWidth(LangAS AddrSpace) const

Return the width of pointers on this target, for the specified address space.

const char * getUserLabelPrefix() const

Returns the default value of the USER_LABEL_PREFIX macro, which is the prefix given to user symbols b...

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

bool shouldUseMicrosoftCCforMangling() const

Should the Microsoft mangling scheme be used for C Calling Convention.

const T * castAs() const

Member-template castAs.

virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)

Represents a variable declaration or definition.

Defines the clang::TargetInfo interface.

@ OS

Indicates that the tracking object is a descendant of a referenced-counted OSObject,...

The JSON file list parser is used to communicate input to InstallAPI.

CXXCtorType

C++ constructor types.

@ Ctor_Base

Base object ctor.

@ Ctor_DefaultClosure

Default closure variant of a ctor.

@ Ctor_Complete

Complete object ctor.

bool isa(CodeGen::Address addr)

bool isInstanceMethod(const Decl *D)

const FunctionProtoType * T

CXXDtorType

C++ destructor types.

@ Dtor_Base

Base object dtor.

@ Dtor_Complete

Complete object dtor.

@ Dtor_Deleting

Deleting dtor.

CallingConv

CallingConv - Specifies the calling convention that a function uses.

U cast(CodeGen::Address addr)

void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName)

Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...

Definition Mangle.cpp:32

uint16_t Part2

...-89ab-...

uint32_t Part1

{01234567-...

uint16_t Part3

...-cdef-...

uint8_t Part4And5[8]

...-0123-456789abcdef}