A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/CodeGen_2MicrosoftCXXABI_8cpp_source.html below:

clang: lib/CodeGen/MicrosoftCXXABI.cpp Source File

30#include "llvm/ADT/StringExtras.h" 31#include "llvm/ADT/StringSet.h" 32#include "llvm/IR/Intrinsics.h" 34using namespace clang

;

35using namespace

CodeGen;

40struct

VBTableGlobals {

45class

MicrosoftCXXABI :

public CGCXXABI

{

48

:

CGCXXABI

(CGM), BaseClassDescriptorType(nullptr),

49

ClassHierarchyDescriptorType(nullptr),

50

CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),

51

ThrowInfoType(nullptr) {

54 "visibility export mapping option unimplemented in this ABI"

);

69 if

(isa<CXXDestructorDecl>(GD.

getDecl

())) {

78 case Dtor_Comdat

: llvm_unreachable(

"emitting dtor comdat as function?"

);

80

llvm_unreachable(

"bad dtor kind"

);

89

assert(Args.size() >= 2 &&

90 "expected the arglist to have at least two args!"

);

100

std::vector<CharUnits> VBPtrOffsets;

104 const

VBTableGlobals &VBGlobals = enumerateVBTables(RD);

105 for

(

const

std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {

110 if

(VBT->getVBaseWithVPtr())

112

VBPtrOffsets.push_back(Offs);

114

llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());

130

llvm::GlobalVariable *getMSCompleteObjectLocator(

const CXXRecordDecl

*RD,

151

llvm::Type *StdTypeInfoPtrTy)

override

;

163

llvm::BasicBlock *CastSuccess,

164

llvm::BasicBlock *CastFail)

override

{

165

llvm_unreachable(

"unsupported"

);

171

llvm::BasicBlock *CastEnd)

override

;

230

AddedStructorArgCounts

244

llvm::GlobalValue::LinkageTypes

251 auto

*MD = cast<CXXMethodDecl>(GD.

getDecl

());

253 if

(MD->isVirtual()) {

255 if

(

const auto

*DD = dyn_cast<CXXDestructorDecl>(MD)) {

259 return

MD->getParent();

277 return

MD->getParent();

283 bool

VirtualCall)

override

;

308

llvm::GlobalVariable *VTable);

314

CodeGenFunction::VPtr Vptr)

override

;

319 return

!VTableClass->

hasAttr

<MSNoVTableAttr>();

340

DeleteOrMemberCallExpr

E

,

341

llvm::CallBase **CallOrInvoke)

override

;

346 "Only deleting destructor thunks are available in this ABI"

);

353

llvm::GlobalVariable *

355

llvm::GlobalVariable::LinkageTypes

Linkage

);

357

llvm::GlobalVariable *

361

llvm::raw_svector_ostream Out(OutName);

363

StringRef MangledName = OutName.str();

365 if

(

auto

*VDispMap = CGM.

getModule

().getNamedGlobal(MangledName))

371

llvm::UndefValue::get(CGM.

IntTy

));

372

Map[0] = llvm::ConstantInt::get(CGM.

IntTy

, 0);

373 bool

AnyDifferent =

false

;

374 for

(

const auto

&I : SrcRD->

vbases

()) {

375 const CXXRecordDecl

*VBase = I.getType()->getAsCXXRecordDecl();

381

Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.

IntTy

, DstVBIndex * 4);

382

AnyDifferent |= SrcVBIndex != DstVBIndex;

388

llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.

IntTy

, Map.size());

389

llvm::Constant *

Init

= llvm::ConstantArray::get(VDispMapTy, Map);

390

llvm::GlobalValue::LinkageTypes

Linkage

=

392

? llvm::GlobalValue::LinkOnceODRLinkage

393

: llvm::GlobalValue::InternalLinkage;

394 auto

*VDispMap =

new

llvm::GlobalVariable(

401

llvm::GlobalVariable *GV)

const

;

409

Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);

411

Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);

413

Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);

433

LangOptions::MSVC2019_5) &&

441

llvm::GlobalVariable *DeclPtr,

442 bool

PerformInit)

override

;

444

llvm::FunctionCallee Dtor,

445

llvm::Constant *Addr)

override

;

476

llvm::Value *NumElements,

483 friend struct

MSRTTIBuilder;

485 bool

isImageRelative()

const

