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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

25#include

26#include

27#include

28

29using namespace clang;

31

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

34

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

38 true, true);

39}

40

42 llvm::Function *ThunkFn, bool ForVTable,

47

48

50

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

53 ThunkFn->setDSOLocal(true);

54 }

55

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

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

58}

59

60#ifndef NDEBUG

64 (typeL == typeR ||

67}

68#endif

69

73

75

76 llvm::BasicBlock *AdjustNull = nullptr;

77 llvm::BasicBlock *AdjustNotNull = nullptr;

78 llvm::BasicBlock *AdjustEnd = nullptr;

79

81

82 if (NullCheckValue) {

86

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

90 }

91

95 CGF,

97 ClassAlign),

98 ClassDecl, Thunk.Return);

99

100 if (NullCheckValue) {

101 CGF.Builder.CreateBr(AdjustEnd);

103 CGF.Builder.CreateBr(AdjustEnd);

105

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

107 PHI->addIncoming(ReturnValue, AdjustNotNull);

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

109 AdjustNull);

110 ReturnValue = PHI;

111 }

112

114}

115

116

117

118

119

120

122 llvm::ValueToValueMapTy &VMap) {

123

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

125 if (!DIS)

126 return;

127 auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone());

128

129

130

131

132 NewDIS->replaceRetainedNodes(llvm::MDTuple::get(Fn->getContext(), {}));

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

134

135

136

137 for (auto &BB : *Fn) {

138 for (auto &I : BB) {

139 for (llvm::DbgVariableRecord &DVR :

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

141 auto *DILocal = DVR.getVariable();

142 if (!DILocal->isResolved())

143 DILocal->resolve();

144 }

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

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

147 if (!DILocal->isResolved())

148 DILocal->resolve();

149 }

150 }

151 }

152}

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170llvm::Function *

177

178

180 llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo);

181 llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, true);

183

184

185

186

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

189 return Fn;

190 }

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

192

193

194 llvm::ValueToValueMapTy VMap;

195

196

197

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

200 Fn->replaceAllUsesWith(NewFn);

201 NewFn->takeName(Fn);

202 Fn->eraseFromParent();

203 Fn = NewFn;

204

205

207

208

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

210 if (CGM.ReturnTypeUsesSRet(FnInfo))

211 ++AI;

212

213

214

217 CGM.getClassPointerAlignment(MD->getParent()));

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

219 llvm::BasicBlock::iterator ThisStore =

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

222 });

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

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

225

226 Builder.SetInsertPoint(&*ThisStore);

227

229 llvm::Value *AdjustedThisPtr = CGM.getCXXABI().performThisAdjustment(

230 *this, ThisPtr, ThisValueClass, Thunk);

231 AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,

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

233 ThisStore->setOperand(0, AdjustedThisPtr);

234

236

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

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

241 T->eraseFromParent();

242 Builder.SetInsertPoint(&BB);

245 break;

246 }

247 }

248 }

249

250 return Fn;

251}

252

255 bool IsUnprototyped) {

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

259

260

264 if (IsUnprototyped)

265 ResultType = CGM.getContext().VoidTy;

266 else if (CGM.getCXXABI().HasThisReturn(GD))

267 ResultType = ThisType;

268 else if (CGM.getCXXABI().hasMostDerivedReturn(GD))

269 ResultType = CGM.getContext().VoidPtrTy;

270 else

273

274

275 CGM.getCXXABI().buildThisParam(*this, FunctionArgs);

276

277

278 if (!IsUnprototyped) {

280

282 CGM.getCXXABI().addImplicitStructorParams(*this, ResultType,

283 FunctionArgs);

284 }

285

286

290

292

293

294 CGM.getCXXABI().EmitInstanceFunctionProlog(*this);

295 CXXThisValue = CXXABIThisValue;

298}

299

308

311 bool IsUnprototyped) {

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

315

316

319 if (Thunk)

321

322 llvm::Value *AdjustedThisPtr =

324 ThisValueClass, *Thunk)

326

327

328

329

330 if (CurFnInfo->usesInAlloca() || CurFnInfo->isVariadic() || IsUnprototyped) {

332 if (IsUnprototyped)

333 CGM.ErrorUnsupported(

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

335 else if (CurFnInfo->isVariadic())

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

337 "thunks for variadic functions");

338 else

339 CGM.ErrorUnsupported(

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

341 }

343 return;

344 }

