clang: lib/CodeGen/CGVTables.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

22#include "llvm/IR/IntrinsicInst.h"

23#include "llvm/Transforms/Utils/Cloning.h"

24#include

25#include

26#include

27

28using namespace clang;

29using namespace CodeGen;

30

32 : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}

33

36 return GetOrCreateLLVMFunction(Name, FnTy, GD, true,

37 true, true);

38}

39

41 llvm::Function *ThunkFn, bool ForVTable,

46

47

49

51 ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);

52 ThunkFn->setDSOLocal(true);

53 }

54

55 if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())

56 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));

57}

58

59#ifndef NDEBUG

63 (typeL == typeR ||

64 (isa(typeL) && isa(typeR)) ||

65 (isa(typeL) && isa(typeR))));

66}

67#endif

68

72

74

75 llvm::BasicBlock *AdjustNull = nullptr;

76 llvm::BasicBlock *AdjustNotNull = nullptr;

77 llvm::BasicBlock *AdjustEnd = nullptr;

78

80

81 if (NullCheckValue) {

85

87 CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);

89 }

90

94 CGF,

96 ClassAlign),

97 ClassDecl, Thunk.Return);

98

99 if (NullCheckValue) {

100 CGF.Builder.CreateBr(AdjustEnd);

102 CGF.Builder.CreateBr(AdjustEnd);

104

105 llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2);

106 PHI->addIncoming(ReturnValue, AdjustNotNull);

107 PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),

108 AdjustNull);

109 ReturnValue = PHI;

110 }

111

113}

114

115

116

117

118

119

121 llvm::ValueToValueMapTy &VMap) {

122

123 auto *DIS = Fn->getSubprogram();

124 if (!DIS)

125 return;

126 auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());

127 VMap.MD()[DIS].reset(NewDIS);

128

129

130

131 for (auto &BB : *Fn) {

132 for (auto &I : BB) {

133 for (llvm::DbgVariableRecord &DVR :

134 llvm::filterDbgVars(I.getDbgRecordRange())) {

135 auto *DILocal = DVR.getVariable();

136 if (!DILocal->isResolved())

137 DILocal->resolve();

138 }

139 if (auto *DII = dyn_castllvm::DbgVariableIntrinsic(&I)) {

140 auto *DILocal = DII->getVariable();

141 if (!DILocal->isResolved())

142 DILocal->resolve();

143 }

144 }

145 }

146}

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164llvm::Function *

171

172

176 llvm::Function *BaseFn = castllvm::Function(Callee);

177

178

179

180

182 CGM.ErrorUnsupported(MD, "return-adjusting thunk with variadic arguments");

183 return Fn;

184 }

185 assert(!BaseFn->isDeclaration() && "cannot clone undefined variadic method");

186

187

188 llvm::ValueToValueMapTy VMap;

189

190

191

193 llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);

194 Fn->replaceAllUsesWith(NewFn);

195 NewFn->takeName(Fn);

196 Fn->eraseFromParent();

197 Fn = NewFn;

198

199

201

202

203 llvm::Function::arg_iterator AI = Fn->arg_begin();

205 ++AI;

206

207

208

212 llvm::BasicBlock *EntryBB = &Fn->front();

213 llvm::BasicBlock::iterator ThisStore =

214 llvm::find_if(*EntryBB, [&](llvm::Instruction &I) {

215 return isallvm::StoreInst(I) && I.getOperand(0) == &*AI;

216 });

217 assert(ThisStore != EntryBB->end() &&

218 "Store of this should be in entry block?");

219

220 Builder.SetInsertPoint(&*ThisStore);

221

224 *this, ThisPtr, ThisValueClass, Thunk);

225 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,

226 ThisStore->getOperand(0)->getType());

227 ThisStore->setOperand(0, AdjustedThisPtr);

228

230

231 for (llvm::BasicBlock &BB : *Fn) {

232 llvm::Instruction *T = BB.getTerminator();

233 if (isallvm::ReturnInst(T)) {

235 T->eraseFromParent();

236 Builder.SetInsertPoint(&BB);

239 break;

240 }

241 }

242 }

243

244 return Fn;

245}

246

249 bool IsUnprototyped) {

250 assert(CurGD.getDecl() && "CurGD was already set!");

253

254

258 if (IsUnprototyped)

261 ResultType = ThisType;

264 else

267

268

270

271

272 if (!IsUnprototyped) {

274

275 if (isa(MD))

277 FunctionArgs);

278 }

279

280

284

286

287

289 CXXThisValue = CXXABIThisValue;

292}

293

295

296

299

301}

302

305 bool IsUnprototyped) {

306 assert(isa(CurGD.getDecl()) &&

307 "Please use a new CGF for this thunk");

309

310

313 if (Thunk)

315

316 llvm::Value *AdjustedThisPtr =

318 ThisValueClass, *Thunk)

320

321

322

323

326 if (IsUnprototyped)

328 MD, "return-adjusting thunk with incomplete parameter type");

330 llvm_unreachable("shouldn't try to emit musttail return-adjusting "

331 "thunks for variadic functions");