{

490

llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {

492

TDTypeName += llvm::utostr(TypeInfoString.size());

493

llvm::StructType *&TypeDescriptorType =

494

TypeDescriptorTypeMap[TypeInfoString.size()];

495 if

(TypeDescriptorType)

496 return

TypeDescriptorType;

497

llvm::Type *FieldTypes[] = {

500

llvm::ArrayType::get(CGM.

Int8Ty

, TypeInfoString.size() + 1)};

502

llvm::StructType::create(CGM.

getLLVMContext

(), FieldTypes, TDTypeName);

503 return

TypeDescriptorType;

506

llvm::Type *getImageRelativeType(llvm::Type *PtrType) {

507 if

(!isImageRelative())

512

llvm::StructType *getBaseClassDescriptorType() {

513 if

(BaseClassDescriptorType)

514 return

BaseClassDescriptorType;

515

llvm::Type *FieldTypes[] = {

524

BaseClassDescriptorType = llvm::StructType::create(

526 return

BaseClassDescriptorType;

529

llvm::StructType *getClassHierarchyDescriptorType() {

530 if

(ClassHierarchyDescriptorType)

531 return

ClassHierarchyDescriptorType;

535

ClassHierarchyDescriptorType =

536

llvm::StructType::create(FieldTypes,

"rtti.ClassHierarchyDescriptor"

);

537 return

ClassHierarchyDescriptorType;

540

llvm::StructType *getCompleteObjectLocatorType() {

541 if

(CompleteObjectLocatorType)

542 return

CompleteObjectLocatorType;

543

llvm::Type *FieldTypes[] = {

549

getImageRelativeType(CGM.

VoidTy

),

552 if

(!isImageRelative())

553

FieldTypesRef = FieldTypesRef.drop_back();

554

CompleteObjectLocatorType =

555

llvm::StructType::create(FieldTypesRef,

"rtti.CompleteObjectLocator"

);

556 return

CompleteObjectLocatorType;

559

llvm::GlobalVariable *getImageBase() {

560

StringRef Name =

"__ImageBase"

;

561 if

(llvm::GlobalVariable *GV = CGM.

getModule

().getNamedGlobal(Name))

566

llvm::GlobalValue::ExternalLinkage,

572

llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {

573 if

(!isImageRelative())

576 if

(PtrVal->isNullValue())

577 return

llvm::Constant::getNullValue(CGM.

IntTy

);

579

llvm::Constant *ImageBaseAsInt =

580

llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.

IntPtrTy

);

581

llvm::Constant *PtrValAsInt =

582

llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.

IntPtrTy

);

583

llvm::Constant *Diff =

584

llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,

586 return

llvm::ConstantExpr::getTrunc(Diff, CGM.

IntTy

);

594

llvm::Constant *getZeroInt() {

595 return

llvm::ConstantInt::get(CGM.

IntTy

, 0);

598

llvm::Constant *getAllOnesInt() {

599 return

llvm::Constant::getAllOnesValue(CGM.

IntTy

);

613

llvm::Value *VBPtrOffset,

614

llvm::Value *VBTableOffset,

615

llvm::Value **VBPtr =

nullptr

);

620

int32_t VBTableOffset,

621

llvm::Value **VBPtr =

nullptr

) {

622

assert(VBTableOffset % 4 == 0 &&

"should be byte offset into table of i32s"

);

623

llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.

IntTy

, VBPtrOffset),

624

*VBTOffset = llvm::ConstantInt::get(CGM.

IntTy

, VBTableOffset);

625 return

GetVBaseOffsetFromVBPtr(CGF,

Base

, VBPOffset, VBTOffset, VBPtr);

628

std::tuple<Address, llvm::Value *, const CXXRecordDecl *>

636

llvm::Value *VirtualBaseAdjustmentOffset,

637

llvm::Value *VBPtrOffset

);

641

llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,

642 bool

IsMemberFunction,

645 unsigned

VBTableIndex);

654 const

VBTableGlobals &enumerateVBTables(

const CXXRecordDecl

*RD);

657

llvm::Function *EmitVirtualMemPtrThunk(

const CXXMethodDecl

*MD,

670 return

RD->

hasAttr

<MSInheritanceAttr>();

684 bool

Inequality)

override

;

695

llvm::Value *EmitNonNullMemberPointerConversion(

703

llvm::Value *Src)

override

;

706

llvm::Constant *Src)

override

;

715 Address

This, llvm::Value *&ThisPtrForCall,

721

llvm::StructType *getCatchableTypeType() {

722 if

(CatchableTypeType)

723 return

CatchableTypeType;

724

llvm::Type *FieldTypes[] = {

733

CatchableTypeType = llvm::StructType::create(

735 return

CatchableTypeType;

738

llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {

739

llvm::StructType *&CatchableTypeArrayType =

740

CatchableTypeArrayTypeMap[NumEntries];

741 if

(CatchableTypeArrayType)

742 return

CatchableTypeArrayType;

745

CTATypeName += llvm::utostr(NumEntries);

746

llvm::Type *CTType = getImageRelativeType(CGM.

UnqualPtrTy

);

747

llvm::Type *FieldTypes[] = {

749

llvm::ArrayType::get(CTType, NumEntries)

751

CatchableTypeArrayType =

752

llvm::StructType::create(CGM.

getLLVMContext

(), FieldTypes, CTATypeName);

753 return

CatchableTypeArrayType;

756

llvm::StructType *getThrowInfoType() {

758 return

ThrowInfoType;

759

llvm::Type *FieldTypes[] = {

765

ThrowInfoType = llvm::StructType::create(CGM.

getLLVMContext

(), FieldTypes,

767 return

ThrowInfoType;

774

llvm::FunctionType *FTy =

775

llvm::FunctionType::get(CGM.

VoidTy

, Args,

false

);

776

llvm::FunctionCallee Throw =

780 if

(

auto

*Fn = dyn_cast<llvm::Function>(Throw.getCallee()))

781 Fn

->setCallingConv(llvm::CallingConv::X86_StdCall);

789

llvm::Constant *getCatchableType(

QualType T

,

790

uint32_t NVOffset = 0,

791

int32_t VBPtrOffset = -1,

792

uint32_t VBIndex = 0);

794

llvm::GlobalVariable *getCatchableTypeArray(

QualType T

);

798

std::pair<llvm::Value *, const CXXRecordDecl *>

806 typedef

std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;

807 typedef

llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;

808 typedef

llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;

810

VFTablesMapTy VFTablesMap;

811

VTablesMapTy VTablesMap;

818

llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;

823

GuardInfo() =

default

;

824

llvm::GlobalVariable *Guard =

nullptr

;

825 unsigned

BitIndex = 0;

830

llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;

831

llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;

832

llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;

834

llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;

835

llvm::StructType *BaseClassDescriptorType;

836

llvm::StructType *ClassHierarchyDescriptorType;

837

llvm::StructType *CompleteObjectLocatorType;

839

llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;

841

llvm::StructType *CatchableTypeType;

842

llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;

843

llvm::StructType *ThrowInfoType;

849

MicrosoftCXXABI::getRecordArgABI(

const CXXRecordDecl

*RD)

const

{

861 case

llvm::Triple::thumb:

867 case

llvm::Triple::x86: {

878 return

RAA_DirectInMemory;

881 case

llvm::Triple::x86_64:

882 case

llvm::Triple::aarch64:

886

llvm_unreachable(

"invalid enum"

);

898

llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,

904void

MicrosoftCXXABI::emitRethrow(

CodeGenFunction

&CGF,

bool

isNoReturn) {

905

llvm::Value *Args[] = {llvm::ConstantPointerNull::get(CGM.

Int8PtrTy

),

906

llvm::ConstantPointerNull::get(CGM.

UnqualPtrTy

)};

918 VarDecl

*CatchParam = S->getExceptionDecl();

919

llvm::BasicBlock *CatchPadBB = CGF.

Builder

.GetInsertBlock();

920

llvm::CatchPadInst *CPI =

921

cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHIIt());

932

CPI->setArgOperand(2,

var

.getObjectAddress(CGF).emitRawPointer(CGF));

940

std::tuple<Address, llvm::Value *, const CXXRecordDecl *>

951 return

std::make_tuple(

Value

, llvm::ConstantInt::get(CGF.

Int32Ty

, 0),

960

PolymorphicBase = BaseDecl;

964

assert(PolymorphicBase &&

"polymorphic class has no apparent vfptr?"

);

966

llvm::Value *Offset =

967

GetVirtualBaseClassOffset(CGF,

Value

, SrcDecl, PolymorphicBase);

969 Value

.getElementType(),

Value

.emitRawPointer(CGF), Offset);

972 return

std::make_tuple(

Address

(Ptr, CGF.

Int8Ty

, VBaseAlign), Offset,

976bool

MicrosoftCXXABI::shouldTypeidBeNullChecked(

QualType

SrcRecordTy) {

978 return

!getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();

982

llvm::Value *Argument) {

983

llvm::Type *ArgTypes[] = {CGF.

Int8PtrTy

};

984

llvm::FunctionType *FTy =

985

llvm::FunctionType::get(CGF.

Int8PtrTy

, ArgTypes,

false

);

986

llvm::Value *Args[] = {Argument};

992

llvm::CallBase *

Call

=

994 Call

->setDoesNotReturn();

995

CGF.

Builder

.CreateUnreachable();

1001

llvm::Type *StdTypeInfoPtrTy) {

1002

std::tie(ThisPtr, std::ignore, std::ignore) =

1003

performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);

1005 return

CGF.

Builder

.CreateBitCast(Typeid, StdTypeInfoPtrTy);

1008bool

MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(

bool

SrcIsPtr,

1012

!getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();

1015

llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(

1017 QualType

DestRecordTy, llvm::BasicBlock *CastEnd) {

1018

llvm::Value *SrcRTTI =

1020

llvm::Value *DestRTTI =

1023

llvm::Value *Offset;

1024

std::tie(This, Offset, std::ignore) =

1025

performBaseAdjustment(CGF, This, SrcRecordTy);

1026

llvm::Value *ThisPtr =

This

.emitRawPointer(CGF);

1038

llvm::FunctionType::get(CGF.

Int8PtrTy

, ArgTypes,

false

),

1039 "__RTDynamicCast"

);

1040

llvm::Value *Args[] = {

1041

ThisPtr, Offset, SrcRTTI, DestRTTI,

1046

llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(

CodeGenFunction

&CGF,

1049

std::tie(

Value

, std::ignore, std::ignore) =

1050

performBaseAdjustment(CGF,

Value

, SrcRecordTy);

1054

llvm::Type *ArgTypes[] = {CGF.

Int8PtrTy

};

1056

llvm::FunctionType::get(CGF.

Int8PtrTy

, ArgTypes,

false

),

1058

llvm::Value *Args[] = {

Value

.emitRawPointer(CGF)};

1066

llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(

1072

llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.

PtrDiffTy

, VBPtrChars);

1077

llvm::Value *VBTableOffset =

1080

llvm::Value *VBPtrToNewBase =

1081

GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);

1084 return

CGF.

Builder

.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);

1087bool

MicrosoftCXXABI::HasThisReturn(

GlobalDecl

GD)

const

{

1088 return

isa<CXXConstructorDecl>(GD.

getDecl

());

1092 return

isa<CXXDestructorDecl>(GD.

getDecl

()) &&

1096bool

MicrosoftCXXABI::hasMostDerivedReturn(

GlobalDecl

GD)

const

{

1106

uint64_t NumElts = 0;

1109

isa<VectorType>(

Base

)) {

1146 if

(

auto

*Ctor = dyn_cast<CXXConstructorDecl>(

D

)) {

1147 if

(Ctor->isUserProvided())

1149

}

else if

(

auto

*Template = dyn_cast<FunctionTemplateDecl>(

D

)) {

1150 if

(isa<CXXConstructorDecl>(Template->getTemplatedDecl()))

1152

}

else if

(

auto

*MethodDecl = dyn_cast<CXXMethodDecl>(

D

)) {

1153 if

(MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())

1162bool

MicrosoftCXXABI::classifyReturnType(

CGFunctionInfo

&FI)

const

{

1173 if

(isIndirectReturn) {

1194

llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);

1195

assert(IsMostDerivedClass &&

1196 "ctor for a class with virtual bases must have an implicit parameter"

);

1197

llvm::Value *IsCompleteObject =

1198

CGF.

Builder

.CreateIsNotNull(IsMostDerivedClass,

"is_complete_object"

);

1200

llvm::BasicBlock *CallVbaseCtorsBB = CGF.

createBasicBlock

(

"ctor.init_vbases"

);

1201

llvm::BasicBlock *SkipVbaseCtorsBB = CGF.

createBasicBlock

(

"ctor.skip_vbases"

);

1202

CGF.

Builder

.CreateCondBr(IsCompleteObject,

1203

CallVbaseCtorsBB, SkipVbaseCtorsBB);

1208

EmitVBPtrStores(CGF, RD);

1212 return

SkipVbaseCtorsBB;

1216

MicrosoftCXXABI::EmitDtorCompleteObjectHandler(

CodeGenFunction

&CGF) {

1217

llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);

1218

assert(IsMostDerivedClass &&

1219 "ctor for a class with virtual bases must have an implicit parameter"

);

1220

llvm::Value *IsCompleteObject =

1221

CGF.

Builder

.CreateIsNotNull(IsMostDerivedClass,

"is_complete_object"

);

1223

llvm::BasicBlock *CallVbaseDtorsBB = CGF.

createBasicBlock

(

"Dtor.dtor_vbases"

);

1224

llvm::BasicBlock *SkipVbaseDtorsBB = CGF.

createBasicBlock

(

"Dtor.skip_vbases"

);

1225

CGF.

Builder

.CreateCondBr(IsCompleteObject,

1226

CallVbaseDtorsBB, SkipVbaseDtorsBB);

1231 return

SkipVbaseDtorsBB;

1234void

MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(

1254

llvm::Value *Int8This =

nullptr

;

1257 const CXXRecordDecl

*VBase = S.getType()->getAsCXXRecordDecl();

1258 auto

I = VBaseMap.find(VBase);

1259

assert(I != VBaseMap.end());

1260 if

(!I->second.hasVtorDisp())

1263

llvm::Value *VBaseOffset =

1264

GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);

1265 uint64_t

ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();

1268

llvm::Value *VtorDispValue = Builder.CreateSub(

1269

VBaseOffset, llvm::ConstantInt::get(CGM.

PtrDiffTy

, ConstantVBaseOffset),

1271

VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.

Int32Ty

);

1274

Int8This = getThisValue(CGF);

1276

llvm::Value *VtorDispPtr =

1277

Builder.CreateInBoundsGEP(CGF.

Int8Ty

, Int8This, VBaseOffset);

1279

VtorDispPtr = Builder.CreateConstGEP1_32(CGF.

Int8Ty

, VtorDispPtr, -4);

1281

Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,

1292 return

ExpectedCallingConv == ActualCallingConv;

1303 if

(

D

->

hasAttr

<DLLExportAttr>() &&

D

->isDefaultConstructor() &&

1307 Fn

->setLinkage(llvm::GlobalValue::WeakODRLinkage);

1320 const

VBTableGlobals &VBGlobals = enumerateVBTables(RD);

1321 for

(

unsigned

I = 0,

E

= VBGlobals.VBTables->size(); I !=

E

; ++I) {

1322 const

std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];

1323

llvm::GlobalVariable *GV = VBGlobals.Globals[I];

1328 if

(VBT->getVBaseWithVPtr())

1331

llvm::Value *GVPtr =

1339

MicrosoftCXXABI::buildStructorSignature(

GlobalDecl

GD,

1341

AddedStructorArgCounts Added;

1343 if

(isa<CXXDestructorDecl>(GD.

getDecl

()) &&

1346

ArgTys.push_back(getContext().IntTy);

1349 auto

*CD = dyn_cast<CXXConstructorDecl>(GD.

getDecl

());

1358 if

(

Class

->getNumVBases()) {

1360

ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);

1363

ArgTys.push_back(getContext().IntTy);

1371void

MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,

1377

GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);

1384

llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(

1389 return

llvm::GlobalValue::InternalLinkage;

1400 if

(Dtor->

hasAttr

<DLLExportAttr>())

1401 return

llvm::GlobalValue::WeakODRLinkage;

1402 if

(Dtor->

hasAttr

<DLLImportAttr>())

1403 return

llvm::GlobalValue::AvailableExternallyLinkage;

1404 return

llvm::GlobalValue::LinkOnceODRLinkage;

1409 return

llvm::GlobalValue::LinkOnceODRLinkage;

1411

llvm_unreachable(

"MS C++ ABI does not support comdat dtors"

);

1413

llvm_unreachable(

"invalid dtor type"

);

1425 if

(

D

->getParent()->getNumVBases() > 0 &&

D

->

hasAttr

<DLLExportAttr>())

1430

MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(

GlobalDecl

GD) {

1452 if

(isa<CXXDestructorDecl>(MD))

1457

getContext().getASTRecordLayout(MD->

getParent

());

1464Address

MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(

1470 CharUnits

Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);

1471 if

(Adjustment.

isZero

())

1505

Result = Result.withElementType(CGF.

Int8Ty

);

1509

llvm::Value *VBaseOffset =

1510

GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);

1512

Result.getElementType(), Result.emitRawPointer(CGF), VBaseOffset);

1517 if

(!StaticOffset.

isZero

()) {

1519

Result = Result.withElementType(CGF.

Int8Ty

);

1538

assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));

1543

ImplicitParamKind::Other);

1548

Params.insert(Params.begin() + 1, IsMostDerived);

1550

Params.push_back(IsMostDerived);

1551

getStructorImplicitParamDecl(CGF) = IsMostDerived;

1555

&Context.

Idents

.

get

(

"should_call_delete"

), Context.

IntTy

,

1556

ImplicitParamKind::Other);

1557

Params.push_back(ShouldDelete);

1558

getStructorImplicitParamDecl(CGF) = ShouldDelete;

1562void

MicrosoftCXXABI::EmitInstanceFunctionProlog(

CodeGenFunction

&CGF) {

1579

llvm::Value *

This

= loadIncomingCXXThis(CGF);

1582 CharUnits

Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.

CurGD

);

1583 if

(!Adjustment.

isZero

()) {

1589

setCXXABIThisValue(CGF, This);

1599 if

(HasThisReturn(CGF.

CurGD

) || hasMostDerivedReturn(CGF.

CurGD

))

1603

assert(getStructorImplicitParamDecl(CGF) &&

1604 "no implicit parameter for a constructor with virtual bases?"

);

1605

getStructorImplicitParamValue(CGF)

1608 "is_most_derived"

);

1612

assert(getStructorImplicitParamDecl(CGF) &&

1613 "no implicit parameter for a deleting destructor?"

);

1614

getStructorImplicitParamValue(CGF)

1617 "should_call_delete"

);

1627 if

(!

D

->getParent()->getNumVBases())

1628 return

AddedStructorArgs{};

1632

llvm::Value *MostDerivedArg;

1634

MostDerivedArg = getStructorImplicitParamValue(CGF);

1639 return

AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});

1641 return

AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});

1644

llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(

1665

assert(

Type

!= CXXDtorType::Dtor_Deleting &&

1666 "The deleting destructor should only be called via a virtual call"

);

1671

llvm::BasicBlock *BaseDtorEndBB =

nullptr

;

1672 if

(ForVirtualBase && isa<CXXConstructorDecl>(CGF.

CurCodeDecl

)) {

1673

BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);

1683 if

(BaseDtorEndBB) {

1685

CGF.

Builder

.CreateBr(BaseDtorEndBB);

1690void

MicrosoftCXXABI::emitVTableTypeMetadata(

const VPtrInfo

&Info,

1692

llvm::GlobalVariable *VTable) {

1703

llvm::DenseSet<const CXXRecordDecl *>

Visited

;

1704

llvm::GlobalObject::VCallVisibility TypeVis =

1706 if

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

1707

VTable->setVCallVisibilityMetadata(TypeVis);

1714

getContext().getLangOpts().RTTIData

1715

? getContext().toCharUnitsFromBits(

1716

getContext().getTargetInfo().getPointerWidth(LangAS::Default))

1735

getContext().getASTRecordLayout(DerivedRD);

1741

Offset = VBI->second.VBaseOffset;

1742 if

(!Offset.isZero())

1752void

MicrosoftCXXABI::emitVTableDefinitions(

CodeGenVTables

&CGVT,

1757 for

(

const

std::unique_ptr<VPtrInfo>& Info : VFPtrs) {

1758

llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->

FullOffsetInMDC

);

1759 if

(VTable->hasInitializer())

1765

llvm::Constant *RTTI =

nullptr

;

1768

RTTI = getMSCompleteObjectLocator(RD, *Info);

1771 auto

components = builder.beginStruct();

1773

VTable->hasLocalLinkage());

1774

components.finishAndSetAsInitializer(VTable);

1776

emitVTableTypeMetadata(*Info, RD, VTable);

1780bool

MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(

1782 return

Vptr.NearestVBase !=

nullptr

;

1785

llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(

1788

llvm::Constant *VTableAddressPoint = getVTableAddressPoint(

Base

, VTableClass);

1789 if

(!VTableAddressPoint) {

1790

assert(

Base

.getBase()->getNumVBases() &&

1791

!getContext().getASTRecordLayout(

Base

.getBase()).hasOwnVFPtr());

1793 return

VTableAddressPoint;

1799

llvm::raw_svector_ostream Out(Name);

1806

(void)getAddrOfVTable(VTableClass,

Base

.getBaseOffset());

1807

VFTableIdTy

ID

(VTableClass,

Base

.getBaseOffset());

1808 return

VFTablesMap[

ID

];

1811

llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(

const CXXRecordDecl

*RD,

1817

VFTableIdTy

ID

(RD, VPtrOffset);

1818

VTablesMapTy::iterator I;

1820

std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,

nullptr

));

1824

llvm::GlobalVariable *&VTable = I->second;

1829 if

(DeferredVFTables.insert(RD).second) {

1837

llvm::StringSet<> ObservedMangledNames;

1838 for

(

size_t

J = 0, F = VFPtrs.size(); J != F; ++J) {

1841 if

(!ObservedMangledNames.insert(Name.str()).second)

1842

llvm_unreachable(

"Already saw this mangling before?"

);

1847 const

std::unique_ptr<VPtrInfo> *VFPtrI =

1848

llvm::find_if(VFPtrs, [&](

const

std::unique_ptr<VPtrInfo> &VPI) {

1849 return

VPI->FullOffsetInMDC == VPtrOffset;

1851 if

(VFPtrI == VFPtrs.end()) {

1852

VFTablesMap[

ID

] =

nullptr

;

1855 const

std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;

1867

llvm::GlobalValue::LinkageTypes VFTableLinkage =

1868

RD->

hasAttr

<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage

1870 bool

VFTableComesFromAnotherTU =

1871

llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||

1872

llvm::GlobalValue::isExternalLinkage(VFTableLinkage);

1873 bool

VTableAliasIsRequred =

1874

!VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;

1876 if

(llvm::GlobalValue *VFTable =

1877

CGM.

getModule

().getNamedGlobal(VFTableName)) {

1878

VFTablesMap[

ID

] = VFTable;

1879

VTable = VTableAliasIsRequred

1880

? cast<llvm::GlobalVariable>(

1881

cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())

1882

:

cast

<

llvm

::GlobalVariable>(VFTable);

1888

llvm::GlobalValue::LinkageTypes VTableLinkage =

1889

VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;

1891

StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();

1897

llvm::GlobalValue *VFTable;

1898

VTable =

new

llvm::GlobalVariable(CGM.

getModule

(), VTableType,

1899 true

, VTableLinkage,

1900 nullptr

, VTableName);

1901

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

1903

llvm::Comdat *

C

=

nullptr

;

1904 if

(!VFTableComesFromAnotherTU &&

1905

llvm::GlobalValue::isWeakForLinker(VFTableLinkage))

1906 C

= CGM.

getModule

().getOrInsertComdat(VFTableName.str());

1911 if

(VTableAliasIsRequred) {

1912

llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.

Int32Ty

, 0),

1913

llvm::ConstantInt::get(CGM.

Int32Ty

, 0),

1914

llvm::ConstantInt::get(CGM.

Int32Ty

, 1)};

1917

llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(

1918

VTable->getValueType(), VTable, GEPIndices);

1919 if

(llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {

1920

VFTableLinkage = llvm::GlobalValue::ExternalLinkage;

1922 C

->setSelectionKind(llvm::Comdat::Largest);

1924

VFTable = llvm::GlobalAlias::create(CGM.

Int8PtrTy

,

1926

VFTableName.str(), VTableGEP,

1928

VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

1937

VTable->setComdat(

C

);

1939 if

(RD->

hasAttr

<DLLExportAttr>())

1940

VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);

1942

VFTablesMap[

ID

] = VFTable;

1955

adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,

true

);

1957 auto

*MethodDecl = cast<CXXMethodDecl>(GD.

getDecl

());

1958

llvm::Value *VTable =

1966 auto

getObjectWithVPtr = [&] {

1969

[&](

const

std::unique_ptr<VPtrInfo> &Info) {

1970

return Info->FullOffsetInMDC == ML.VFPtrOffset;

1979

getObjectWithVPtr(), VTable, Ty,

1987

llvm::Value *VFuncPtr =

1988

Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.

Index

,

"vfn"

);

1989

VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.

getPointerAlign

());

1996

llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(

1998 Address

This, DeleteOrMemberCallExpr

E

, llvm::CallBase **CallOrInvoke) {

1999 auto

*CE = dyn_cast<const CXXMemberCallExpr *>(

E

);

2000 auto

*

D

= dyn_cast<const CXXDeleteExpr *>(

E

);

2001

assert((CE !=

nullptr

) ^ (

D

!=

nullptr

));

2002

assert(CE ==

nullptr

|| CE->arg_begin() == CE->arg_end());

2014

llvm::Value *ImplicitParam = llvm::ConstantInt::get(

2020

ThisTy = CE->getObjectType();

2022

ThisTy =

D

->getDestroyedType();

2025 This

= adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,

true

);

2028

ImplicitParam, Context.

IntTy

, CE, CallOrInvoke);

2032const

VBTableGlobals &

2033

MicrosoftCXXABI::enumerateVBTables(

const CXXRecordDecl

*RD) {

2036

llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;

2038

std::tie(Entry, Added) =

2039

VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));

2040

VBTableGlobals &VBGlobals = Entry->second;

2045

VBGlobals.VBTables = &Context.enumerateVBTables(RD);

2050 for

(VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),

2051 E

= VBGlobals.VBTables->end();

2053

VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,

Linkage

));

2060

MicrosoftCXXABI::EmitVirtualMemPtrThunk(

const CXXMethodDecl

*MD,

2062

assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&

2063 "can't form pointers to ctors or virtual dtors"

);

2067

llvm::raw_svector_ostream Out(ThunkName);

2068

getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);

2071 if

(llvm::GlobalValue *GV = CGM.

getModule

().getNamedValue(ThunkName))

2072 return

cast<llvm::Function>(GV);

2078

llvm::Function *ThunkFn =

2079

llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,

2081

assert(ThunkFn->getName() == ThunkName &&

"name was uniqued!"

);

2084

? llvm::GlobalValue::LinkOnceODRLinkage

2085

: llvm::GlobalValue::InternalLinkage);

2087

ThunkFn->setComdat(CGM.

getModule

().getOrInsertComdat(ThunkFn->getName()));

2096

ThunkFn->addFnAttr(

"thunk"

);

2099

ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);

2109

buildThisParam(CGF, FunctionArgs);

2116

setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));

2121

llvm::Value *VTable =

2124

llvm::Value *VFuncPtr = CGF.

Builder

.CreateConstInBoundsGEP1_64(

2125

ThunkPtrTy, VTable, ML.

Index

,

"vfn"

);

2134void

MicrosoftCXXABI::emitVirtualInheritanceTables(

const CXXRecordDecl

*RD) {

2135 const

VBTableGlobals &VBGlobals = enumerateVBTables(RD);

2136 for

(

unsigned

I = 0,

E

= VBGlobals.VBTables->size(); I !=

E

; ++I) {

2137 const

std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];

2138

llvm::GlobalVariable *GV = VBGlobals.Globals[I];

2139 if

(GV->isDeclaration())

2140

emitVBTableDefinition(*VBT, RD, GV);

2144

llvm::GlobalVariable *

2146

llvm::GlobalVariable::LinkageTypes

Linkage

) {

2148

llvm::raw_svector_ostream Out(OutName);

2149

getMangleContext().mangleCXXVBTable(RD, VBT.

MangledPath

, Out);

2150

StringRef Name = OutName.str();

2152

llvm::ArrayType *VBTableType =

2155

assert(!CGM.

getModule

().getNamedGlobal(Name) &&

2156 "vbtable with this name already exists: mangling bug?"

);

2161

GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

2163 if

(RD->

hasAttr

<DLLImportAttr>())

2164

GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);

2165 else if

(RD->

hasAttr

<DLLExportAttr>())

2166

GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);

2168 if

(!GV->hasExternalLinkage())

2169

emitVBTableDefinition(VBT, RD, GV);

2174void

MicrosoftCXXABI::emitVBTableDefinition(

const VPtrInfo

&VBT,

2176

llvm::GlobalVariable *GV)

const

{

2180 "should only emit vbtables for classes with vbtables"

);

2184 const ASTRecordLayout

&DerivedLayout = getContext().getASTRecordLayout(RD);

2191

Offsets[0] = llvm::ConstantInt::get(CGM.

IntTy

, -VBPtrOffset.

getQuantity

());

2194 for

(

const auto

&I : ObjectWithVPtr->

vbases

()) {

2195 const CXXRecordDecl

*VBase = I.getType()->getAsCXXRecordDecl();

2197

assert(!Offset.isNegative());

2202

CompleteVBPtrOffset +=

2204

Offset -= CompleteVBPtrOffset;

2206 unsigned

VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);

2207

assert(Offsets[VBIndex] ==

nullptr

&&

"The same vbindex seen twice?"

);

2208

Offsets[VBIndex] = llvm::ConstantInt::get(CGM.

IntTy

, Offset.getQuantity());

2211

assert(Offsets.size() ==

2212

cast<llvm::ArrayType>(GV->getValueType())->getNumElements());

2213

llvm::ArrayType *VBTableType =

2214

llvm::ArrayType::get(CGM.

IntTy

, Offsets.size());

2215

llvm::Constant *

Init

= llvm::ConstantArray::get(VBTableType, Offsets);

2216

GV->setInitializer(

Init

);

2218 if

(RD->

hasAttr

<DLLImportAttr>())

2219

GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);

2222

llvm::Value *MicrosoftCXXABI::performThisAdjustment(

2227 return This

.emitRawPointer(CGF);

2233 V

=

This

.emitRawPointer(CGF);

2243

CGF.

Builder

.CreateNeg(VtorDisp));

2256

llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(

2275

llvm::Value *MicrosoftCXXABI::performReturnAdjustment(

2280 return Ret

.emitRawPointer(CGF);

2284

llvm::Value *

V

=

Ret

.emitRawPointer(CGF);

2289

llvm::Value *VBaseOffset =

2308bool

MicrosoftCXXABI::requiresArrayCookie(

const CXXNewExpr

*

expr

) {

2311 return expr

->getAllocatedType().isDestructedType();

2322

llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(

CodeGenFunction

&CGF,

2331

llvm::Value *numElements,

2334

assert(requiresArrayCookie(

expr

));

2337 CharUnits

cookieSize = getArrayCookieSizeImpl(elementType);

2352

llvm::FunctionCallee Dtor,

2353

llvm::Constant *Addr) {

2358

llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(

2359

CGF.

IntTy

, DtorStub->getType(),

false

);

2362

TLRegDtorTy,

"__tlregdtor"

, llvm::AttributeList(),

true

);

2363 if

(llvm::Function *TLRegDtorFn =

2364

dyn_cast<llvm::Function>(TLRegDtor.getCallee()))

2365

TLRegDtorFn->setDoesNotThrow();

2371

llvm::FunctionCallee Dtor,

2372

llvm::Constant *Addr) {

2376 if

(

D

.getTLSKind())

2387void

MicrosoftCXXABI::EmitThreadLocalInitFuncs(

2391 if

(CXXThreadLocalInits.empty())

2396

?

"/include:___dyn_tls_init@12" 2397

:

"/include:__dyn_tls_init"

);

2402 auto

AddToXDU = [&CGM](llvm::Function *InitFunc) {

2403

llvm::GlobalVariable *InitFuncPtr =

new

llvm::GlobalVariable(

2404

CGM.

getModule

(), InitFunc->getType(),

true

,

2405

llvm::GlobalVariable::InternalLinkage, InitFunc,

2406

Twine(InitFunc->getName(),

"$initializer$"

));

2407

InitFuncPtr->setSection(

".CRT$XDU"

);

2414

std::vector<llvm::Function *> NonComdatInits;

2415 for

(

size_t

I = 0,

E

= CXXThreadLocalInitVars.size(); I !=

E

; ++I) {

2416

llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(

2418

llvm::Function *F = CXXThreadLocalInits[I];

2421 if

(llvm::Comdat *

C

= GV->getComdat())

2422

AddToXDU(F)->setComdat(

C

);

2424

NonComdatInits.push_back(F);

2427 if

(!NonComdatInits.empty()) {

2428

llvm::FunctionType *FTy =

2429

llvm::FunctionType::get(CGM.

VoidTy

,

false

);

2445

llvm::Constant *TlsGuardConstant =

2447

llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);

2449

TlsGuard->setThreadLocal(

true

);

2457

llvm::FunctionType *FTy =

2458

llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.

getLLVMContext

()), {},

2461

FTy,

"__dyn_tls_on_demand_init"

,

2463

llvm::AttributeList::FunctionIndex,

2464

llvm::Attribute::NoUnwind),

2469

llvm::BasicBlock *DynInitBB,

2470

llvm::BasicBlock *ContinueBB) {

2471

llvm::LoadInst *TlsGuardValue =

2473

llvm::Value *CmpResult =

2474

CGF.

Builder

.CreateICmpEQ(TlsGuardValue, CGF.

Builder

.getInt8(0));

2475

CGF.

Builder

.CreateCondBr(CmpResult, DynInitBB, ContinueBB);

2479

llvm::GlobalValue *TlsGuard,

2480

llvm::BasicBlock *ContinueBB) {

2482

llvm::Function *InitializerFunction =

2484

llvm::CallInst *CallVal = CGF.

Builder

.CreateCall(InitializerFunction);

2485

CallVal->setCallingConv(InitializerFunction->getCallingConv());

2487

CGF.

Builder

.CreateBr(ContinueBB);

2491

llvm::BasicBlock *DynInitBB =

2493

llvm::BasicBlock *ContinueBB =

2499

CGF.

Builder

.SetInsertPoint(DynInitBB);

2501

CGF.

Builder

.SetInsertPoint(ContinueBB);

2520 Address

Addr(

V

, RealVarTy, Alignment);

2524

AlignmentSource::Decl)

2530

StringRef VarName(

"_Init_thread_epoch"

);

2532 if

(

auto

*GV = CGM.

getModule

().getNamedGlobal(VarName))

2534 auto

*GV =

new

llvm::GlobalVariable(

2536 false

, llvm::GlobalVariable::ExternalLinkage,

2538 nullptr

, llvm::GlobalVariable::GeneralDynamicTLSModel);

2544

llvm::FunctionType *FTy =

2545

llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.

getLLVMContext

()),

2548

FTy,

"_Init_thread_header"

,

2550

llvm::AttributeList::FunctionIndex,

2551

llvm::Attribute::NoUnwind),

2556

llvm::FunctionType *FTy =

2557

llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.

getLLVMContext

()),

2560

FTy,

"_Init_thread_footer"

,

2562

llvm::AttributeList::FunctionIndex,

2563

llvm::Attribute::NoUnwind),

2568

llvm::FunctionType *FTy =

2569

llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.

getLLVMContext

()),

2572

FTy,

"_Init_thread_abort"

,

2574

llvm::AttributeList::FunctionIndex,

2575

llvm::Attribute::NoUnwind),

2583

ResetGuardBit(

Address

Guard,

unsigned

GuardNum)

2584

: Guard(Guard), GuardNum(GuardNum) {}

2590

llvm::LoadInst *LI = Builder.CreateLoad(Guard);

2591

llvm::ConstantInt *Mask =

2592

llvm::ConstantInt::get(CGF.

IntTy

, ~(1ULL << GuardNum));

2593

Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);

2599

CallInitThreadAbort(

RawAddress

Guard) : Guard(Guard.getPointer()) {}

2609

llvm::GlobalVariable *GV,

2612 if

(!

D

.isStaticLocal()) {

2613

assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());

2615

llvm::Function *F = CGF.

CurFn

;

2616

F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);

2617

F->setComdat(CGM.

getModule

().getOrInsertComdat(F->getName()));

2622 bool

ThreadlocalStatic =

D

.getTLSKind();

2623 bool

ThreadsafeStatic = getContext().

getLangOpts

().ThreadsafeStatics;

2627 bool

HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;

2630

llvm::IntegerType *GuardTy = CGF.

Int32Ty

;

2631

llvm::ConstantInt *

Zero

= llvm::ConstantInt::get(GuardTy, 0);

2635

GuardInfo *GI =

nullptr

;

2636 if

(ThreadlocalStatic)

2638 else if

(!ThreadsafeStatic)

2641

llvm::GlobalVariable *GuardVar = GI ? GI->Guard :

nullptr

;

2643 if

(

D

.isExternallyVisible()) {

2646

GuardNum = getContext().getStaticLocalNumber(&

D

);

2647

assert(GuardNum > 0);

2649

}

else if

(HasPerVariableGuard) {

2653

GuardNum = GI->BitIndex++;

2656 if

(!HasPerVariableGuard && GuardNum >= 32) {

2657 if

(

D

.isExternallyVisible())

2658

ErrorUnsupportedABI(CGF,

"more than 32 guarded initializations"

);

2660

GuardVar =

nullptr

;

2667

llvm::raw_svector_ostream Out(GuardName);

2668 if

(HasPerVariableGuard)

2669

getMangleContext().mangleThreadSafeStaticGuardVariable(&

D

, GuardNum,

2672

getMangleContext().mangleStaticGuardVariable(&

D

, Out);

2678 new

llvm::GlobalVariable(CGM.

getModule

(), GuardTy,

false

,

2679

GV->getLinkage(), Zero, GuardName.str());

2680

GuardVar->setVisibility(GV->getVisibility());

2681

GuardVar->setDLLStorageClass(GV->getDLLStorageClass());

2682

GuardVar->setAlignment(GuardAlign.

getAsAlign

());

2683 if

(GuardVar->isWeakForLinker())

2684

GuardVar->setComdat(

2685

CGM.

getModule

().getOrInsertComdat(GuardVar->getName()));

2686 if

(

D

.getTLSKind())

2688 if

(GI && !HasPerVariableGuard)

2689

GI->Guard = GuardVar;

2694

assert(GuardVar->getLinkage() == GV->getLinkage() &&

2695 "static local from the same function had different linkage"

);

2697 if

(!HasPerVariableGuard) {

2705

llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);

2706

llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);

2707

llvm::Value *NeedsInit =

2708

Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);

2712

CodeGenFunction::GuardKind::VariableGuard, &

D

);

2717

Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);

2718

CGF.

EHStack

.pushCleanup<ResetGuardBit>(

EHCleanup

, GuardAddr, GuardNum);

2721

Builder.CreateBr(EndBlock);

2739

llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);

2740

FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);

2741

llvm::LoadInst *InitThreadEpoch =

2743

llvm::Value *IsUninitialized =

2744

Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);

2745

llvm::BasicBlock *AttemptInitBlock = CGF.

createBasicBlock

(

"init.attempt"

);

2748

CodeGenFunction::GuardKind::VariableGuard, &

D

);

2754

GuardAddr.getPointer());

2755

llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);

2756

SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);

2757

llvm::Value *ShouldDoInit =

2758

Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());

2760

Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);

2768

GuardAddr.getPointer());

2769

Builder.CreateBr(EndBlock);

2798

fields.push_back(CGM.

IntTy

);

2802

fields.push_back(CGM.

IntTy

);

2804

fields.push_back(CGM.

IntTy

);

2806

fields.push_back(CGM.

IntTy

);

2808 if

(fields.size() == 1)

2813void

MicrosoftCXXABI::

2816

assert(fields.empty());

2821

fields.push_back(llvm::Constant::getNullValue(CGM.

VoidPtrTy

));

2824

fields.push_back(getZeroInt());

2826

fields.push_back(getAllOnesInt());

2831

fields.push_back(getZeroInt());

2833

fields.push_back(getZeroInt());

2835

fields.push_back(getAllOnesInt());

2841

GetNullMemberPointerFields(MPT, fields);

2842 if

(fields.size() == 1)

2844

llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);