345

346

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

350

352 CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, CurGD, CallArgs);

353

354#ifndef NDEBUG

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

356#endif

357

360

362

363#ifndef NDEBUG

364 const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(

366 assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&

367 CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&

368 CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());

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

372 assert(CallFnInfo.arg_size() == CurFnInfo->arg_size());

373 for (unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i)

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

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

377 CurFnInfo->arg_begin()[i].type));

378#endif

379

380

382 ? ThisType

383 : CGM.getCXXABI().hasMostDerivedReturn(CurGD)

384 ? CGM.getContext().VoidPtrTy

391 false, true);

392

393

394 llvm::CallBase *CallOrInvoke;

396 CallArgs, &CallOrInvoke);

397

398

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

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

403

404

406 CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType);

407

408

410

412}

413

415 llvm::Value *AdjustedThisPtr,

416 llvm::FunctionCallee Callee) {

417

418

419

420

422

423

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

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

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

431 Args[ThisArgNo] = AdjustedThisPtr;

432 } else {

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

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

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

438 Builder.CreateStore(AdjustedThisPtr, ThisAddr);

439 }

440

441

442

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

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

445

446

448 llvm::AttributeList Attrs;

449 CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD,

450 Attrs, CallingConv, true,

451 false);

452 Call->setAttributes(Attrs);

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

454

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

457 else

459

460

461

463

465}

466

470 bool IsUnprototyped) {

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

472

474

475

476

477 llvm::Type *Ty;

478 if (IsUnprototyped)

480 else

481 Ty = CGM.getTypes().GetFunctionType(FnInfo);

482

483 llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, true);

484

485

487 &Thunk, IsUnprototyped);

488}

489

491 bool IsUnprototyped, bool ForVTable) {

492

493

495 return true;

496

497

498

499

500

501 if (ForVTable)

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

503

504

505 return true;

506}

507

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

509 const ThunkInfo &TI,

510 bool ForVTable) {

512

513

514

515

516 SmallString<256> Name;

517 MangleContext &MCtx = CGM.getCXXABI().getMangleContext();

518 llvm::raw_svector_ostream Out(Name);

519

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

522 false, Out);

523 } else

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

525

526 if (CGM.getContext().useAbbreviatedThunkName(GD, Name.str())) {

527 Name = "";

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

530 true, Out);

531 else

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

533 }

534

535 llvm::Type *ThunkVTableTy = CGM.getTypes().GetFunctionTypeForVTable(GD);

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

537

538

539 bool IsUnprototyped = !CGM.getTypes().isFuncTypeConvertible(

542 return Thunk;

543

544

545

546 const CGFunctionInfo &FnInfo =

547 IsUnprototyped ? CGM.getTypes().arrangeUnprototypedMustTailThunk(MD)

548 : CGM.getTypes().arrangeGlobalDeclaration(GD);

549 llvm::FunctionType *ThunkFnTy = CGM.getTypes().GetFunctionType(FnInfo);

550

551

552

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

555 llvm::GlobalValue *OldThunkFn = ThunkFn;

556

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

558

559

560 OldThunkFn->setName(StringRef());

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

562 Name.str(), &CGM.getModule());

563 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, false);

564

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

566 OldThunkFn->replaceAllUsesWith(ThunkFn);

567 }

568

569

570 OldThunkFn->eraseFromParent();

571 }

572

573 bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();

574 bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;

575

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

577 if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {

578

579 return ThunkFn;

580 }

581

583 return ThunkFn;

584 }

585

586

587

588

589

590 if (IsUnprototyped)

591 ThunkFn->addFnAttr("thunk");

592

593 CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);

594

595

596

597

598

599

600 bool ShouldCloneVarArgs = false;

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

602 ShouldCloneVarArgs = true;

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

605 case llvm::Triple::x86_64:

606 case llvm::Triple::x86:

607 case llvm::Triple::aarch64:

608 ShouldCloneVarArgs = false;

609 break;

610 default:

611 break;

612 }

613 }

614 }

615

616 if (ShouldCloneVarArgs) {

617 if (UseAvailableExternallyLinkage)

618 return ThunkFn;

619 ThunkFn =

620 CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, TI);

621 } else {

622

623 CodeGenFunction(CGM).generateThunk(ThunkFn, FnInfo, GD, TI, IsUnprototyped);

624 }