332 else

334 MD, "non-trivial argument copy for return-adjusting thunk");

335 }

337 return;

338 }

339

340

343 CallArgs.add(RValue::get(AdjustedThisPtr), ThisType);

344

345 if (isa(MD))

347

348#ifndef NDEBUG

349 unsigned PrefixArgs = CallArgs.size() - 1;

350#endif

351

354

356

357#ifndef NDEBUG

363 assert(isa(MD) ||

364 similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),

368 assert(similar(CallFnInfo.arg_begin()[i].info,

369 CallFnInfo.arg_begin()[i].type,

372#endif

373

374

376 ? ThisType

385 false, true);

386

387

388 llvm::CallBase *CallOrInvoke;

390 CallArgs, &CallOrInvoke);

391

392

395 else if (llvm::CallInst* Call = dyn_castllvm::CallInst(CallOrInvoke))

396 Call->setTailCallKind(llvm::CallInst::TCK_Tail);

397

398

401

402

404

406}

407

409 llvm::Value *AdjustedThisPtr,

410 llvm::FunctionCallee Callee) {

411

412

413

414

416

417

422 llvm::Type *ThisType = Args[ThisArgNo]->getType();

423 if (ThisType != AdjustedThisPtr->getType())

424 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);

425 Args[ThisArgNo] = AdjustedThisPtr;

426 } else {

427 assert(ThisAI.isInAlloca() && "this is passed directly or inalloca");

430 if (ThisType != AdjustedThisPtr->getType())

431 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);

433 }

434

435

436

437 llvm::CallInst *Call = Builder.CreateCall(Callee, Args);

438 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);

439

440

442 llvm::AttributeList Attrs;

444 Attrs, CallingConv, true,

445 false);

446 Call->setAttributes(Attrs);

447 Call->setCallingConv(static_castllvm::CallingConv::ID\(CallingConv));

448

449 if (Call->getType()->isVoidTy())

451 else

453

454

455

457

459}

460

464 bool IsUnprototyped) {

465 StartThunk(Fn, GD, FnInfo, IsUnprototyped);

466

468

469

470

471 llvm::Type *Ty;

472 if (IsUnprototyped)

474 else

476

478

479

481 &Thunk, IsUnprototyped);

482}

483

485 bool IsUnprototyped, bool ForVTable) {

486

487

489 return true;

490

491

492

493

494

495 if (ForVTable)

496 return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped;

497

498

499 return true;

500}

501

502llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,

504 bool ForVTable) {

506

507

508

509

512 llvm::raw_svector_ostream Out(Name);

513

514 if (const CXXDestructorDecl *DD = dyn_cast(MD)) {

516 false, Out);

517 } else

518 MCtx.mangleThunk(MD, TI, false, Out);

519

521 Name = "";

522 if (const CXXDestructorDecl *DD = dyn_cast(MD))

524 true, Out);

525 else

526 MCtx.mangleThunk(MD, TI, true, Out);

527 }

528

530 llvm::Constant *Thunk = CGM.GetAddrOfThunk(Name, ThunkVTableTy, GD);

531

532

536 return Thunk;

537

538

539

544

545

546

547 llvm::Function *ThunkFn = castllvm::Function(Thunk->stripPointerCasts());

548 if (ThunkFn->getFunctionType() != ThunkFnTy) {

549 llvm::GlobalValue *OldThunkFn = ThunkFn;

550

551 assert(OldThunkFn->isDeclaration() && "Shouldn't replace non-declaration");

552

553

554 OldThunkFn->setName(StringRef());

555 ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,

558

559 if (!OldThunkFn->use_empty()) {

560 OldThunkFn->replaceAllUsesWith(ThunkFn);

561 }

562

563

564 OldThunkFn->eraseFromParent();

565 }

566

568 bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;

569

570 if (!ThunkFn->isDeclaration()) {

571 if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {

572

573 return ThunkFn;

574 }

575

577 return ThunkFn;

578 }

579

580

581

582

583

584 if (IsUnprototyped)

585 ThunkFn->addFnAttr("thunk");

586

588

589

590

591

592

593

594 bool ShouldCloneVarArgs = false;

595 if (!IsUnprototyped && ThunkFn->isVarArg()) {

596 ShouldCloneVarArgs = true;

598 switch (CGM.getTriple().getArch()) {

599 case llvm::Triple::x86_64:

600 case llvm::Triple::x86:

601 case llvm::Triple::aarch64:

602 ShouldCloneVarArgs = false;

603 break;

604 default:

605 break;

606 }

607 }

608 }

609

610 if (ShouldCloneVarArgs) {

611 if (UseAvailableExternallyLinkage)

612 return ThunkFn;

613 ThunkFn =

615 } else {

616

618 }

619

621 return ThunkFn;

622}

623

627

628

630 return;

631

634

635 if (!ThunkInfoVector)

636 return;

637

638 for (const ThunkInfo& Thunk : *ThunkInfoVector)

639 maybeEmitThunk(GD, Thunk, false);

640}

641

643 llvm::Constant *component,