2845

assert(Res->getType() == ConvertMemberPointerType(MPT));

2850

MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,

2851 bool

IsMemberFunction,

2854 unsigned

VBTableIndex) {

2863

fields.push_back(FirstField);

2866

fields.push_back(llvm::ConstantInt::get(

2872

Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();

2873

fields.push_back(llvm::ConstantInt::get(CGM.

IntTy

, Offs.

getQuantity

()));

2878

fields.push_back(llvm::ConstantInt::get(CGM.

IntTy

, VBTableIndex));

2880 return

llvm::ConstantStruct::getAnon(fields);

2889

llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(

const CXXRecordDecl

*RD,

2892

MSInheritanceModel::Virtual)

2893

offset -= getContext().getOffsetOfBaseWithVBPtr(RD);

2894

llvm::Constant *FirstField =

2896 return

EmitFullMemberPointer(FirstField,

false

, RD,

2900

llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(

const APValue

&MP,

2905 return

EmitNullMemberPointer(DstTy);

2910

llvm::Constant *

C

;

2911 if

(

const CXXMethodDecl

*MD = dyn_cast<CXXMethodDecl>(MPD)) {

2912 C

= EmitMemberFunctionPointer(MD);

2919 const FieldDecl

*FD = dyn_cast<FieldDecl>(MPD);

2921

FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());

2924 C

= EmitMemberDataPointer(RD, FieldOffset);

2927 if

(!MemberPointerPath.empty()) {

2928 const CXXRecordDecl

*SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());

2940 if

(DerivedMember) {

2948 if

(BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==

2949 Base

->getCanonicalDecl())

2950

DerivedToBasePath.push_back(&BS);

2953

assert(DerivedToBasePath.size() == MemberPointerPath.size());

2955 CastKind

CK = DerivedMember ? CK_DerivedToBaseMemberPointer

2956

: CK_BaseToDerivedMemberPointer;

2957 C

= EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),

2958

DerivedToBasePath.end(),

C

);

2964

MicrosoftCXXABI::EmitMemberFunctionPointer(

const CXXMethodDecl

*MD) {

2965

assert(MD->

isInstance

() &&

"Member function must not be static!"

);

2971 unsigned

VBTableIndex = 0;

2972

llvm::Constant *FirstField;

2977 if

(Types.isFuncTypeConvertible(FPT)) {

2979

Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));

2989

FirstField = EmitVirtualMemPtrThunk(MD, ML);

2993

VBTableIndex = VTableContext.getVBTableIndex(RD, ML.

VBase

) * 4;

2996 if

(VBTableIndex == 0 &&

2998

MSInheritanceModel::Virtual)

2999

NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);

3002 return

EmitFullMemberPointer(FirstField,

true

, RD,

3003

NonVirtualBaseAdjustment, VBTableIndex);

3018

llvm::ICmpInst::Predicate

Eq

;

3019

llvm::Instruction::BinaryOps

And

,

Or

;

3021 Eq

= llvm::ICmpInst::ICMP_NE;

3022 And

= llvm::Instruction::Or;

3023 Or

= llvm::Instruction::And;

3025 Eq

= llvm::ICmpInst::ICMP_EQ;

3026 And

= llvm::Instruction::And;

3027 Or

= llvm::Instruction::Or;

3036 return

Builder.CreateICmp(

Eq

, L, R);

3039

llvm::Value *L0 = Builder.CreateExtractValue(L, 0,

"lhs.0"

);

3040

llvm::Value *R0 = Builder.CreateExtractValue(R, 0,

"rhs.0"

);

3041

llvm::Value *Cmp0 = Builder.CreateICmp(

Eq

, L0, R0,

"memptr.cmp.first"

);

3044

llvm::Value *Res =

nullptr

;

3045

llvm::StructType *LType = cast<llvm::StructType>(L->getType());

3046 for

(

unsigned

I = 1,

E

= LType->getNumElements(); I !=

E

; ++I) {

3047

llvm::Value *LF = Builder.CreateExtractValue(L, I);

3048

llvm::Value *RF = Builder.CreateExtractValue(R, I);

3049

llvm::Value *Cmp = Builder.CreateICmp(

Eq

, LF, RF,

"memptr.cmp.rest"

);

3051

Res = Builder.CreateBinOp(

And

, Res, Cmp);

3059

llvm::Value *

Zero

= llvm::Constant::getNullValue(L0->getType());

3060

llvm::Value *IsZero = Builder.CreateICmp(

Eq

, L0, Zero,

"memptr.cmp.iszero"

);

3061

Res = Builder.CreateBinOp(

Or

, Res, IsZero);

3066 return

Builder.CreateBinOp(

And

, Res, Cmp0,

"memptr.cmp"

);

3071

llvm::Value *MemPtr,

3077

fields.push_back(llvm::Constant::getNullValue(CGM.

VoidPtrTy

));

3079

GetNullMemberPointerFields(MPT, fields);

3080

assert(!fields.empty());

3081

llvm::Value *FirstField = MemPtr;

3082 if

(MemPtr->getType()->isStructTy())

3083

FirstField = Builder.CreateExtractValue(MemPtr, 0);

3084

llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],

"memptr.cmp0"

);

3092 for

(

int

I = 1,

E

= fields.size(); I <

E

; ++I) {

3093

llvm::Value *

Field

= Builder.CreateExtractValue(MemPtr, I);

3094

llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],

"memptr.cmp"

);

3095

Res = Builder.CreateOr(Res, Next,

"memptr.tobool"

);

3101

llvm::Constant *Val) {

3104

llvm::Constant *FirstField = Val->getType()->isStructTy() ?

3105

Val->getAggregateElement(0

U

) : Val;

3106 return

FirstField->isNullValue();

3111 if

(isZeroInitializable(MPT) && Val->isNullValue())

3117

GetNullMemberPointerFields(MPT, Fields);

3118 if

(Fields.size() == 1) {

3119

assert(Val->getType()->isIntegerTy());

3120 return

Val == Fields[0];

3124 for

(I = 0,

E

= Fields.size(); I !=

E

; ++I) {

3125 if

(Val->getAggregateElement(I) != Fields[I])

3134

llvm::Value *VBPtrOffset,

3135

llvm::Value *VBTableOffset,

3136

llvm::Value **VBPtrOut) {

3139

llvm::Value *VBPtr = Builder.CreateInBoundsGEP(

3140

CGM.

Int8Ty

,

This

.emitRawPointer(CGF), VBPtrOffset,

"vbptr"

);

3145 if

(

auto

CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {

3146

VBPtrAlign =

This

.getAlignment().alignmentAtOffset(

3152

llvm::Value *VBTable =

3153

Builder.CreateAlignedLoad(CGM.

UnqualPtrTy

, VBPtr, VBPtrAlign,

"vbtable"

);

3156

llvm::Value *VBTableIndex = Builder.CreateAShr(

3157

VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),

3158 "vbtindex"

,

true

);

3161

llvm::Value *VBaseOffs =

3162

Builder.CreateInBoundsGEP(CGM.

Int32Ty

, VBTable, VBTableIndex);

3163 return

Builder.CreateAlignedLoad(CGM.

Int32Ty

, VBaseOffs,

3169

llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(

3171 Address Base

, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {

3174

llvm::BasicBlock *OriginalBB =

nullptr

;

3175

llvm::BasicBlock *SkipAdjustBB =

nullptr

;

3176

llvm::BasicBlock *VBaseAdjustBB =

nullptr

;

3183

OriginalBB = Builder.GetInsertBlock();

3186

llvm::Value *IsVirtual =

3187

Builder.CreateICmpNE(VBTableOffset, getZeroInt(),

3188 "memptr.is_vbase"

);

3189

Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);

3201 "member pointer representation requires a " 3202 "complete class type for %0 to perform this expression"

);

3205

offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();

3208

llvm::Value *VBPtr =

nullptr

;

3209

llvm::Value *VBaseOffs =

3210

GetVBaseOffsetFromVBPtr(CGF,

Base

, VBPtrOffset, VBTableOffset, &VBPtr);

3211

llvm::Value *AdjustedBase =

3212

Builder.CreateInBoundsGEP(CGM.

Int8Ty

, VBPtr, VBaseOffs);

3215 if

(VBaseAdjustBB) {

3216

Builder.CreateBr(SkipAdjustBB);

3218

llvm::PHINode *Phi = Builder.CreatePHI(CGM.

Int8PtrTy

, 2,

"memptr.base"

);

3219

Phi->addIncoming(

Base

.emitRawPointer(CGF), OriginalBB);

3220

Phi->addIncoming(AdjustedBase, VBaseAdjustBB);

3223 return

AdjustedBase;

3226

llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(

3236

llvm::Value *FieldOffset = MemPtr;

3237

llvm::Value *VirtualBaseAdjustmentOffset =

nullptr

;

3238

llvm::Value *VBPtrOffset =

nullptr

;

3239 if

(MemPtr->getType()->isStructTy()) {

3242

FieldOffset = Builder.CreateExtractValue(MemPtr, I++);

3244

VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);

3246

VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);

3250 if

(VirtualBaseAdjustmentOffset) {

3251

Addr = AdjustVirtualBase(CGF,

E

, RD,

Base

, VirtualBaseAdjustmentOffset,

3254

Addr =

Base

.emitRawPointer(CGF);

3258 return

Builder.CreateInBoundsGEP(CGF.

Int8Ty

, Addr, FieldOffset,

3266

assert(

E

->getCastKind() == CK_DerivedToBaseMemberPointer ||

3267 E

->getCastKind() == CK_BaseToDerivedMemberPointer ||

3268 E

->getCastKind() == CK_ReinterpretMemberPointer);

3271 if

(isa<llvm::Constant>(Src))

3272 return

EmitMemberPointerConversion(

E

, cast<llvm::Constant>(Src));

3282 bool

IsReinterpret =

E

->getCastKind() == CK_ReinterpretMemberPointer;

3283 if

(IsReinterpret && IsFunc)

3288 if

(IsReinterpret &&

3295

llvm::Value *

IsNotNull

= EmitMemberPointerIsNotNull(CGF, Src, SrcTy);

3296

llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);

3300 if

(IsReinterpret) {

3303

assert(Src->getType() == DstNull->getType());

3304 return

Builder.CreateSelect(

IsNotNull

, Src, DstNull);

3307

llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();

3309

llvm::BasicBlock *ContinueBB = CGF.

createBasicBlock

(

"memptr.converted"

);

3310

Builder.CreateCondBr(

IsNotNull

, ConvertBB, ContinueBB);

3313

llvm::Value *Dst = EmitNonNullMemberPointerConversion(

3314

SrcTy, DstTy,

E

->getCastKind(),

E

->path_begin(),

E

->path_end(), Src,

3317

Builder.CreateBr(ContinueBB);

3321

llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,

"memptr.converted"

);

3322

Phi->addIncoming(DstNull, OriginalBB);

3323

Phi->addIncoming(Dst, ConvertBB);

3327

llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(

3337 bool

IsConstant = isa<llvm::Constant>(Src);

3340

llvm::Value *FirstField = Src;

3341

llvm::Value *NonVirtualBaseAdjustment = getZeroInt();

3342

llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();

3343

llvm::Value *VBPtrOffset = getZeroInt();

3347

FirstField = Builder.CreateExtractValue(Src, I++);

3349

NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);

3351

VBPtrOffset = Builder.CreateExtractValue(Src, I++);

3353

VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);

3356 bool

IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);

3362

llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;

3369

llvm::Value *SrcVBIndexEqZero =

3370

Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());

3371 if

(SrcInheritance == MSInheritanceModel::Virtual) {

3372 if

(int64_t SrcOffsetToFirstVBase =

3373

getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {

3374

llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(

3376

llvm::ConstantInt::get(CGM.

IntTy

, SrcOffsetToFirstVBase),

3378

NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);

3389

llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(

3394

llvm::Value *NVDisp;

3395 if

(IsDerivedToBase)

3396

NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,

"adj"

);

3398

NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,

"adj"

);

3400

NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());

3404

llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;

3407 if

(llvm::GlobalVariable *VDispMap =

3408

getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {

3409

llvm::Value *VBIndex = Builder.CreateExactUDiv(

3410

VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.

IntTy

, 4));

3412

llvm::Constant *Mapping = VDispMap->getInitializer();

3413

VirtualBaseAdjustmentOffset =

3414

Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));

3416

llvm::Value *Idxs[] = {getZeroInt(), VBIndex};

3417

VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(

3418

CGM.

IntTy

, Builder.CreateInBoundsGEP(VDispMap->getValueType(),

3424

Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());

3431

llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(

3433

getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());

3435

Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);

3441 if

(DstInheritance == MSInheritanceModel::Virtual) {

3442 if

(int64_t DstOffsetToFirstVBase =

3443

getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {

3444

llvm::Value *DoDstAdjustment = Builder.CreateSelect(

3446

llvm::ConstantInt::get(CGM.

IntTy

, DstOffsetToFirstVBase),

3448

NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);

3457

Dst = llvm::PoisonValue::get(ConvertMemberPointerType(DstTy));

3459

Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);

3461

Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);

3463

Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);

3465

Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);

3471

MicrosoftCXXABI::EmitMemberPointerConversion(

const CastExpr

*

E

,

3472

llvm::Constant *Src) {

3479 return

EmitMemberPointerConversion(SrcTy, DstTy, CK,

E

->path_begin(),

3480 E

->path_end(), Src);

3483

llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(

3487

assert(CK == CK_DerivedToBaseMemberPointer ||

3488

CK == CK_BaseToDerivedMemberPointer ||

3489

CK == CK_ReinterpretMemberPointer);

3492 if

(MemberPointerConstantIsNull(SrcTy, Src))

3493 return

EmitNullMemberPointer(DstTy);

3498 if

(CK == CK_ReinterpretMemberPointer)

3502 auto

*Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(

3503

SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));

3508CGCallee

MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(

3510

llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,

3522

llvm::Value *FunctionPointer = MemPtr;

3523

llvm::Value *NonVirtualBaseAdjustment =

nullptr

;

3524

llvm::Value *VirtualBaseAdjustmentOffset =

nullptr

;

3525

llvm::Value *VBPtrOffset =

nullptr

;

3526 if

(MemPtr->getType()->isStructTy()) {

3529

FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);

3531

NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);

3533

VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);

3535

VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);

3538 if

(VirtualBaseAdjustmentOffset) {

3539

ThisPtrForCall = AdjustVirtualBase(CGF,

E

, RD, This,

3540

VirtualBaseAdjustmentOffset, VBPtrOffset);

3542

ThisPtrForCall =

This

.emitRawPointer(CGF);

3545 if

(NonVirtualBaseAdjustment)

3546

ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.

Int8Ty

, ThisPtrForCall,

3547

NonVirtualBaseAdjustment);

3554 return new

MicrosoftCXXABI(CGM);

3588

StringRef MangledName(

"??_7type_info@@6B@"

);

3589 if

(

auto

VTable = CGM.

getModule

().getNamedGlobal(MangledName))

3593

llvm::GlobalVariable::ExternalLinkage,

3594 nullptr

, MangledName);

3607

IsPrivateOnPath = 1 | 8,

3611

HasHierarchyDescriptor = 64

3617

MSRTTIClass *getFirstChild() {

return this

+ 1; }

3618 static

MSRTTIClass *getNextChild(MSRTTIClass *Child) {

3619 return

Child + 1 + Child->NumBases;

3623 uint32_t

Flags, NumBases, OffsetInVBase;

3629

Flags = HasHierarchyDescriptor;

3631

VirtualRoot =

nullptr

;

3635

Flags |= IsPrivate | IsPrivateOnPath;

3641 if

(

Parent

->Flags & IsPrivateOnPath)

3642

Flags |= IsPrivateOnPath;

3643

VirtualRoot =

Parent

->VirtualRoot;

3644

OffsetInVBase =

Parent

->OffsetInVBase + RD->getASTContext()

3645

.getASTRecordLayout(

Parent

->RD).getBaseClassOffset(RD).getQuantity();

3649

MSRTTIClass *Child = getFirstChild();

3651

NumBases += Child->initialize(

this

, &

Base

) + 1;

3652

Child = getNextChild(Child);

3657static

llvm::GlobalValue::LinkageTypes getLinkageForRTTI(

QualType

Ty) {

3659 case

Linkage::Invalid:

3660

llvm_unreachable(

"Linkage hasn't been computed!"

);

3663 case

Linkage::Internal:

3664 case

Linkage::UniqueExternal:

3665 return

llvm::GlobalValue::InternalLinkage;

3667 case

Linkage::VisibleNone:

3668 case

Linkage::Module:

3669 case

Linkage::External:

3670 return

llvm::GlobalValue::LinkOnceODRLinkage;

3672

llvm_unreachable(

"Invalid linkage!"

);

3678struct

MSRTTIBuilder {

3680

HasBranchingHierarchy = 1,

3681

HasVirtualBranchingHierarchy = 2,

3682

HasAmbiguousBases = 4

3685

MSRTTIBuilder(MicrosoftCXXABI &ABI,

const CXXRecordDecl

*RD)

3686

: CGM(ABI.CGM), Context(CGM.getContext()),

3687

VMContext(CGM.getLLVMContext()),

Module

(CGM.getModule()), RD(RD),

3688 Linkage

(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),

3691

llvm::GlobalVariable *getBaseClassDescriptor(

const

MSRTTIClass &Classes);

3692

llvm::GlobalVariable *

3694

llvm::GlobalVariable *getClassHierarchyDescriptor();

3695

llvm::GlobalVariable *getCompleteObjectLocator(

const VPtrInfo

&Info);

3699

llvm::LLVMContext &VMContext;

3702

llvm::GlobalVariable::LinkageTypes

Linkage

;

3703

MicrosoftCXXABI &ABI;

3712

Classes.push_back(MSRTTIClass(RD));

3723 for

(MSRTTIClass *

Class

= &Classes.front();

Class

<= &Classes.back();) {

3724 if

((

Class

->Flags & MSRTTIClass::IsVirtual) &&

3725

!VirtualBases.insert(

Class

->RD).second) {

3729 if

(!UniqueBases.insert(

Class

->RD).second)

3730

AmbiguousBases.insert(

Class

->RD);

3733 if

(AmbiguousBases.empty())

3735 for

(MSRTTIClass &

Class

: Classes)

3736 if

(AmbiguousBases.count(

Class

.RD))

3737 Class

.Flags |= MSRTTIClass::IsAmbiguous;

3740

llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {

3743

llvm::raw_svector_ostream Out(MangledName);

3744

ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);

3748 if

(

auto

CHD =

Module

.getNamedGlobal(MangledName))

3754

Classes.front().initialize(

nullptr

,

nullptr

);

3757 for

(

const

MSRTTIClass &Class : Classes) {

3758 if

(

Class

.RD->getNumBases() > 1)

3759

Flags |= HasBranchingHierarchy;

3762 if

(

Class

.Flags & MSRTTIClass::IsAmbiguous)

3763

Flags |= HasAmbiguousBases;

3765 if

((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)

3766

Flags |= HasVirtualBranchingHierarchy;

3769

llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.

IntTy

, 0),

3770

llvm::ConstantInt::get(CGM.

IntTy

, 0)};

3773 auto Type

= ABI.getClassHierarchyDescriptorType();

3777 if

(CHD->isWeakForLinker())

3778

CHD->setComdat(CGM.

getModule

().getOrInsertComdat(CHD->getName()));

3780 auto

*Bases = getBaseClassArray(Classes);

3783

llvm::Constant *Fields[] = {

3784

llvm::ConstantInt::get(CGM.

IntTy

, 0),

3785

llvm::ConstantInt::get(CGM.

IntTy

, Flags),

3786

llvm::ConstantInt::get(CGM.

IntTy

, Classes.size()),

3787

ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(

3788

Bases->getValueType(), Bases,

3791

CHD->setInitializer(llvm::ConstantStruct::get(

Type

, Fields));

3795

llvm::GlobalVariable *

3799

llvm::raw_svector_ostream Out(MangledName);

3800

ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);

3808

llvm::Type *PtrType = ABI.getImageRelativeType(CGM.

UnqualPtrTy

);

3809 auto

*ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);

3811 new

llvm::GlobalVariable(

Module

, ArrType,

3813 nullptr

, MangledName);

3814 if

(BCA->isWeakForLinker())

3815

BCA->setComdat(CGM.

getModule

().getOrInsertComdat(BCA->getName()));

3819 for

(MSRTTIClass &Class : Classes)

3820

BaseClassArrayData.push_back(

3821

ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));

3822

BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));

3823

BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));

3827

llvm::GlobalVariable *

3828

MSRTTIBuilder::getBaseClassDescriptor(

const

MSRTTIClass &Class) {

3833 if

(

Class

.VirtualRoot) {

3841

llvm::raw_svector_ostream Out(MangledName);

3842

ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(

3843 Class

.RD,

Class

.OffsetInVBase, VBPtrOffset, OffsetInVBTable,

3848 if

(

auto

BCD =

Module

.getNamedGlobal(MangledName))

3852 auto Type

= ABI.getBaseClassDescriptorType();

3855 nullptr

, MangledName);

3856 if

(BCD->isWeakForLinker())

3857

BCD->setComdat(CGM.

getModule

().getOrInsertComdat(BCD->getName()));

3860

llvm::Constant *Fields[] = {

3861

ABI.getImageRelativeConstant(

3863

llvm::ConstantInt::get(CGM.

IntTy

,

Class

.NumBases),

3864

llvm::ConstantInt::get(CGM.

IntTy

,

Class

.OffsetInVBase),

3865

llvm::ConstantInt::get(CGM.

IntTy

, VBPtrOffset),

3866

llvm::ConstantInt::get(CGM.

IntTy

, OffsetInVBTable),

3867

llvm::ConstantInt::get(CGM.

IntTy

,

Class

.Flags),

3868

ABI.getImageRelativeConstant(

3869

MSRTTIBuilder(ABI,

Class

.RD).getClassHierarchyDescriptor()),

3871

BCD->setInitializer(llvm::ConstantStruct::get(

Type

, Fields));

3875

llvm::GlobalVariable *

3876

MSRTTIBuilder::getCompleteObjectLocator(

const VPtrInfo

&Info) {

3879

llvm::raw_svector_ostream Out(MangledName);

3880

ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.

MangledPath

, Out);

3884 if

(

auto

COL =

Module

.getNamedGlobal(MangledName))

3889 int

VFPtrOffset = 0;

3895

->second.hasVtorDisp())

3899

llvm::StructType *

Type

= ABI.getCompleteObjectLocatorType();

3901 nullptr

, MangledName);

3904

llvm::Constant *Fields[] = {

3905

llvm::ConstantInt::get(CGM.

IntTy

, ABI.isImageRelative()),

3906

llvm::ConstantInt::get(CGM.

IntTy

, OffsetToTop),

3907

llvm::ConstantInt::get(CGM.

IntTy

, VFPtrOffset),

3908

ABI.getImageRelativeConstant(

3910

ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),

3911

ABI.getImageRelativeConstant(COL),

3914 if

(!ABI.isImageRelative())

3915

FieldsRef = FieldsRef.drop_back();

3916

COL->setInitializer(llvm::ConstantStruct::get(

Type

, FieldsRef));

3917 if

(COL->isWeakForLinker())

3918

COL->setComdat(CGM.

getModule

().getOrInsertComdat(COL->getName()));

3923 bool

&IsConst,

bool

&IsVolatile,

3924 bool

&IsUnaligned) {

3933

IsVolatile =

false

;

3934

IsUnaligned =

false

;

3936 if

(!PointeeType.

isNull

()) {

3957

MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(

QualType Type

,

3962 bool

IsConst, IsVolatile, IsUnaligned;

3986

llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(

QualType Type

) {

3989

llvm::raw_svector_ostream Out(MangledName);

3990

getMangleContext().mangleCXXRTTI(

Type

, Out);

3994 if

(llvm::GlobalVariable *GV = CGM.

getModule

().getNamedGlobal(MangledName))

4003

llvm::raw_svector_ostream Out(TypeInfoString);

4004

getMangleContext().mangleCXXRTTIName(

Type

, Out);

4008

llvm::Constant *Fields[] = {

4010

llvm::ConstantPointerNull::get(CGM.

Int8PtrTy

),

4011

llvm::ConstantDataArray::getString(CGM.

getLLVMContext

(), TypeInfoString)};

4012

llvm::StructType *TypeDescriptorType =

4013

getTypeDescriptorType(TypeInfoString);

4014 auto

*Var =

new

llvm::GlobalVariable(

4015

CGM.

getModule

(), TypeDescriptorType,

false

,

4016

getLinkageForRTTI(

Type

),

4017

llvm::ConstantStruct::get(TypeDescriptorType, Fields),

4019 if

(Var->isWeakForLinker())

4020

Var->setComdat(CGM.

getModule

().getOrInsertComdat(Var->getName()));

4025

llvm::GlobalVariable *

4026

MicrosoftCXXABI::getMSCompleteObjectLocator(

const CXXRecordDecl

*RD,

4028 return

MSRTTIBuilder(*

this

, RD).getCompleteObjectLocator(Info);

4031void

MicrosoftCXXABI::emitCXXStructor(

GlobalDecl

GD) {

4032 if

(

auto

*ctor = dyn_cast<CXXConstructorDecl>(GD.

getDecl

())) {

4034

llvm::Function *

Fn

=

4040 auto

*dtor = cast<CXXDestructorDecl>(GD.

getDecl

());

4046

dtor->getParent()->getNumVBases() == 0)

4057 if

(

Fn

->isWeakForLinker())

4058 Fn

->setComdat(CGM.

getModule

().getOrInsertComdat(

Fn

->getName()));

4068

llvm::raw_svector_ostream Out(ThunkName);

4069

getMangleContext().mangleName(

GlobalDecl

(CD, CT), Out);

4072 if

(llvm::GlobalValue *GV = CGM.

getModule

().getNamedValue(ThunkName))

4073 return

cast<llvm::Function>(GV);

4079 QualType

RecordTy = getContext().getRecordType(RD);

4080

llvm::Function *ThunkFn = llvm::Function::Create(

4081

ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.

getModule

());

4082

ThunkFn->setCallingConv(

static_cast<

llvm::CallingConv::ID

>

(

4084 if

(ThunkFn->isWeakForLinker())

4085

ThunkFn->setComdat(CGM.

getModule

().getOrInsertComdat(ThunkFn->getName()));

4096

buildThisParam(CGF, FunctionArgs);

4102

&getContext().Idents.get(

"src"

),

4103

getContext().getLValueReferenceType(RecordTy,

4105

ImplicitParamKind::Other);

4107

FunctionArgs.push_back(&SrcParam);

4114

&getContext().Idents.get(

"is_most_derived"

),

4115

getContext().IntTy, ImplicitParamKind::Other);

4118

FunctionArgs.push_back(&IsMostDerived);

4126

setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));

4127

llvm::Value *

This

= getThisValue(CGF);

4129

llvm::Value *SrcVal =

4146

assert(PD->hasDefaultArg() &&

"ctor closure lacks default args"

);

4147

ArgVec.push_back(PD->getDefaultArg());

4150

CodeGenFunction::RunCleanupsScope Cleanups(CGF);

4156

AddedStructorArgCounts ExtraArgs =

4161

llvm::Constant *CalleePtr =

4166

Args, CD,

Ctor_Complete

, ExtraArgs.Prefix, ExtraArgs.Suffix);

4169

Cleanups.ForceCleanup();

4178

llvm::Constant *MicrosoftCXXABI::getCatchableType(

QualType T

,

4180

int32_t VBPtrOffset,

4192 uint32_t Size

= getContext().getTypeSizeInChars(

T

).getQuantity();

4195

llvm::raw_svector_ostream Out(MangledName);

4196

getMangleContext().mangleCXXCatchableType(

T

, CD, CT, Size, NVOffset,

4197

VBPtrOffset, VBIndex, Out);

4199 if

(llvm::GlobalVariable *GV = CGM.

getModule

().getNamedGlobal(MangledName))

4200 return

getImageRelativeConstant(GV);

4204

llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(

T

));

4208

llvm::Constant *CopyCtor;

4215

CopyCtor = llvm::Constant::getNullValue(CGM.

Int8PtrTy

);

4217

CopyCtor = getImageRelativeConstant(CopyCtor);

4219 bool

IsScalar = !RD;

4220 bool

HasVirtualBases =

false

;

4221 bool

IsStdBadAlloc =

false

;

4236 if

(HasVirtualBases)

4241

llvm::Constant *Fields[] = {

4242

llvm::ConstantInt::get(CGM.

IntTy

, Flags),

4244

llvm::ConstantInt::get(CGM.

IntTy

, NVOffset),

4245

llvm::ConstantInt::get(CGM.

IntTy

, VBPtrOffset),

4246

llvm::ConstantInt::get(CGM.

IntTy

, VBIndex),

4247

llvm::ConstantInt::get(CGM.

IntTy

, Size),

4250

llvm::StructType *CTType = getCatchableTypeType();

4251 auto

*GV =

new

llvm::GlobalVariable(

4252

CGM.

getModule

(), CTType,

true

, getLinkageForRTTI(

T

),

4253

llvm::ConstantStruct::get(CTType, Fields), MangledName);

4254

GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

4255

GV->setSection(

".xdata"

);

4256 if

(GV->isWeakForLinker())

4257

GV->setComdat(CGM.

getModule

().getOrInsertComdat(GV->getName()));

4258 return

getImageRelativeConstant(GV);

4261

llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(

QualType T

) {

4265

llvm::GlobalVariable *&CTA = CatchableTypeArrays[

T

];

4290 if

(MostDerivedClass) {

4297

Classes.front().initialize(

nullptr

,

nullptr

);

4299 for

(

const

MSRTTIClass &Class : Classes) {

4302

(MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))

4307 if

(

Class

.VirtualRoot) {

4318

CatchableTypes.insert(getCatchableType(RTTITy,

Class

.OffsetInVBase,

4319

VBPtrOffset, OffsetInVBTable));

4327

CatchableTypes.insert(getCatchableType(

T

));

4340

CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));

4351

CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));

4353 uint32_t

NumEntries = CatchableTypes.size();

4354

llvm::Type *CTType = getImageRelativeType(CGM.

UnqualPtrTy

);

4355

llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);

4356

llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);

4357

llvm::Constant *Fields[] = {

4358

llvm::ConstantInt::get(CGM.

IntTy

, NumEntries),

4359

llvm::ConstantArray::get(

4361

CatchableTypes.end()))

4365

llvm::raw_svector_ostream Out(MangledName);

4366

getMangleContext().mangleCXXCatchableTypeArray(

T

, NumEntries, Out);

4368

CTA =

new

llvm::GlobalVariable(

4369

CGM.

getModule

(), CTAType,

true

, getLinkageForRTTI(

T

),

4370

llvm::ConstantStruct::get(CTAType, Fields), MangledName);

4371

CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

4372

CTA->setSection(

".xdata"

);

4373 if

(CTA->isWeakForLinker())

4374

CTA->setComdat(CGM.

getModule

().getOrInsertComdat(CTA->getName()));

4378

llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(

QualType T

) {

4379 bool

IsConst, IsVolatile, IsUnaligned;

4384

llvm::GlobalVariable *CTA = getCatchableTypeArray(

T

);

4390

cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0

U

))

4391

->getLimitedValue();

4395

llvm::raw_svector_ostream Out(MangledName);

4396

getMangleContext().mangleCXXThrowInfo(

T

, IsConst, IsVolatile, IsUnaligned,

4402 if

(llvm::GlobalVariable *GV = CGM.

getModule

().getNamedGlobal(MangledName))

4418

llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.

Int8PtrTy

);

4421 if

(!DtorD->isTrivial())

4424

llvm::Constant *ForwardCompat =

4425

getImageRelativeConstant(llvm::Constant::getNullValue(CGM.

Int8PtrTy

));

4426

llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);

4427

llvm::StructType *TIType = getThrowInfoType();

4428

llvm::Constant *Fields[] = {

4429

llvm::ConstantInt::get(CGM.

IntTy

, Flags),

4430

getImageRelativeConstant(CleanupFn),

4432

PointerToCatchableTypes

4434 auto

*GV =

new

llvm::GlobalVariable(

4435

CGM.

getModule

(), TIType,

true

, getLinkageForRTTI(

T

),

4436

llvm::ConstantStruct::get(TIType, Fields), MangledName.str());

4437

GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);

4438

GV->setSection(

".xdata"

);

4439 if

(GV->isWeakForLinker())

4440

GV->setComdat(CGM.

getModule

().getOrInsertComdat(GV->getName()));

4445 const Expr

*SubExpr =

E

->getSubExpr();

4446

assert(SubExpr &&

"SubExpr cannot be null"

);

4456

llvm::GlobalVariable *TI = getThrowInfo(ThrowType);

4463

std::pair<llvm::Value *, const CXXRecordDecl *>

4466

std::tie(This, std::ignore, RD) =

4471bool

MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(

4503 if

(

const CXXRecordDecl

*FRD = B.getType()->getAsCXXRecordDecl()) {

4504 if

(!isPermittedToBeHomogeneousAggregate(FRD))

static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)

static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *DynInitBB, llvm::BasicBlock *ContinueBB)

static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)

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

static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty, CodeGenModule &CGM)

static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM)

static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM)

static llvm::GlobalValue * getTlsGuardVar(CodeGenModule &CGM)

static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)

static llvm::CallBase * emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)

static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM)

static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *ContinueBB)