625

627 return ThunkFn;

628}

629

633

634

636 return;

637

639 VTContext->getThunkInfo(GD);

640

641 if (!ThunkInfoVector)

642 return;

643

644 for (const ThunkInfo& Thunk : *ThunkInfoVector)

645 maybeEmitThunk(GD, Thunk, false);

646}

647

649 llvm::Constant *component,

650 unsigned vtableAddressPoint,

651 bool vtableHasLocalLinkage,

652 bool isCompleteDtor) const {

653

654 if (component->isNullValue())

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

656

657 auto *globalVal =

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

660

661

662

663

664

665

666

667

668

669

670

671

672 auto stubLinkage = vtableHasLocalLinkage

673 ? llvm::GlobalValue::InternalLinkage

674 : llvm::GlobalValue::LinkOnceODRLinkage;

675

676 llvm::Constant *target;

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

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

679 } else {

681 rttiProxyName.append(".rtti_proxy");

682

683

684

685

686

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

688 if (!proxy) {

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

690 true, stubLinkage,

691 globalVal, rttiProxyName);

692 proxy->setDSOLocal(true);

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

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

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

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

697 }

698

699

700

701

702

704 }

705 target = proxy;

706 }

707

709 vtableAddressPoint);

710}

711

716

720

726

728 return CGM.getVTableComponentType();

729}

730

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

737}

738

744

746 const VTableLayout &layout,

747 unsigned componentIndex,

748 llvm::Constant *rtti,

749 unsigned &nextVTableThunkIndex,

750 unsigned vtableAddressPoint,

751 bool vtableHasLocalLinkage) {

753

754 auto addOffsetConstant =

756

757 switch (component.getKind()) {

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

760

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

763

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

766

769 return addRelativeComponent(builder, rtti, vtableAddressPoint,

770 vtableHasLocalLinkage,

771 false);

772 else

773 return builder.add(rtti);

774

778 GlobalDecl GD = component.getGlobalDecl(

779 CGM.getContext().getTargetInfo().emitVectorDeletingDtors(

780 CGM.getContext().getLangOpts()));

781

782 const bool IsThunk =

783 nextVTableThunkIndex < layout.vtable_thunks().size() &&

784 layout.vtable_thunks()[nextVTableThunkIndex].first == componentIndex;

785

786 if (CGM.getLangOpts().CUDA) {

787

788

789

791

792

793 bool CanEmitMethod =

794 CGM.getLangOpts().CUDAIsDevice

795 ? MD->hasAttr()

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

797 if (!CanEmitMethod) {

798 if (IsThunk)

799 nextVTableThunkIndex++;

800 return builder.add(

801 llvm::ConstantExpr::getNullValue(CGM.GlobalsInt8PtrTy));

802 }

803

804 }

805

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

807

808

809

810

811

812

813

815 return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy);

816

817

818

819 if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPIsTargetDevice &&

820 CGM.getTriple().isNVPTX())

821 return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy);

822 llvm::FunctionType *fnTy =

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

825 CGM.CreateRuntimeFunction(fnTy, name).getCallee());

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

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

828 return fn;

829 };

830

831 llvm::Constant *fnPtr;

832

833

835 if (!PureVirtualFn)

836 PureVirtualFn =

837 getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());

838 fnPtr = PureVirtualFn;

839

840

842 if (!DeletedVirtualFn)

843 DeletedVirtualFn =

844 getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName());

845 fnPtr = DeletedVirtualFn;

846

847

848 } else if (IsThunk) {

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

850

851 nextVTableThunkIndex++;

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

853 if (CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers) {

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

856 }

857

858

859 } else {

860 llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);

861 fnPtr = CGM.GetAddrOfFunction(GD, fnTy, true);

862 if (CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers)

864 }

865

867 return addRelativeComponent(

868 builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,

870 } else {

871

872

873

874

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

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

877

878 if (FnAS != GVAS)

879 fnPtr =

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

881 if (const auto &Schema =

882 CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers)

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

884 return builder.add(fnPtr);

885 }

886 }

887

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

891 else

893 }

894

895 llvm_unreachable("Unexpected vtable component kind");

896}

897

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

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

903

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

905}

906

909 llvm::Constant *rtti,