644 unsigned vtableAddressPoint,

645 bool vtableHasLocalLinkage,

646 bool isCompleteDtor) const {

647

648 if (component->isNullValue())

649 return builder.add(llvm::ConstantInt::get(CGM.Int32Ty, 0));

650

651 auto *globalVal =

652 castllvm::GlobalValue(component->stripPointerCastsAndAliases());

653 llvm::Module &module = CGM.getModule();

654

655

656

657

658

659

660

661

662

663

664

665

666 auto stubLinkage = vtableHasLocalLinkage

667 ? llvm::GlobalValue::InternalLinkage

668 : llvm::GlobalValue::LinkOnceODRLinkage;

669

670 llvm::Constant *target;

671 if (auto *func = dyn_castllvm::Function(globalVal)) {

672 target = llvm::DSOLocalEquivalent::get(func);

673 } else {

675 rttiProxyName.append(".rtti_proxy");

676

677

678

679

680

681 llvm::GlobalVariable *proxy = module.getNamedGlobal(rttiProxyName);

682 if (!proxy) {

683 proxy = new llvm::GlobalVariable(module, globalVal->getType(),

684 true, stubLinkage,

685 globalVal, rttiProxyName);

686 proxy->setDSOLocal(true);

687 proxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

688 if (!proxy->hasLocalLinkage()) {

689 proxy->setVisibility(llvm::GlobalValue::HiddenVisibility);

690 proxy->setComdat(module.getOrInsertComdat(rttiProxyName));

691 }

692

693

694

695

696

698 }

699 target = proxy;

700 }

701

702 builder.addRelativeOffsetToPosition(CGM.Int32Ty, target,

703 vtableAddressPoint);

704}

705

709}

710

711bool CodeGenVTables::useRelativeLayout() const {

713}

714

719}

720

721llvm::Type *CodeGenVTables::getVTableComponentType() const {

723}

724

728 builder.add(llvm::ConstantExpr::getIntToPtr(

731}

732

736 builder.add(llvm::ConstantInt::get(CGM.Int32Ty, offset.getQuantity()));

737}

738

741 unsigned componentIndex,

742 llvm::Constant *rtti,

743 unsigned &nextVTableThunkIndex,

744 unsigned vtableAddressPoint,

745 bool vtableHasLocalLinkage) {

747

748 auto addOffsetConstant =

750

751 switch (component.getKind()) {

753 return addOffsetConstant(CGM, builder, component.getVCallOffset());

754

756 return addOffsetConstant(CGM, builder, component.getVBaseOffset());

757

759 return addOffsetConstant(CGM, builder, component.getOffsetToTop());

760

762 if (useRelativeLayout())

763 return addRelativeComponent(builder, rtti, vtableAddressPoint,

764 vtableHasLocalLinkage,

765 false);

766 else

767 return builder.add(rtti);

768

772 GlobalDecl GD = component.getGlobalDecl();

773

775

776

777

779

780

781 bool CanEmitMethod =

783 ? MD->hasAttr()

784 : (MD->hasAttr() || !MD->hasAttr());

785 if (!CanEmitMethod)

786 return builder.add(

788

789 }

790

791 auto getSpecialVirtualFn = [&](StringRef name) -> llvm::Constant * {

792

793

794

795

796

797

798

799 if (useRelativeLayout())

801

802

803

807 llvm::FunctionType *fnTy =

808 llvm::FunctionType::get(CGM.VoidTy, false);

809 llvm::Constant *fn = castllvm::Constant(

811 if (auto f = dyn_castllvm::Function(fn))

812 f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

813 return fn;

814 };

815

816 llvm::Constant *fnPtr;

817

818

819 if (cast(GD.getDecl())->isPureVirtual()) {

820 if (!PureVirtualFn)

821 PureVirtualFn =

823 fnPtr = PureVirtualFn;

824

825

826 } else if (cast(GD.getDecl())->isDeleted()) {

827 if (!DeletedVirtualFn)

828 DeletedVirtualFn =

830 fnPtr = DeletedVirtualFn;

831

832

833 } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&

834 layout.vtable_thunks()[nextVTableThunkIndex].first ==

835 componentIndex) {

836 auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;

837

838 nextVTableThunkIndex++;

839 fnPtr = maybeEmitThunk(GD, thunkInfo, true);

841 assert(thunkInfo.Method && "Method not set");

843 }

844

845

846 } else {

851 }

852

853 if (useRelativeLayout()) {

854 return addRelativeComponent(

855 builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,

857 } else {

858

859

860

861

862 unsigned FnAS = fnPtr->getType()->getPointerAddressSpace();

863 unsigned GVAS = CGM.GlobalsInt8PtrTy->getPointerAddressSpace();

864

865 if (FnAS != GVAS)

866 fnPtr =

867 llvm::ConstantExpr::getAddrSpaceCast(fnPtr, CGM.GlobalsInt8PtrTy);

868 if (const auto &Schema =

870 return builder.addSignedPointer(fnPtr, Schema, GD, QualType());

871 return builder.add(fnPtr);

872 }

873 }

874

876 if (useRelativeLayout())

877 return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int32Ty));