static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)

Find ambiguity among base classes.

static void emitDynamicTlsInitialization(CodeGenFunction &CGF)

static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)

Recursively serializes a class hierarchy in pre-order depth first order.

static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM)

static bool isDeletingDtor(GlobalDecl GD)

static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)

static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)

static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)

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

llvm::DenseSet< const void * > Visited

const NestedNameSpecifier * Specifier

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

bool isMemberPointerToDerivedMember() const

const ValueDecl * getMemberPointerDecl() const

ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const

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

CharUnits getTypeAlignInChars(QualType T) const

Return the ABI-specified alignment of a (complete) type T, in characters.

uint64_t getFieldOffset(const ValueDecl *FD) const

Get the offset of a FieldDecl or IndirectFieldDecl, in bits.

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

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

Get or compute information about the layout of the specified record (struct/union/class) D,...

CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const

Retrieves the default calling convention for the current target.

QualType getPointerType(QualType T) const

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

QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const

Return the unique reference to the type for the specified type declaration.

const LangOptions & getLangOpts() const

GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const

CanQualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const

Return a conservative estimate of the alignment of the specified decl D.

CharUnits getTypeSizeInChars(QualType T) const

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

QualType getExceptionObjectType(QualType T) const

const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)

const TargetInfo & getTargetInfo() const

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy

CharUnits getVBPtrOffset() const

getVBPtrOffset - Get the offset for virtual base table pointer.

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

getBaseClassOffset - Get the offset, in chars, for the given base class.

CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const

getVBaseClassOffset - Get the offset, in chars, for the given base class.

const VBaseOffsetsMapTy & getVBaseOffsetsMap() const

bool hasExtendableVFPtr() const

hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...

Represents a base class of a C++ class.

CXXCatchStmt - This represents a C++ catch block.

Represents a C++ constructor within a class.

Represents a delete expression for memory deallocation and destructor calls, e.g.

FunctionDecl * getOperatorDelete() const

bool isGlobalDelete() const

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.

Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".

Represents a C++ struct/union/class.

bool hasNonTrivialCopyAssignment() const

Determine whether this class has a non-trivial copy assignment operator (C++ [class....

bool hasPrivateFields() const

bool hasProtectedFields() const

bool hasNonTrivialDestructor() const

Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)

bool isPolymorphic() const

Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...

unsigned getNumBases() const

Retrieves the number of base classes of this class.

CXXRecordDecl * getMostRecentNonInjectedDecl()

base_class_range vbases()

MSInheritanceModel getMSInheritanceModel() const

Returns the inheritance model used for this record.

bool nullFieldOffsetIsZero() const

In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...

bool hasDefinition() const

bool isEmpty() const

Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).