910 bool vtableHasLocalLinkage) {

912

914 unsigned nextVTableThunkIndex = 0;

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

916 vtableIndex != endIndex; ++vtableIndex) {

917 auto vtableElem = builder.beginArray(componentType);

918

919 size_t vtableStart = layout.getVTableOffset(vtableIndex);

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

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

922 ++componentIndex) {

923 addVTableComponent(vtableElem, layout, componentIndex, rtti,

924 nextVTableThunkIndex, addressPoints[vtableIndex],

925 vtableHasLocalLinkage);

926 }

927 vtableElem.finishAndAddTo(builder);

928 }

929}

930

933 llvm::GlobalVariable::LinkageTypes Linkage,

934 VTableAddressPointsMapTy &AddressPoints) {

935 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())

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

937

938 std::unique_ptr VTLayout(

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

941

942

943 AddressPoints = VTLayout->getAddressPoints();

944

945

947 llvm::raw_svector_ostream Out(OutName);

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

950 Base.getBase(), Out);

952

954 bool VTableAliasExists =

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

956 if (VTableAliasExists) {

957

958 Name.append(".local");

959 }

960

962

963

964

965

966

967

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

969 Linkage = llvm::GlobalVariable::InternalLinkage;

970

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

972

973

974 llvm::GlobalVariable *VTable =

975 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align);

976

977

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

979

980 llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(

981 CGM.getContext().getCanonicalTagType(Base.getBase()));

982

983

987 VTable->hasLocalLinkage());

988 components.finishAndSetAsInitializer(VTable);

989

990

991

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

993 CGM.setGVProperties(VTable, RD);

994

995 CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout);

996

997 if (UsingRelativeLayout) {

999 if (!VTable->isDSOLocal())

1001 }

1002

1003 return VTable;

1004}

1005

1006

1007

1008

1009

1010

1011

1012

1013

1015 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::HWAddress)) {

1016 llvm::GlobalValue::SanitizerMetadata Meta;

1017 if (GV->hasSanitizerMetadata())

1018 Meta = GV->getSanitizerMetadata();

1019 Meta.NoHWAddress = true;

1020 GV->setSanitizerMetadata(Meta);

1021 }

1022}

1023

1024

1025

1026

1027

1028

1029

1031 llvm::StringRef AliasNameRef) {

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

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

1035 "not guaranteed to be dso_local");

1036

1037

1038

1039

1040 if (VTable->hasAvailableExternallyLinkage())

1041 return;

1042

1043

1044

1045

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

1048

1049 auto Linkage = VTable->getLinkage();

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

1051 "Invalid vtable alias linkage");

1052

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

1054 if (!VTableAlias) {

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

1056 VTable->getAddressSpace(), Linkage,

1057 AliasName, &CGM.getModule());

1058 } else {

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

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

1061 }

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

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

1064

1065

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

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

1068 } else {

1069

1070

1071

1072

1073

1074

1075

1076

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

1078 }

1079

1080 VTableAlias->setAliasee(VTable);

1081}

1082

1088

1089

1090

1091

1092llvm::GlobalVariable::LinkageTypes

1095 return llvm::GlobalVariable::InternalLinkage;

1096

1097

1100

1101

1102

1104 IsInNamedModule ? nullptr : Context.getCurrentKeyFunction(RD);

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

1106

1107

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

1111

1112 bool IsExternalDefinition =

1114

1118

1119 switch (Kind) {

1122 assert(

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

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

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

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

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

1128 return llvm::GlobalVariable::AvailableExternallyLinkage;

1129

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

1131 return !Context.getLangOpts().AppleKext

1132 ? llvm::GlobalVariable::LinkOnceODRLinkage

1133 : llvm::Function::InternalLinkage;

1134

1135 return llvm::GlobalVariable::ExternalLinkage;

1136

1138 return !Context.getLangOpts().AppleKext ?

1139 llvm::GlobalVariable::LinkOnceODRLinkage :

1140 llvm::Function::InternalLinkage;

1141

1143 return !Context.getLangOpts().AppleKext ?

1144 llvm::GlobalVariable::WeakODRLinkage :

1145 llvm::Function::InternalLinkage;

1146

1148 return IsExternalDefinition

1149 ? llvm::GlobalVariable::AvailableExternallyLinkage

1150 : llvm::GlobalVariable::ExternalLinkage;

1151 }

1152 }

1153

1154

1155