878 else

880 }

881

882 llvm_unreachable("Unexpected vtable component kind");

883}

884

887 llvm::Type *componentType = getVTableComponentType();

888 for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i)

889 tys.push_back(llvm::ArrayType::get(componentType, layout.getVTableSize(i)));

890

891 return llvm::StructType::get(CGM.getLLVMContext(), tys);

892}

893

896 llvm::Constant *rtti,

897 bool vtableHasLocalLinkage) {

898 llvm::Type *componentType = getVTableComponentType();

899

901 unsigned nextVTableThunkIndex = 0;

902 for (unsigned vtableIndex = 0, endIndex = layout.getNumVTables();

903 vtableIndex != endIndex; ++vtableIndex) {

904 auto vtableElem = builder.beginArray(componentType);

905

906 size_t vtableStart = layout.getVTableOffset(vtableIndex);

907 size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex);

908 for (size_t componentIndex = vtableStart; componentIndex < vtableEnd;

909 ++componentIndex) {

910 addVTableComponent(vtableElem, layout, componentIndex, rtti,

911 nextVTableThunkIndex, addressPoints[vtableIndex],

912 vtableHasLocalLinkage);

913 }

914 vtableElem.finishAndAddTo(builder);

915 }

916}

917

920 llvm::GlobalVariable::LinkageTypes Linkage,

921 VTableAddressPointsMapTy &AddressPoints) {

923 DI->completeClassData(Base.getBase());

924

925 std::unique_ptr VTLayout(

927 Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));

928

929

930 AddressPoints = VTLayout->getAddressPoints();

931

932

934 llvm::raw_svector_ostream Out(OutName);

936 .mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(),

937 Base.getBase(), Out);

939

941 bool VTableAliasExists =

942 UsingRelativeLayout && CGM.getModule().getNamedAlias(Name);

943 if (VTableAliasExists) {

944

945 Name.append(".local");

946 }

947

949

950

951

952

953

954

955 if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)

956 Linkage = llvm::GlobalVariable::InternalLinkage;

957

958 llvm::Align Align = CGM.getDataLayout().getABITypeAlign(VTType);

959

960

961 llvm::GlobalVariable *VTable =

963

964

965 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

966

969

970

974 VTable->hasLocalLinkage());

975 components.finishAndSetAsInitializer(VTable);

976

977

978

979 assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration");

981

983

984 if (UsingRelativeLayout) {

986 if (!VTable->isDSOLocal())

988 }

989

990 return VTable;

991}

992

993

994

995

996

997

998

999

1000

1003 llvm::GlobalValue::SanitizerMetadata Meta;

1004 if (GV->hasSanitizerMetadata())

1005 Meta = GV->getSanitizerMetadata();

1006 Meta.NoHWAddress = true;

1007 GV->setSanitizerMetadata(Meta);

1008 }

1009}

1010

1011

1012

1013

1014

1015

1016

1018 llvm::StringRef AliasNameRef) {

1020 "Can only use this if the relative vtable ABI is used");

1021 assert(!VTable->isDSOLocal() && "This should be called only if the vtable is "

1022 "not guaranteed to be dso_local");

1023

1024

1025

1026

1027 if (VTable->hasAvailableExternallyLinkage())

1028 return;

1029

1030

1031

1032

1034 VTable->setName(AliasName + ".local");

1035

1036 auto Linkage = VTable->getLinkage();

1037 assert(llvm::GlobalAlias::isValidLinkage(Linkage) &&

1038 "Invalid vtable alias linkage");

1039

1040 llvm::GlobalAlias *VTableAlias = CGM.getModule().getNamedAlias(AliasName);

1041 if (!VTableAlias) {

1042 VTableAlias = llvm::GlobalAlias::create(VTable->getValueType(),

1043 VTable->getAddressSpace(), Linkage,

1045 } else {

1046 assert(VTableAlias->getValueType() == VTable->getValueType());

1047 assert(VTableAlias->getLinkage() == Linkage);

1048 }

1049 VTableAlias->setVisibility(VTable->getVisibility());

1050 VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());

1051

1052

1053 if (!VTable->hasComdat()) {

1054 VTable->setLinkage(llvm::GlobalValue::InternalLinkage);

1055 } else {

1056

1057

1058

1059

1060

1061

1062

1063

1064 VTable->setVisibility(llvm::GlobalValue::HiddenVisibility);

1065 }

1066

1067 VTableAlias->setAliasee(VTable);

1068}

1069

1072 return CGM.getCodeGenOpts().OptimizationLevel > 0 &&

1074}

1075

1076

1077

1078

1079llvm::GlobalVariable::LinkageTypes

1082 return llvm::GlobalVariable::InternalLinkage;

1083

1084

1087

1088

1089