CXXDestructorDecl * getDestructor() const

Returns the destructor decl for this class.

bool hasNonTrivialDefaultConstructor() const

Determine whether this class has a non-trivial default constructor (C++11 [class.ctor]p5).

bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const

Determine whether this class is virtually derived from the class Base.

bool needsImplicitCopyAssignment() const

Determine whether this class needs an implicit copy assignment operator to be lazily declared.

bool hasSimpleCopyAssignment() const

true if we know for sure that this class has a single, accessible, unambiguous copy assignment operat...

unsigned getNumVBases() const

Retrieves the number of virtual base classes of this class.

A C++ throw-expression (C++ [except.throw]).

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

const CXXBaseSpecifier *const * path_const_iterator

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

bool isPositive() const

isPositive - Test whether the quantity is greater than zero.

bool isZero() const

isZero - Test whether the quantity equals zero.

llvm::Align getAsAlign() const

getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

static CharUnits One()

One - Construct a CharUnits quantity of one.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

bool hasProfileIRInstr() const

Check if IR level profile instrumentation is on.

static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)

void setSRetAfterThis(bool AfterThis)

bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const

isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous aggregate.

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

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

Return the pointer contained in this class after authenticating it and adding offset to it if necessa...

Address withElementType(llvm::Type *ElemTy) const