1156 if (Context.getLangOpts().AppleKext)

1157 return llvm::Function::InternalLinkage;

1158

1159 llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =

1160 llvm::GlobalValue::LinkOnceODRLinkage;

1161 llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =

1162 llvm::GlobalValue::WeakODRLinkage;

1163 if (RD->hasAttr()) {

1164

1165 DiscardableODRLinkage = NonDiscardableODRLinkage;

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

1167

1168 DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;

1169 NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;

1170 }

1171

1176 return DiscardableODRLinkage;

1177

1179

1180

1182 return DiscardableODRLinkage;

1184 ? llvm::GlobalVariable::AvailableExternallyLinkage

1185 : llvm::GlobalVariable::ExternalLinkage;

1186

1188 return NonDiscardableODRLinkage;

1189 }

1190

1191 llvm_unreachable("Invalid TemplateSpecializationKind!");

1192}

1193

1194

1195

1196

1197

1198

1199

1201 VTables.GenerateClassData(theClass);

1202}

1203

1204void

1206 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())

1207 DI->completeClassData(RD);

1208

1210 CGM.getCXXABI().emitVirtualInheritanceTables(RD);

1211

1212 CGM.getCXXABI().emitVTableDefinitions(*this, RD);

1213}

1214

1215

1216

1217

1218

1219

1220

1221

1222

1223

1224

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

1227

1228

1229

1230 if (CGM.getTarget().getCXXABI().isMicrosoft())

1231 return false;

1232

1233

1234

1237 return true;

1238

1239

1240

1243 return false;

1244

1245

1246

1249

1250

1251

1252 const CXXMethodDecl *keyFunction = CGM.getContext().getCurrentKeyFunction(RD);

1253 if (!keyFunction)

1254 return false;

1255

1256

1257

1258 return !keyFunction->hasBody();

1259}

1260

1261

1262

1263

1266

1268 return true;

1269

1270

1272}

1273

1274

1275

1276

1277void CodeGenModule::EmitDeferredVTables() {

1278#ifndef NDEBUG

1279

1280

1281 size_t savedSize = DeferredVTables.size();

1282#endif

1283

1284 for (const CXXRecordDecl *RD : DeferredVTables)

1286 VTables.GenerateClassData(RD);

1287 else if (shouldOpportunisticallyEmitVTables())

1288 OpportunisticVTables.push_back(RD);

1289

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

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

1292 DeferredVTables.clear();

1293}

1294

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

1297 RD->hasAttr() || RD->hasAttr())

1298 return true;

1299

1301 return false;

1302

1304 while (true) {

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

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

1311 return true;

1312 break;

1313 }

1314 }

1315

1316 return false;

1317}

1318

1322 return true;

1323

1324 if (getTriple().isOSBinFormatCOFF() &&

1326 return false;

1327

1329}

1330

1332 const CXXRecordDecl *RD, llvm::DenseSet<const CXXRecordDecl *> &Visited) {

1333

1334

1335

1336

1337

1338 if (!Visited.insert(RD).second)

1339 return llvm::GlobalObject::VCallVisibilityTranslationUnit;

1340

1342 llvm::GlobalObject::VCallVisibility TypeVis;

1344 TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;

1346 TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;

1347 else

1348 TypeVis = llvm::GlobalObject::VCallVisibilityPublic;

1349

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

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

1352 TypeVis = std::min(

1353 TypeVis,

1355

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

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

1358 TypeVis = std::min(

1359 TypeVis,

1361

1362 return TypeVis;

1363}

1364

1366 llvm::GlobalVariable *VTable,

1368

1369

1370

1371

1374 return;

1375

1377

1378 struct AddressPoint {

1380 size_t Offset;

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

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

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

1385 }

1386 };

1387 std::vector AddressPoints;

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

1391 AP.second.AddressPointIndex,

1392 {}};

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

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

1397 }

1398

1399

1400 llvm::sort(AddressPoints);

1401

1403 for (auto AP : AddressPoints) {

1404

1406

1407

1408

1409

1410

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

1413 continue;

1415 Context.getMemberPointerType(Comps[I].getFunctionDecl()->getType(),

1416 std::nullopt, AP.Base));

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

1418 }

1419 }

1420

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

1424 llvm::GlobalObject::VCallVisibility TypeVis =

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

1427 VTable->setVCallVisibilityMetadata(TypeVis);