1092 if (IsInNamedModule || (keyFunction && !RD->hasAttr())) {

1093

1094

1096 if (keyFunction && keyFunction->hasBody(def))

1097 keyFunction = cast(def);

1098

1099 bool IsExternalDefinition =

1101

1105

1106 switch (Kind) {

1109 assert(

1110 (IsInNamedModule || def || CodeGenOpts.OptimizationLevel > 0 ||

1111 CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&

1112 "Shouldn't query vtable linkage without the class in module units, "

1113 "key function, optimizations, or debug info");

1114 if (IsExternalDefinition && CodeGenOpts.OptimizationLevel > 0)

1115 return llvm::GlobalVariable::AvailableExternallyLinkage;

1116

1117 if (keyFunction && keyFunction->isInlined())

1119 ? llvm::GlobalVariable::LinkOnceODRLinkage

1120 : llvm::Function::InternalLinkage;

1121

1122 return llvm::GlobalVariable::ExternalLinkage;

1123

1125 return !Context.getLangOpts().AppleKext ?

1126 llvm::GlobalVariable::LinkOnceODRLinkage :

1127 llvm::Function::InternalLinkage;

1128

1130 return !Context.getLangOpts().AppleKext ?

1131 llvm::GlobalVariable::WeakODRLinkage :

1132 llvm::Function::InternalLinkage;

1133

1135 llvm_unreachable("Should not have been asked to emit this");

1136 }

1137 }

1138

1139

1140

1142 return llvm::Function::InternalLinkage;

1143

1144 llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =

1145 llvm::GlobalValue::LinkOnceODRLinkage;

1146 llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =

1147 llvm::GlobalValue::WeakODRLinkage;

1148 if (RD->hasAttr()) {

1149

1150 DiscardableODRLinkage = NonDiscardableODRLinkage;

1151 } else if (RD->hasAttr()) {

1152

1153 DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;

1154 NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;

1155 }

1156

1161 return DiscardableODRLinkage;

1162

1164

1165

1167 return DiscardableODRLinkage;

1169 ? llvm::GlobalVariable::AvailableExternallyLinkage

1170 : llvm::GlobalVariable::ExternalLinkage;

1171

1173 return NonDiscardableODRLinkage;

1174 }

1175

1176 llvm_unreachable("Invalid TemplateSpecializationKind!");

1177}

1178

1179

1180

1181

1182

1183

1184

1187}

1188

1189void

1192 DI->completeClassData(RD);

1193

1196

1198}

1199

1200

1201

1202

1203

1204

1205

1206

1207

1208

1209

1211 assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");

1212

1213

1214

1216 return false;

1217

1218

1219

1222 return true;

1223

1224

1225

1228 return false;

1229

1230

1231

1234

1235

1236

1238 if (!keyFunction)

1239 return false;

1240

1241

1242

1243 return !keyFunction->hasBody();

1244}

1245

1246

1247

1248

1251

1253 return true;

1254

1255

1257}

1258

1259

1260

1261

1262void CodeGenModule::EmitDeferredVTables() {

1263#ifndef NDEBUG

1264

1265

1266 size_t savedSize = DeferredVTables.size();

1267#endif

1268

1272 else if (shouldOpportunisticallyEmitVTables())

1273 OpportunisticVTables.push_back(RD);

1274

1275 assert(savedSize == DeferredVTables.size() &&

1276 "deferred extra vtables during vtable emission?");

1277 DeferredVTables.clear();

1278}

1279

1281 if (RD->hasAttr() || RD->hasAttr() ||

1282 RD->hasAttr() || RD->hasAttr())

1283 return true;

1284

1286 return false;

1287

1289 while (true) {

1290 auto *D = cast(DC);

1293 if (auto *ND = dyn_cast(D))

1295 if (II->isStr("std") || II->isStr("stdext"))

1296 return true;

1297 break;

1298 }

1299 }

1300

1301 return false;

1302}

1303

1307 return true;

1308

1309 if (getTriple().isOSBinFormatCOFF() &&

1311 return false;

1312

1314}

1315

1318

1319

1320

1321

1322

1323 if (Visited.insert(RD).second)

1324 return llvm::GlobalObject::VCallVisibilityTranslationUnit;

1325

1327 llvm::GlobalObject::VCallVisibility TypeVis;

1329 TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;

1331 TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;

1332 else

1333 TypeVis = llvm::GlobalObject::VCallVisibilityPublic;

1334

1335 for (const auto &B : RD->bases())

1336 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())

1337 TypeVis = std::min(

1338 TypeVis,

1340

1341 for (const auto &B : RD->vbases())

1342 if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())

1343 TypeVis = std::min(

1344 TypeVis,

1346

1347 return TypeVis;

1348}

1349

1351 llvm::GlobalVariable *VTable,

1353

1354

1355

1357 return;

1358

1360

1361 struct AddressPoint {

1363 size_t Offset;

1365 bool operator<(const AddressPoint &RHS) const {

1366 int D = TypeName.compare(RHS.TypeName);

1367 return D < 0 || (D == 0 && Offset < RHS.Offset);

1368 }

1369 };

1370 std::vector AddressPoints;

1372 AddressPoint N{AP.first.getBase(),

1374 AP.second.AddressPointIndex,

1375 {}};

1376 llvm::raw_string_ostream Stream(N.TypeName);