Return address with different element type, but same pointer and alignment.

A scoped helper to set the current debug location to the specified location or preferred location of ...

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)

Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")

Given a pointer to i8, adjust it by a given constant offset.

Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")

Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")

llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")

Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")

llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")

Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")

Implements C++ ABI-specific code generation functions.

virtual bool shouldEmitExactDynamicCast(QualType DestRecordTy)=0

llvm::Value *& getStructorImplicitParamValue(CodeGenFunction &CGF)

virtual void EmitCXXConstructors(const CXXConstructorDecl *D)=0

Emit constructor variants required by this ABI.

virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0

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 llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0

Get the address point of the vtable for the given base subobject while building a constructor or a de...

virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0

virtual std::vector< CharUnits > getVBPtrOffsets(const CXXRecordDecl *RD)

Gets the offsets of all the virtual base pointers in a given class.

virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0

virtual void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, const CXXRecordDecl *RD)

Emit the code to initialize hidden members required to handle virtual inheritance,...

virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const

Return whether or not a member pointers type is convertible to an IR type.

virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0

virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0

Checks if ABI requires extra virtual offset for vtable field.

virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)=0

Emits the guarded initializer and destructor setup for the given variable, given that it couldn't be ...

virtual void EmitCXXDestructors(const CXXDestructorDecl *D)=0

Emit destructor variants required by this ABI.

virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0

Emit the ABI-specific prolog for the function.

virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, CXXDtorType DT) const =0

Returns true if the given destructor type should be emitted as a linkonce delegating thunk,...

virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)

Get the ABI-specific "this" parameter adjustment to apply in the prologue of a virtual function.

virtual void setCXXDestructorDLLStorage(llvm::GlobalValue *GV, const CXXDestructorDecl *Dtor, CXXDtorType DT) const

RecordArgABI

Specify how one should pass an argument of a record type.

virtual bool shouldTypeidBeNullChecked(QualType SrcRecordTy)=0

virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)

Find the LLVM type used to represent the given member pointer type.

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

virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)

Create a null member pointer of the given type.

virtual StringRef GetPureVirtualCallName()=0

Gets the pure virtual member call function.

virtual CharUnits getArrayCookieSizeImpl(QualType elementType)

Returns the extra size required in order to store the array cookie for the given type.

virtual bool isSRetParameterAfterThis() const

Returns true if the implicit 'sret' parameter comes after the implicit 'this' parameter of C++ instan...

virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0

Emit code to force the execution of a destructor during global teardown.

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.

virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)

Determine if a member pointer is non-null. Returns an i1.

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

virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0

Emit a reference to a non-local thread_local variable (including triggering the initialization of all...

bool isEmittedWithConstantInitializer(const VarDecl *VD, bool InspectInitForWeakDef=false) const

Determine whether we will definitely emit this variable with a constant initializer,...

virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)

Emit a comparison between two member pointers. Returns an i1.

virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)

Create a member pointer for the given member pointer constant.

virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0

Get the address point of the vtable for the given base subobject.

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

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

virtual llvm::Value * readArrayCookieImpl(CodeGenFunction &IGF, Address ptr, CharUnits cookieSize)

Reads the array cookie for an allocation which is known to have one.

virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT)

Calculate an l-value from an object and a data member pointer.

virtual llvm::Value * getCXXDestructorImplicitParam(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating)=0

Get the implicit (second) parameter that comes after the "this" pointer, or nullptr if there is isn't...

virtual bool requiresArrayCookie(const CXXDeleteExpr *E, QualType eltType)

virtual CatchTypeInfo getCatchAllTypeInfo()

virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0

Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...

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

virtual Address adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD, Address This, bool VirtualCall)

Perform ABI-specific "this" argument adjustment required prior to a call of a virtual function.

bool mayNeedDestruction(const VarDecl *VD) const

virtual llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD)

virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0

Checks if ABI requires to initialize vptrs for given dynamic class.

virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0

virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0