1428 }

1429}

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

Definition CGVTables.cpp:70

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

Definition CGVTables.cpp:41

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

Definition CGVTables.cpp:490

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...

Definition CGVTables.cpp:121

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

Definition CGVTables.cpp:1083

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...

Definition CGVTables.cpp:1264

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

Definition CGVTables.cpp:739

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

Definition CGVTables.cpp:731

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

Definition CGVTables.cpp:61

static bool UseRelativeLayout(const CodeGenModule &CGM)

Definition CGVTables.cpp:712

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

static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)

CanQualType getCanonicalTagType(const TagDecl *TD) const

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

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.

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::Value * CreateIsNull(Address Addr, const Twine &Name="")

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 llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const CXXRecordDecl *UnadjustedClass, const ReturnAdjustment &RA)=0

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

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.

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...

GlobalDecl CurGD

CurGD - The GlobalDecl for the current function being compiled.

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

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

Definition CGVTables.cpp:414

Address LoadCXXThisAddress()

bool CurFuncIsThunk

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

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

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

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

createBasicBlock - Create an LLVM basic block.

void FinishThunk()

Definition CGVTables.cpp:300

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.

const Decl * CurCodeDecl

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

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

Definition CGVTables.cpp:309

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.

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

Definition CGVTables.cpp:171

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.

bool AutoreleaseResult

In ARC, whether we should autorelease the return value.

llvm::Type * ConvertTypeForMem(QualType T)

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

Generate a thunk for the given method.

Definition CGVTables.cpp:467

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

Definition CGVTables.cpp:253

static bool hasAggregateEvaluationKind(QualType T)

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

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 EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

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.

Definition CGVTables.cpp:1331

llvm::Module & getModule() const

CodeGenVTables & getVTables()

CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const

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

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.

Definition CGVTables.cpp:1365

bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)

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

Definition CGVTables.cpp:1319

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...

Definition CGVTables.cpp:1295

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...

Definition CGVTables.cpp:1200

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

ItaniumVTableContext & getItaniumVTableContext()

ASTContext & getContext() const

llvm::Type * getVTableComponentType() const

Definition CGVTables.cpp:721

bool supportsCOMDAT() const

const CodeGenOptions & getCodeGenOpts() const

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

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

Definition CGVTables.cpp:1093

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.

Definition CGVTables.cpp:35

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.

Definition CGVTables.cpp:907

void GenerateClassData(const CXXRecordDecl *RD)

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

Definition CGVTables.cpp:1205

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

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

Definition CGVTables.cpp:1030

ItaniumVTableContext & getItaniumVTableContext()

CodeGenVTables(CodeGenModule &CGM)

Definition CGVTables.cpp:32

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.

Definition CGVTables.cpp:931

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

Returns the type of a vtable with the given layout.

Definition CGVTables.cpp:898

bool useRelativeLayout() const

Return true if the relative vtable layout is used.

Definition CGVTables.cpp:717

llvm::Type * getVTableComponentType() const

Return the type used as components for a vtable.

Definition CGVTables.cpp:727

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...

Definition CGVTables.cpp:1225

void RemoveHwasanMetadata(llvm::GlobalValue *GV) const

Specify a global should not be instrumented with hwasan.

Definition CGVTables.cpp:1014

void EmitThunks(GlobalDecl GD)

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

Definition CGVTables.cpp:630

void addRelativeOffsetToPosition(llvm::IntegerType *type, llvm::Constant *target, size_t position)

Same as addRelativeOffset(), but instead relative to an element in this aggregate,...

void add(llvm::Constant *value)

Add a new value to this initializer.

void addNullPointer(llvm::PointerType *ptrTy)

Add a null pointer of a specific type.

void addSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, GlobalDecl CalleeDecl, QualType CalleeType)

Add a signed pointer using the given pointer authentication schema.

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.

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.

Visibility getVisibility() const

Linkage getLinkage() const

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.

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?

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.

SmallVector< ThunkInfo, 1 > ThunkInfoVectorTy

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.

CanQual< Type > CanQualType

Represents a canonical, potentially-qualified type.

bool isa(CodeGen::Address addr)

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

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.

const FunctionProtoType * T

@ Dtor_Base

Base object dtor.

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.

U cast(CodeGen::Address addr)

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

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

ReturnAdjustment Return

The return adjustment.