1378 QualType(N.Base->getTypeForDecl(), 0), Stream);

1379 AddressPoints.push_back(std::move(N));

1380 }

1381

1382

1383 llvm::sort(AddressPoints);

1384

1386 for (auto AP : AddressPoints) {

1387

1389

1390

1391

1392

1393

1394 for (unsigned I = 0; I != Comps.size(); ++I) {

1396 continue;

1399 Comps[I].getFunctionDecl()->getType(),

1401 VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD);

1402 }

1403 }

1404

1407 llvm::DenseSet<const CXXRecordDecl *> Visited;

1408 llvm::GlobalObject::VCallVisibility TypeVis =

1410 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)

1411 VTable->setVCallVisibilityMetadata(TypeVis);

1412 }

1413}

static RValue PerformReturnAdjustment(CodeGenFunction &CGF, QualType ResultType, RValue RV, const ThunkInfo &Thunk)

static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk, llvm::Function *ThunkFn, bool ForVTable, GlobalDecl GD)

static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD, bool IsUnprototyped, bool ForVTable)

static void resolveTopLevelMetadata(llvm::Function *Fn, llvm::ValueToValueMapTy &VMap)

This function clones a function's DISubprogram node and enters it into a value map with the intent th...

static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, const CXXRecordDecl *RD)

static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM, const CXXRecordDecl *RD)

Given that we're currently at the end of the translation unit, and we've emitted a reference to the v...

static void AddRelativeLayoutOffset(const CodeGenModule &CGM, ConstantArrayBuilder &builder, CharUnits offset)

static void AddPointerLayoutOffset(const CodeGenModule &CGM, ConstantArrayBuilder &builder, CharUnits offset)

static bool similar(const ABIArgInfo &infoL, CanQualType typeL, const ABIArgInfo &infoR, CanQualType typeR)

static bool UseRelativeLayout(const CodeGenModule &CGM)

static Decl::Kind getKind(const Decl *D)

llvm::DenseSet< const void * > Visited

QualType getTagDeclType(const TagDecl *Decl) const

Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.

QualType getMemberPointerType(QualType T, const Type *Cls) const

Return the uniqued reference to the type for a member pointer to the specified type in the specified ...

QualType getRecordType(const RecordDecl *Decl) const

const CXXMethodDecl * getCurrentKeyFunction(const CXXRecordDecl *RD)

Get our current best idea for the key function of the given record decl, or nullptr if there isn't on...

const LangOptions & getLangOpts() const

bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl, StringRef MangledName)

Represents a C++ destructor within a class.

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

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

QualType getThisType() const

Return the type of the this pointer.

QualType getFunctionObjectParameterType() const

CXXMethodDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

Represents a C++ struct/union/class.

TemplateSpecializationKind getTemplateSpecializationKind() const

Determine whether this particular class is a specialization or instantiation of a class template or m...

base_class_range vbases()

bool isDynamicClass() const

unsigned getNumVBases() const

Retrieves the number of virtual base classes of this class.

CharUnits - This is an opaque type for sizes expressed in character units.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

PointerAuthOptions PointerAuth

Configuration for pointer-signing.

ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...

@ Indirect

Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...

bool isSRetAfterThis() const

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

llvm::Type * getElementType() const

Return the type of the values stored in this address.

static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)

Apply TemporaryLocation if it is valid.

static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)

Set the IRBuilder to not attach debug locations.

llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")

virtual bool hasMostDerivedReturn(GlobalDecl GD) const

virtual bool HasThisReturn(GlobalDecl GD) const

Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...

virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0

Emit the ABI-specific prolog for the function.

virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const CXXRecordDecl *UnadjustedClass, const ThunkInfo &TI)=0

virtual StringRef GetPureVirtualCallName()=0

Gets the pure virtual member call function.

virtual void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResultType)

virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0

Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...

virtual StringRef GetDeletedVirtualCallName()=0

Gets the deleted virtual member call name.

void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params)

Build a parameter variable suitable for 'this'.

virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const CXXRecordDecl *UnadjustedClass, const ReturnAdjustment &RA)=0

virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0

Insert any ABI-specific implicit parameters into the parameter list for a function.

virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0

virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs)

virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0

Emit any tables needed to implement virtual inheritance.

virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0

Emits the VTable definitions required for the given record type.

virtual bool exportThunk()=0

MangleContext & getMangleContext()

Gets the mangle context.

static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())

This class gathers all debug information during compilation and is responsible for emitting to llvm g...

CGFunctionInfo - Class to encapsulate the information about a function definition.

bool usesInAlloca() const

Return true if this function uses inalloca arguments.

ABIArgInfo & getReturnInfo()

unsigned getCallingConvention() const

getCallingConvention - Return the user specified calling convention, which has been translated into a...

const_arg_iterator arg_begin() const

unsigned getRegParm() const

CanQualType getReturnType() const

unsigned arg_size() const

CallArgList - Type for representing both the value and type of arguments in a call.

void add(RValue rvalue, QualType type)

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

GlobalDecl CurGD

CurGD - The GlobalDecl for the current function being compiled.