virtual bool isThisCompleteObject(GlobalDecl GD) const =0

Determine whether there's something special about the rules of the ABI tell us that 'this' is a compl...

virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0

Build a virtual function pointer in the ABI-specific way.

virtual bool classifyReturnType(CGFunctionInfo &FI) const =0

If the C++ ABI requires the given type be returned in a particular way, this method sets RetAI and re...

virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0

virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0

virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0

Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.

virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0

virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0

Returns how an argument of the given record type should be passed.

virtual llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0

Emit a dynamic_cast from SrcRecordTy to DestRecordTy.

virtual const CXXRecordDecl * getThisArgumentTypeForMethod(GlobalDecl GD)

Get the type of the implicit "this" parameter used by a method.

virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0

Emit the destructor call.

virtual llvm::GlobalVariable * getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset)=0

Get the address of the vtable for the given record decl which should be used for the vptr at the give...

virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0

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

virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)

Create a member pointer for the given field.

virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0

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 CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, const MemberPointerType *MPT)

Load a member function from an object and a member function pointer.

virtual bool isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const

Returns true if the ABI permits the argument to be a homogeneous aggregate.

virtual void emitCXXStructor(GlobalDecl GD)=0

Emit a single constructor/destructor with the given type from a C++ constructor Decl.

virtual llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke)=0

Emit the ABI-specific virtual destructor call.

virtual bool exportThunk()=0

virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0

virtual llvm::Value * emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy)=0

virtual bool isZeroInitializable(const MemberPointerType *MPT)

Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...

virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)

Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.

virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)

Create a member pointer for the given method.

virtual llvm::Value * emitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0

virtual llvm::GlobalVariable * getThrowInfo(QualType T)

virtual llvm::GlobalValue::LinkageTypes getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const

virtual Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType)

Initialize the array cookie for the given allocation.

ASTContext & getContext() const

virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, QualType SrcRecordTy)=0

virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0

Build the signature of the given constructor or destructor variant by adding any required parameters.

MangleContext & getMangleContext()

Gets the mangle context.

virtual AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating)=0

All available information about a concrete callee.

static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)

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

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

bool isInstanceMethod() const

ABIArgInfo & getReturnInfo()

CanQualType getReturnType() const

unsigned getEffectiveCallingConvention() const

getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...

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 GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())

GenerateCXXGlobalInitFunc - Generates code for initializing global variables.

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

GlobalDecl CurGD

CurGD - The GlobalDecl for the current function being compiled.

llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)

GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.

llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)

void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)

bool CurFuncIsThunk

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

void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)

llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)

void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())

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.

llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)

Emit a type checked load from the given vtable.

void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)

EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...

const Decl * CurCodeDecl

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

RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)

CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...

void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)

EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.

bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)

Returns whether we should perform a type checked load when loading a virtual function for virtual cal...

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 registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)

Call atexit() with a function that passes the given argument to the given function.

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

llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

ASTContext & getContext() const

const Decl * CurFuncDecl

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

AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)

void EmitAutoVarCleanups(const AutoVarEmission &emission)

void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)

PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.

void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)

If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...

llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)

CodeGenTypes & getTypes() const

llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")

LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)

LValue EmitLoadOfReferenceLValue(LValue RefLVal)

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::Instruction * CurrentFuncletPad

llvm::LLVMContext & getLLVMContext()

void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)

Emit a branch to select whether or not to perform guarded initialization.

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 AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object)

Add a destructor and object to add to the C++ global destructor function.

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

Create and attach type metadata for the given vtable.

void setDSOLocal(llvm::GlobalValue *GV) const

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.

CodeGenVTables & getVTables()

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.

const ABIInfo & getABIInfo()

DiagnosticsEngine & getDiags() const

llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)

Return the address of the constructor/destructor of the given type.

llvm::GlobalValue::LinkageTypes getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage)

Returns LLVM linkage for a declarator.

const LangOptions & getLangOpts() const

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

void EmitGlobal(GlobalDecl D)

Emit code for a single global function or var decl.

void addUsedGlobal(llvm::GlobalValue *GV)

Add a global to a list to be added to the llvm.used metadata.

void AppendLinkerOptions(StringRef Opts)

Appends Opts to the "llvm.linker.options" metadata value.

bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)

Try to emit a base destructor as an alias to its primary base-class destructor.

CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)

CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)

Returns the assumed alignment of a virtual base of a class.

llvm::Function * codegenCXXStructor(GlobalDecl GD)

llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)

Create a new runtime global variable with the specified type and name.

void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const

Set the TLS mode for the given LLVM GlobalValue for the thread-local variable declaration D.

ASTContext & getContext() const

llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)

Return the llvm::Constant for the address of the given global variable.

MicrosoftVTableContext & getMicrosoftVTableContext()

const CodeGenOptions & getCodeGenOpts() const

StringRef getMangledName(GlobalDecl GD)

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::GlobalValue * GetGlobalValue(StringRef Ref)

void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)

void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const

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 addDeferredVTable(const CXXRecordDecl *RD)

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

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

llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)

This class organizes the cross-module state that is used while lowering AST types to LLVM types.

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

GetFunctionType - Get the LLVM function type for.

llvm::Type * ConvertTypeForMem(QualType T)

ConvertTypeForMem - Convert type T into a llvm::Type.

const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)

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

const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)

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

const CGFunctionInfo & arrangeCXXStructorDeclaration(GlobalDecl GD)

const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)

const CGFunctionInfo & arrangeNullaryFunction()

A nullary function is a freestanding function of type 'void ()'.

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.

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

Returns the type of a vtable with the given layout.

A specialization of Address that requires the address to be an LLVM Constant.

The standard implementation of ConstantInitBuilder used in Clang.

Information for lazily generating a cleanup.

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

LValue - This represents an lvalue references.

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.

An abstract representation of an aligned address.

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

DeclContext * getParent()

getParent - Returns the containing DeclContext.

decl_range decls() const

decls_begin/decls_end - Iterate over the declarations stored in this context.

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

bool isInStdNamespace() const

SourceLocation getLocation() const

DeclContext * getDeclContext()

const LangOptions & getLangOpts() const LLVM_READONLY

Helper to get the language options from the ASTContext.

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

This represents one expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

Represents a member of a struct/union/class.

const RecordDecl * getParent() const

Returns the parent of this field declaration, which is the struct in which this field is defined.

ArrayRef< ParmVarDecl * > parameters() const

unsigned getNumParams() const

Return the number of parameters this function must have based on its FunctionType.

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

bool isVariadic() const

Whether this function prototype is variadic.

GlobalDecl - represents a global declaration.

GlobalDecl getWithCtorType(CXXCtorType Type)

GlobalDecl getWithDtorType(CXXDtorType Type)

CXXDtorType getDtorType() const

const Decl * getDecl() const

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

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)

Create implicit parameter.

bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const

bool isExplicitDefaultVisibilityExportMapping() const

bool isAllDefaultVisibilityExportMapping() const

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

A pointer to member type per C++ 8.3.3 - Pointers to members.

CXXRecordDecl * getMostRecentCXXRecordDecl() const

QualType getPointeeType() const

bool isMemberFunctionPointer() const

Returns true if the member type (i.e.

bool isMemberDataPointer() const

Returns true if the member type (i.e.

unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)

Returns the index of VBase in the vbtable of Derived.

MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)

const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)

const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)

Describes a module or submodule.

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

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

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

bool isExternallyVisible() const

Represents a parameter to a function.

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

bool isConstQualified() const

Determine whether this type is const-qualified.

DestructionKind isDestructedType() const

Returns a nonzero value if objects of this type require non-trivial work to clean up after.

bool hasUnaligned() const

bool canPassInRegisters() const

Determine whether this class can be passed in registers.

Encodes a location in the source.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

uint64_t getPointerWidth(LangAS AddrSpace) const

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

const Type * getTypeForDecl() const

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

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

bool isPointerType() const

const T * castAs() const

Member-template castAs<specific type>.

bool isReferenceType() const

QualType getPointeeType() const

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

bool isObjectType() const

Determine whether this type is an object type.

Linkage getLinkage() const

Determine the linkage of this type.

const T * getAs() const

Member-template getAs<specific type>'.

bool isNullPtrType() const

Represents a single component in a vtable.

ArrayRef< VTableComponent > vtable_components() const

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)

@ NormalCleanup

Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...

@ EHCleanup

Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...

CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)

Creates a Microsoft-family ABI.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr

Matches expressions.

constexpr Variable var(Literal L)

Returns the variable of L.

bool This(InterpState &S, CodePtr OpPC)

bool Zero(InterpState &S, CodePtr OpPC)

bool Ret(InterpState &S, CodePtr &PC)

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

CXXCtorType

C++ constructor types.

@ Ctor_Base

Base object ctor.

@ Ctor_DefaultClosure

Default closure variant of a ctor.

@ Ctor_CopyingClosure

Copying closure variant of a ctor.

@ Ctor_Complete

Complete object ctor.

GVALinkage

A more specific kind of linkage than enum Linkage.

void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)

bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)

bool inheritanceModelHasOnlyOneField(bool IsMemberFunction, MSInheritanceModel Inheritance)

bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)

bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)

Linkage

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

CXXDtorType

C++ destructor types.

@ Dtor_Comdat

The COMDAT used for dtors.

@ Dtor_Base

Base object dtor.

@ Dtor_Complete

Complete object dtor.

@ Dtor_Deleting

Deleting dtor.

CastKind

CastKind - The kind of operation required for a conversion.

const FunctionProtoType * T

MSInheritanceModel

Assigned inheritance model for a class in the MS C++ ABI.

CallingConv

CallingConv - Specifies the calling convention that a function uses.

U cast(CodeGen::Address addr)

@ Class

The "class" keyword introduces the elaborated-type-specifier.

@ Implicit

An implicit conversion.

Diagnostic wrappers for TextAPI types for error reporting.

Similar to AddedStructorArgs, but only notes the number of additional arguments.

Additional implicit arguments to add to the beginning (Prefix) and end (Suffix) of a constructor / de...

The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...

llvm::PointerType * VoidPtrTy

llvm::PointerType * Int8PtrPtrTy

CharUnits getIntAlign() const

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

CharUnits getIntSize() const

llvm::IntegerType * SizeTy

llvm::IntegerType * Int32Ty

llvm::IntegerType * IntPtrTy

llvm::IntegerType * IntTy

int

llvm::PointerType * Int8PtrTy

llvm::PointerType * UnqualPtrTy

llvm::IntegerType * PtrDiffTy

CharUnits getPointerAlign() const

const CXXRecordDecl * VBase

If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.

CharUnits VFPtrOffset

This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...

uint64_t Index

Method's index in the vftable.

union clang::ReturnAdjustment::VirtualAdjustment Virtual

int64_t NonVirtual

The non-virtual adjustment from the derived object to its nearest virtual base.

A this pointer adjustment.

union clang::ThisAdjustment::VirtualAdjustment Virtual

int64_t NonVirtual

The non-virtual adjustment from the derived object to its nearest virtual base.

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

ThisAdjustment This

The this pointer adjustment.

Holds information about the inheritance path to a virtual base or function table pointer.

CharUnits NonVirtualOffset

IntroducingObject is at this offset from its containing complete object or virtual base.

CharUnits FullOffsetInMDC

Static offset from the top of the most derived class to this vfptr, including any virtual base offset...

const CXXRecordDecl * getVBaseWithVPtr() const

The vptr is stored inside the non-virtual component of this virtual base.

const CXXRecordDecl * IntroducingObject

This is the class that introduced the vptr by declaring new virtual methods or virtual bases.

BasePath MangledPath

The bases from the inheritance path that got used to mangle the vbtable name.

BasePath PathToIntroducingObject

This holds the base classes path from the complete type to the first base with the given vfptr offset...

const CXXRecordDecl * ObjectWithVPtr

This is the most derived class that has this vptr at offset zero.

struct clang::ReturnAdjustment::VirtualAdjustment::@193 Microsoft

uint32_t VBPtrOffset

The offset (in bytes) of the vbptr, relative to the beginning of the derived class.

uint32_t VBIndex

Index of the virtual base in the vbtable.

int32_t VtordispOffset

The offset of the vtordisp (in bytes), relative to the ECX.

int32_t VBOffsetOffset

The offset (in bytes) of the vbase offset in the vbtable.

int32_t VBPtrOffset

The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...

struct clang::ThisAdjustment::VirtualAdjustment::@195 Microsoft


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4