void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, const ThunkInfo *Thunk, bool IsUnprototyped)

llvm::Function * GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk)

void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, GlobalDecl GD, const ThunkInfo &Thunk, bool IsUnprototyped)

Generate a thunk for the given method.

bool CurFuncIsThunk

In C++, whether we are code generating a thunk.

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

Construct an address with the natural alignment of T.

llvm::Type * ConvertTypeForMem(QualType T)

const Decl * CurCodeDecl

CurCodeDecl - This is the inner-most code context, which includes blocks.

void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())

Emit code for the start of a function.

void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)

EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...

RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)

EmitCall - Generate a call of the given function, expecting the given result type,...

const Decl * CurFuncDecl

CurFuncDecl - Holds the Decl for the current outermost non-closure context.

void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo, bool IsUnprototyped)

bool AutoreleaseResult

In ARC, whether we should autorelease the return value.

Address LoadCXXThisAddress()

static bool hasAggregateEvaluationKind(QualType T)

llvm::Value * LoadCXXThis()

LoadCXXThis - Load the value of 'this'.

const CGFunctionInfo * CurFnInfo

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

llvm::LLVMContext & getLLVMContext()

void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)

Emit a musttail call for a thunk with a potentially adjusted this pointer.

This class organizes the cross-function state that is used while generating LLVM code.

void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const

Set visibility, dllimport/dllexport and dso_local.

void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD)

Create and attach type metadata for the given vtable.

llvm::GlobalObject::VCallVisibility GetVCallVisibilityLevel(const CXXRecordDecl *RD, llvm::DenseSet< const CXXRecordDecl * > &Visited)

Returns the vcall visibility of the given type.

llvm::Module & getModule() const

llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)

Create or return a runtime function declaration with the specified type and name.

CGDebugInfo * getModuleDebugInfo()

CodeGenVTables & getVTables()

CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const

Return the store size, in character units, of the given LLVM type.

llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)

Get the address of the RTTI descriptor for the given type.

llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)

Return the address of the given function.

void ErrorUnsupported(const Stmt *S, const char *Type)

Print out an error that codegen doesn't support the specified stmt yet.

const LangOptions & getLangOpts() const

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

void EmitVTableTypeMetadata(const CXXRecordDecl *RD, llvm::GlobalVariable *VTable, const VTableLayout &VTLayout)

Emit type metadata for the given vtable using the given layout.

bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)

Returns whether the given record has hidden LTO visibility and therefore may participate in (single-m...

const llvm::DataLayout & getDataLayout() const

CGCXXABI & getCXXABI() const

CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)

Returns the assumed alignment of an opaque pointer to the given class.

const llvm::Triple & getTriple() const

bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD)

Returns whether the given record has public LTO visibility (regardless of -lto-whole-program-visibili...

void EmitVTable(CXXRecordDecl *Class)

This is a callback from Sema to tell us that a particular vtable is required to be emitted in this tr...

void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk)

Get the LLVM attributes and calling convention to use for a particular function type.

void setFunctionLinkage(GlobalDecl GD, llvm::Function *F)

ItaniumVTableContext & getItaniumVTableContext()

ASTContext & getContext() const

llvm::Type * getVTableComponentType() const

bool supportsCOMDAT() const

bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)

Return true iff the given type uses 'sret' when used as a return type.

const CodeGenOptions & getCodeGenOpts() const

llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)

Will return a global variable of the given type.

llvm::LLVMContext & getLLVMContext()

llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)

Return the appropriate linkage for the vtable, VTT, and type information of the given class.

void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)

Set the LLVM function attributes (sext, zext, etc).

void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)

Set the LLVM function attributes which only apply to a function definition.

llvm::Metadata * CreateMetadataIdentifierForVirtualMemPtrType(QualType T)

Create a metadata identifier that is intended to be used to check virtual calls via a member function...

llvm::Constant * GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, GlobalDecl GD)

Get the address of the thunk for the given global decl.

llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)

GetFunctionType - Get the LLVM function type for.

bool isFuncTypeConvertible(const FunctionType *FT)

isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....

const CGFunctionInfo & arrangeGlobalDeclaration(GlobalDecl GD)

const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)

Arrange a thunk that takes 'this' as the first parameter followed by varargs.

const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)

Arrange a call to a C++ method, passing the given arguments.

llvm::Type * GetFunctionTypeForVTable(GlobalDecl GD)

GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, given a CXXMethodDecl.

void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti, bool vtableHasLocalLinkage)

Add vtable components for the given vtable layout to the given global initializer.

void GenerateClassData(const CXXRecordDecl *RD)

GenerateClassData - Generate all the class data required to be generated upon definition of a KeyFunc...

void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable, llvm::StringRef AliasNameRef)

Generate a public facing alias for the vtable and make the vtable either hidden or private.

ItaniumVTableContext & getItaniumVTableContext()

CodeGenVTables(CodeGenModule &CGM)

llvm::GlobalVariable * GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual, llvm::GlobalVariable::LinkageTypes Linkage, VTableAddressPointsMapTy &AddressPoints)

GenerateConstructionVTable - Generate a construction vtable for the given base subobject.

llvm::Type * getVTableType(const VTableLayout &layout)

Returns the type of a vtable with the given layout.

bool isVTableExternal(const CXXRecordDecl *RD)

At this point in the translation unit, does it appear that can we rely on the vtable being defined el...

void RemoveHwasanMetadata(llvm::GlobalValue *GV) const

Specify a global should not be instrumented with hwasan.

void EmitThunks(GlobalDecl GD)

EmitThunks - Emit the associated thunks for the given global decl.

ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)

A helper class of ConstantInitBuilder, used for building constant array initializers.

StructBuilder beginStruct(llvm::StructType *structTy=nullptr)

The standard implementation of ConstantInitBuilder used in Clang.

A helper class of ConstantInitBuilder, used for building constant struct initializers.

FunctionArgList - Type for representing both the decl and type of parameters to a function.

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

static RValue get(llvm::Value *V)

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)

Compute the arguments required by the given formal prototype, given that there may be some additional...

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

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.

DeclContext * getRedeclContext()

getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...

bool isInNamedModule() const

Whether this declaration comes from a named module.

SourceLocation getLocation() const

bool shouldEmitInExternalSource() const

Whether the definition of the declaration should be emitted in external sources.

Represents a function declaration or definition.

param_iterator param_end()

bool isInlined() const

Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...

ArrayRef< ParmVarDecl * > parameters() const

param_iterator param_begin()

TemplateSpecializationKind getTemplateSpecializationKind() const

Determine what kind of template instantiation this function represents.

bool hasBody(const FunctionDecl *&Definition) const

Returns true if the function has a body.

bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const

Returns true if the function has a definition that does not need to be instantiated.

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

FunctionType - C99 6.7.5.3 - Function Declarators.

QualType getReturnType() const

GlobalDecl - represents a global declaration.

GlobalDecl getWithDecl(const Decl *D)

CXXDtorType getDtorType() const

const Decl * getDecl() const

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

bool isRelativeLayout() const

GlobalDecl findOriginalMethod(GlobalDecl GD)

Return the method that added the v-table slot that will be used to call the given method.

SanitizerSet Sanitize

Set of enabled sanitizers.

Visibility getVisibility() const

Linkage getLinkage() const

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

virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0

virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0

virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0

Generates a unique string for an externally visible type for use with TBAA or type uniquing.

LinkageInfo getLinkageAndVisibility() const

Determines the linkage and visibility of this entity.

bool isExternallyVisible() const

Represents a parameter to a function.

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

Encodes a location in the source.

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

bool isItaniumFamily() const

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

bool hasKeyFunctions() const

Does this ABI use key functions? If so, class data such as the vtable is emitted with strong linkage ...

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

const CXXRecordDecl * getPointeeCXXRecordDecl() const

If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

@ CK_DeletingDtorPointer

A pointer to the deleting destructor.

@ CK_UnusedFunctionPointer

An entry that is never used.

@ CK_CompleteDtorPointer

A pointer to the complete destructor.

virtual const ThunkInfoVectorTy * getThunkInfo(GlobalDecl GD)

const AddressPointsIndexMapTy & getAddressPointIndices() const

size_t getVTableOffset(size_t i) const

ArrayRef< VTableComponent > vtable_components() const

size_t getNumVTables() const

ArrayRef< VTableThunkTy > vtable_thunks() const

const AddressPointsMapTy & getAddressPoints() const

size_t getVTableSize(size_t i) const

RangeSelector name(std::string ID)

Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...

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

bool operator<(DeclarationName LHS, DeclarationName RHS)

Ordering on two declaration names.

Linkage

Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.

@ Dtor_Base

Base object dtor.

const FunctionProtoType * T

TemplateSpecializationKind

Describes the kind of template specialization that a particular template specialization declaration r...

@ TSK_ExplicitInstantiationDefinition

This template specialization was instantiated from a template due to an explicit instantiation defini...

@ TSK_ExplicitInstantiationDeclaration

This template specialization was instantiated from a template due to an explicit instantiation declar...

@ TSK_ExplicitSpecialization

This template specialization was declared or defined by an explicit specialization (C++ [temp....

@ TSK_ImplicitInstantiation

This template specialization was implicitly instantiated from a template.

@ TSK_Undeclared

This template specialization was formed from a template-id but has not yet been declared,...

CallingConv

CallingConv - Specifies the calling convention that a function uses.

bool isExternallyVisible(Linkage L)

@ HiddenVisibility

Objects with "hidden" visibility are not seen by the dynamic linker.

llvm::PointerType * GlobalsInt8PtrTy

llvm::IntegerType * Int32Ty

llvm::IntegerType * PtrDiffTy

PointerAuthSchema CXXVirtualFunctionPointers

The ABI for most C++ virtual function pointers, i.e. v-table entries.

bool has(SanitizerMask K) const

Check if a certain (single) sanitizer is enabled.

The this pointer adjustment as well as an optional return adjustment for a thunk.

ReturnAdjustment Return

The return adjustment.