A RetroSearch Logo

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

Search Query:

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

clang: lib/CodeGen/CGExprConstant.cpp Source File

27#include "llvm/ADT/STLExtras.h" 28#include "llvm/ADT/Sequence.h" 29#include "llvm/Analysis/ConstantFolding.h" 30#include "llvm/IR/Constants.h" 31#include "llvm/IR/DataLayout.h" 32#include "llvm/IR/Function.h" 33#include "llvm/IR/GlobalVariable.h" 35using namespace clang

;

36using namespace

CodeGen;

43class

ConstExprEmitter;

46

llvm::Type *Ty = CGM.

CharTy

;

48

Ty = llvm::ArrayType::get(Ty, PadSize.

getQuantity

());

50 return

llvm::Constant::getNullValue(Ty);

52 return

llvm::UndefValue::get(Ty);

55struct

ConstantAggregateBuilderUtils {

58

ConstantAggregateBuilderUtils(

CodeGenModule

&CGM) : CGM(CGM) {}

60 CharUnits

getAlignment(

const

llvm::Constant *

C

)

const

{

69 CharUnits

getSize(

const

llvm::Constant *

C

)

const

{

70 return

getSize(

C

->getType());

73

llvm::Constant *getPadding(

CharUnits

PadSize)

const

{

74

return ::getPadding(CGM, PadSize);

77

llvm::Constant *getZeroes(

CharUnits

ZeroSize)

const

{

79 return

llvm::ConstantAggregateZero::get(Ty);

85class

ConstantAggregateBuilder :

private

ConstantAggregateBuilderUtils {

104 bool

NaturalLayout =

true

;

106 bool

split(

size_t

Index,

CharUnits

Hint);

107

std::optional<size_t> splitAt(

CharUnits

Pos);

113 bool

NaturalLayout, llvm::Type *DesiredTy,

114 bool

AllowOversized);

118

: ConstantAggregateBuilderUtils(CGM) {}

125 bool

add(llvm::Constant *

C

,

CharUnits

Offset,

bool

AllowOverwrite);

128 bool

addBits(llvm::APInt Bits, uint64_t OffsetInBits,

bool

AllowOverwrite);

132 void

condense(

CharUnits

Offset, llvm::Type *DesiredTy);

139

llvm::Constant *build(llvm::Type *DesiredTy,

bool

AllowOversized)

const

{

141

NaturalLayout, DesiredTy, AllowOversized);

145template

<

typename

Container,

typename Range

= std::initializer_list<

146 typename

Container::value_type>>

147static void

replace(Container &

C

,

size_t

BeginOff,

size_t

EndOff,

Range

Vals) {

148

assert(BeginOff <= EndOff &&

"invalid replacement range"

);

149

llvm::replace(

C

,

C

.begin() + BeginOff,

C

.begin() + EndOff, Vals);

152bool

ConstantAggregateBuilder::add(llvm::Constant *

C

,

CharUnits

Offset,

153 bool

AllowOverwrite) {

155 if

(Offset >= Size) {

158 if

(AlignedSize > Offset || Offset.alignTo(Align) != Offset)

159

NaturalLayout =

false

;

160 else if

(AlignedSize < Offset) {

161

Elems.push_back(getPadding(Offset - Size));

162

Offsets.push_back(Size);

164

Elems.push_back(

C

);

165

Offsets.push_back(Offset);

166 Size

= Offset + getSize(

C

);

171

std::optional<size_t> FirstElemToReplace = splitAt(Offset);

172 if

(!FirstElemToReplace)

176

std::optional<size_t> LastElemToReplace = splitAt(Offset + CSize);

177 if

(!LastElemToReplace)

180

assert((FirstElemToReplace == LastElemToReplace || AllowOverwrite) &&

181 "unexpectedly overwriting field"

);

183

replace(Elems, *FirstElemToReplace, *LastElemToReplace, {

C

});

184

replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});

185 Size

= std::max(Size, Offset + CSize);

186

NaturalLayout =

false

;

190bool

ConstantAggregateBuilder::addBits(llvm::APInt Bits, uint64_t OffsetInBits,

191 bool

AllowOverwrite) {

197 unsigned

OffsetWithinChar = OffsetInBits % CharWidth;

205 unsigned

WantedBits =

206

std::min((uint64_t)Bits.getBitWidth(), CharWidth - OffsetWithinChar);

210

llvm::APInt BitsThisChar = Bits;

211 if

(BitsThisChar.getBitWidth() < CharWidth)

212

BitsThisChar = BitsThisChar.zext(CharWidth);

216 int Shift

= Bits.getBitWidth() - CharWidth + OffsetWithinChar;

218

BitsThisChar.lshrInPlace(Shift);

220

BitsThisChar = BitsThisChar.shl(-Shift);

222

BitsThisChar = BitsThisChar.shl(OffsetWithinChar);

224 if

(BitsThisChar.getBitWidth() > CharWidth)

225

BitsThisChar = BitsThisChar.trunc(CharWidth);

227 if

(WantedBits == CharWidth) {

230

OffsetInChars, AllowOverwrite);

235

std::optional<size_t> FirstElemToUpdate = splitAt(OffsetInChars);

236 if

(!FirstElemToUpdate)

238

std::optional<size_t> LastElemToUpdate =

240 if

(!LastElemToUpdate)

242

assert(*LastElemToUpdate - *FirstElemToUpdate < 2 &&

243 "should have at most one element covering one byte"

);

246

llvm::APInt UpdateMask(CharWidth, 0);

248

UpdateMask.setBits(CharWidth - OffsetWithinChar - WantedBits,

249

CharWidth - OffsetWithinChar);

251

UpdateMask.setBits(OffsetWithinChar, OffsetWithinChar + WantedBits);

252

BitsThisChar &= UpdateMask;

254 if

(*FirstElemToUpdate == *LastElemToUpdate ||

255

Elems[*FirstElemToUpdate]->isNullValue() ||

256

isa<llvm::UndefValue>(Elems[*FirstElemToUpdate])) {

259

OffsetInChars,

true

);

261

llvm::Constant *&ToUpdate = Elems[*FirstElemToUpdate];

264 auto

*CI = dyn_cast<llvm::ConstantInt>(ToUpdate);

269

assert(CI->getBitWidth() == CharWidth &&

"splitAt failed"

);

270

assert((!(CI->getValue() & UpdateMask) || AllowOverwrite) &&

271 "unexpectedly overwriting bitfield"

);

272

BitsThisChar |= (CI->getValue() & ~UpdateMask);

273

ToUpdate = llvm::ConstantInt::get(CGM.

getLLVMContext

(), BitsThisChar);

278 if

(WantedBits == Bits.getBitWidth())

283

Bits.lshrInPlace(WantedBits);

284

Bits = Bits.trunc(Bits.getBitWidth() - WantedBits);

287

OffsetWithinChar = 0;

297

std::optional<size_t> ConstantAggregateBuilder::splitAt(

CharUnits

Pos) {

299 return

Offsets.size();

302 auto

FirstAfterPos = llvm::upper_bound(Offsets, Pos);

303 if

(FirstAfterPos == Offsets.begin())

307 size_t

LastAtOrBeforePosIndex = FirstAfterPos - Offsets.begin() - 1;

308 if

(Offsets[LastAtOrBeforePosIndex] == Pos)

309 return

LastAtOrBeforePosIndex;

312 if

(Offsets[LastAtOrBeforePosIndex] +

313

getSize(Elems[LastAtOrBeforePosIndex]) <= Pos)

314 return

LastAtOrBeforePosIndex + 1;

317 if

(!split(LastAtOrBeforePosIndex, Pos))

325bool

ConstantAggregateBuilder::split(

size_t

Index,

CharUnits

Hint) {

326

NaturalLayout =

false

;

327

llvm::Constant *

C

= Elems[Index];

330 if

(

auto

*CA = dyn_cast<llvm::ConstantAggregate>(

C

)) {

333

replace(Elems, Index, Index + 1,

334

llvm::map_range(llvm::seq(0u, CA->getNumOperands()),

335

[&](

unsigned

Op) { return CA->getOperand(Op); }));

336 if

(isa<llvm::ArrayType>(CA->getType()) ||

337

isa<llvm::VectorType>(CA->getType())) {

340

llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);

343

Offsets, Index, Index + 1,

344

llvm::map_range(llvm::seq(0u, CA->getNumOperands()),

345

[&](

unsigned

Op) { return Offset + Op * ElemSize; }));

348 auto

*ST = cast<llvm::StructType>(CA->getType());

349 const

llvm::StructLayout *Layout =

351

replace(Offsets, Index, Index + 1,

353

llvm::seq(0u, CA->getNumOperands()), [&](

unsigned

Op) {

354

return Offset + CharUnits::fromQuantity(

355

Layout->getElementOffset(Op));

361 if

(

auto

*CDS = dyn_cast<llvm::ConstantDataSequential>(

C

)) {

365 CharUnits

ElemSize = getSize(CDS->getElementType());

366

replace(Elems, Index, Index + 1,

367

llvm::map_range(llvm::seq(0u, CDS->getNumElements()),

368

[&](

unsigned

Elem) {

369

return CDS->getElementAsConstant(Elem);

371

replace(Offsets, Index, Index + 1,

373

llvm::seq(0u, CDS->getNumElements()),

374

[&](

unsigned

Elem) { return Offset + Elem * ElemSize; }));

378 if

(isa<llvm::ConstantAggregateZero>(

C

)) {

381

assert(Hint > Offset && Hint < Offset + ElemSize &&

"nothing to split"

);

382

replace(Elems, Index, Index + 1,

383

{getZeroes(Hint - Offset), getZeroes(Offset + ElemSize - Hint)});

384

replace(Offsets, Index, Index + 1, {Offset, Hint});

388 if

(isa<llvm::UndefValue>(

C

)) {

390

replace(Elems, Index, Index + 1, {});

391

replace(Offsets, Index, Index + 1, {});

402static

llvm::Constant *

403

EmitArrayConstant(

CodeGenModule

&CGM, llvm::ArrayType *DesiredType,

404

llvm::Type *CommonElementType, uint64_t ArrayBound,

406

llvm::Constant *Filler);

408

llvm::Constant *ConstantAggregateBuilder::buildFrom(

411 bool

NaturalLayout, llvm::Type *DesiredTy,

bool

AllowOversized) {

412

ConstantAggregateBuilderUtils Utils(CGM);

415 return

llvm::UndefValue::get(DesiredTy);

417 auto

Offset = [&](

size_t

I) {

return

Offsets[I] - StartOffset; };

421 if

(llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(DesiredTy)) {

422

assert(!AllowOversized &&

"oversized array emission not supported"

);

424 bool

CanEmitArray =

true

;

425

llvm::Type *CommonType = Elems[0]->getType();

426

llvm::Constant *Filler = llvm::Constant::getNullValue(CommonType);

427 CharUnits

ElemSize = Utils.getSize(ATy->getElementType());

429 for

(

size_t

I = 0; I != Elems.size(); ++I) {

431 if

(Elems[I]->isNullValue())

435 if

(Elems[I]->getType() != CommonType ||

436

Offset(I) % ElemSize != 0) {

437

CanEmitArray =

false

;

440

ArrayElements.resize(Offset(I) / ElemSize + 1, Filler);

441

ArrayElements.back() = Elems[I];

445 return

EmitArrayConstant(CGM, ATy, CommonType, ATy->getNumElements(),

446

ArrayElements, Filler);

455 CharUnits

DesiredSize = Utils.getSize(DesiredTy);

456 if

(Size > DesiredSize) {

457

assert(AllowOversized &&

"Elems are oversized"

);

463 for

(llvm::Constant *

C

: Elems)

464

Align = std::max(Align, Utils.getAlignment(

C

));

469 bool

Packed =

false

;

472 if

(DesiredSize < AlignedSize || DesiredSize.

alignTo

(Align) != DesiredSize) {

474

NaturalLayout =

false

;

476

}

else if

(DesiredSize > AlignedSize) {

479

UnpackedElemStorage.assign(Elems.begin(), Elems.end());

480

UnpackedElemStorage.push_back(Utils.getPadding(DesiredSize - Size));

481

UnpackedElems = UnpackedElemStorage;

488 if

(!NaturalLayout) {

490 for

(

size_t

I = 0; I != Elems.size(); ++I) {

491 CharUnits

Align = Utils.getAlignment(Elems[I]);

494

assert(DesiredOffset >= SizeSoFar &&

"elements out of order"

);

496 if

(DesiredOffset != NaturalOffset)

498 if

(DesiredOffset != SizeSoFar)

499

PackedElems.push_back(Utils.getPadding(DesiredOffset - SizeSoFar));

500

PackedElems.push_back(Elems[I]);

501

SizeSoFar = DesiredOffset + Utils.getSize(Elems[I]);

506

assert(SizeSoFar <= DesiredSize &&

507 "requested size is too small for contents"

);

508 if

(SizeSoFar < DesiredSize)

509

PackedElems.push_back(Utils.getPadding(DesiredSize - SizeSoFar));

513

llvm::StructType *STy = llvm::ConstantStruct::getTypeForElements(

514

CGM.

getLLVMContext

(), Packed ? PackedElems : UnpackedElems, Packed);

518 if

(llvm::StructType *DesiredSTy = dyn_cast<llvm::StructType>(DesiredTy)) {

519 if

(DesiredSTy->isLayoutIdentical(STy))

523 return

llvm::ConstantStruct::get(STy, Packed ? PackedElems : UnpackedElems);

526void

ConstantAggregateBuilder::condense(

CharUnits

Offset,

527

llvm::Type *DesiredTy) {

530

std::optional<size_t> FirstElemToReplace = splitAt(Offset);

531 if

(!FirstElemToReplace)

533 size_t First

= *FirstElemToReplace;

535

std::optional<size_t> LastElemToReplace = splitAt(Offset + Size);

536 if

(!LastElemToReplace)

538 size_t Last

= *LastElemToReplace;

544 if

(Length == 1 && Offsets[

First

] == Offset &&

545

getSize(Elems[

First

]) == Size) {

548 auto

*STy = dyn_cast<llvm::StructType>(DesiredTy);

549 if

(STy && STy->getNumElements() == 1 &&

550

STy->getElementType(0) == Elems[

First

]->getType())

551

Elems[

First

] = llvm::ConstantStruct::get(STy, Elems[

First

]);

555

llvm::Constant *Replacement = buildFrom(

557 ArrayRef

(Offsets).slice(

First

, Length), Offset, getSize(DesiredTy),

558 false

, DesiredTy,

false

);

559

replace(Elems,

First

,

Last

, {Replacement});

560

replace(Offsets,

First

,

Last

, {Offset});

567class

ConstStructBuilder {

570

ConstantAggregateBuilder &Builder;

580

ConstantAggregateBuilder &Const,

CharUnits

Offset,

585

ConstantAggregateBuilder &Builder,

CharUnits

StartOffset)

587

StartOffset(StartOffset) {}

589 bool

AppendField(

const FieldDecl

*Field, uint64_t FieldOffset,

590

llvm::Constant *InitExpr,

bool

AllowOverwrite =

false

);

592 bool

AppendBytes(

CharUnits

FieldOffsetInChars, llvm::Constant *InitCst,

593 bool

AllowOverwrite =

false

);

595 bool

AppendBitField(

const FieldDecl

*Field, uint64_t FieldOffset,

596

llvm::Constant *InitExpr,

bool

AllowOverwrite =

false

);

598 bool

Build(

const InitListExpr

*ILE,

bool

AllowOverwrite);

601 bool

DoZeroInitPadding(

const ASTRecordLayout

&Layout,

unsigned

FieldNo,

602 const FieldDecl

&Field,

bool

AllowOverwrite,

603 CharUnits

&SizeSoFar,

bool

&ZeroFieldSize);

604 bool

DoZeroInitPadding(

const ASTRecordLayout

&Layout,

bool

AllowOverwrite,

609bool

ConstStructBuilder::AppendField(

610 const FieldDecl

*Field, uint64_t FieldOffset, llvm::Constant *InitCst,

611 bool

AllowOverwrite) {

616 return

AppendBytes(FieldOffsetInChars, InitCst, AllowOverwrite);

619bool

ConstStructBuilder::AppendBytes(

CharUnits

FieldOffsetInChars,

620

llvm::Constant *InitCst,

621 bool

AllowOverwrite) {

622 return

Builder.add(InitCst, StartOffset + FieldOffsetInChars, AllowOverwrite);

625bool

ConstStructBuilder::AppendBitField(

const FieldDecl

*Field,

626

uint64_t FieldOffset, llvm::Constant *

C

,

627 bool

AllowOverwrite) {

629

llvm::ConstantInt *CI = dyn_cast<llvm::ConstantInt>(

C

);

635

llvm::Type *LoadType =

637

llvm::Constant *FoldedConstant = llvm::ConstantFoldLoadFromConst(

639

CI = dyn_cast_if_present<llvm::ConstantInt>(FoldedConstant);

647

llvm::APInt FieldValue = CI->getValue();

653 if

(Info.

Size

> FieldValue.getBitWidth())

654

FieldValue = FieldValue.zext(Info.

Size

);

657 if

(Info.

Size

< FieldValue.getBitWidth())

658

FieldValue = FieldValue.trunc(Info.

Size

);

660 return

Builder.addBits(FieldValue,

666

ConstantAggregateBuilder &Const,

670 return

ConstStructBuilder::UpdateStruct(

Emitter

, Const, Offset, Updater);

672 auto

CAT =

Emitter

.CGM.getContext().getAsConstantArrayType(

Type

);

675 QualType

ElemType = CAT->getElementType();

676 CharUnits

ElemSize =

Emitter

.CGM.getContext().getTypeSizeInChars(ElemType);

677

llvm::Type *ElemTy =

Emitter

.CGM.getTypes().ConvertTypeForMem(ElemType);

679

llvm::Constant *FillC =

nullptr

;

681 if

(!isa<NoInitExpr>(Filler)) {

682

FillC =

Emitter

.tryEmitAbstractForMemory(Filler, ElemType);

688 unsigned

NumElementsToUpdate =

689

FillC ? CAT->getZExtSize() : Updater->

getNumInits

();

690 for

(

unsigned

I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {

692 if

(I < Updater->getNumInits())

695 if

(!

Init

&& FillC) {

696 if

(!

Const

.add(FillC, Offset,

true

))

698

}

else if

(!

Init

|| isa<NoInitExpr>(

Init

)) {

700

}

else if

(

const auto

*ChildILE = dyn_cast<InitListExpr>(

Init

)) {

701 if

(!EmitDesignatedInitUpdater(

Emitter

, Const, Offset, ElemType,

705 Const

.condense(Offset, ElemTy);

707

llvm::Constant *Val =

Emitter

.tryEmitPrivateForMemory(

Init

, ElemType);

708 if

(!

Const

.add(Val, Offset,

true

))

716bool

ConstStructBuilder::Build(

const InitListExpr

*ILE,

bool

AllowOverwrite) {

720 unsigned

FieldNo = -1;

721 unsigned

ElementNo = 0;

726 if

(

auto

*CXXRD = dyn_cast<CXXRecordDecl>(RD))

727 if

(CXXRD->getNumBases())

731 bool

ZeroFieldSize =

false

;

743 if

(

Field

->isUnnamedBitField())

749 if

(ElementNo < ILE->getNumInits())

751 if

(isa_and_nonnull<NoInitExpr>(

Init

)) {

752 if

(ZeroInitPadding &&

753

!DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,

767 if

(ZeroInitPadding &&

768

!DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite, SizeSoFar,

775 if

(AllowOverwrite &&

776

(

Field

->getType()->isArrayType() ||

Field

->getType()->isRecordType())) {

777 if

(

auto

*SubILE = dyn_cast<InitListExpr>(

Init

)) {

780 if

(!EmitDesignatedInitUpdater(

Emitter

, Builder, StartOffset + Offset,

781 Field

->getType(), SubILE))

785

Builder.condense(StartOffset + Offset,

791

llvm::Constant *EltInit =

797 if

(ZeroInitPadding && ZeroFieldSize)

801 if

(!

Field

->isBitField()) {

803 if

(!AppendField(Field, Layout.

getFieldOffset

(FieldNo), EltInit,

808 if

(

Field

->hasAttr<NoUniqueAddressAttr>())

809

AllowOverwrite =

true

;

812 if

(!AppendBitField(Field, Layout.

getFieldOffset

(FieldNo), EltInit,

818 if

(ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))

827

:

Decl

(

Decl

), Offset(Offset), Index(Index) {

834 bool operator<

(

const

BaseInfo &O)

const

{

return

Offset < O.Offset; }

844 if

(

const CXXRecordDecl

*CD = dyn_cast<CXXRecordDecl>(RD)) {

847

llvm::Constant *VTableAddressPoint =

851

VTableAddressPoint =

Emitter

.tryEmitConstantSignedPointer(

852

VTableAddressPoint, *Authentication);

853 if

(!VTableAddressPoint)

856 if

(!AppendBytes(Offset, VTableAddressPoint))

863

Bases.reserve(CD->getNumBases());

866

BaseEnd = CD->bases_end();

Base

!= BaseEnd; ++

Base

, ++BaseNo) {

867

assert(!

Base

->isVirtual() &&

"should not have virtual bases here"

);

870

Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));

872

llvm::stable_sort(Bases);

874 for

(

unsigned

I = 0, N = Bases.size(); I != N; ++I) {

875

BaseInfo &

Base

= Bases[I];

879

VTableClass, Offset +

Base

.Offset);

883 unsigned

FieldNo = 0;

886 bool

ZeroFieldSize =

false

;

889 bool

AllowOverwrite =

false

;

891

FieldEnd = RD->

field_end

(); Field != FieldEnd; ++Field, ++FieldNo) {

897 if

(

Field

->isUnnamedBitField() ||

904

llvm::Constant *EltInit =

905 Emitter

.tryEmitPrivateForMemory(FieldValue,

Field

->getType());

909 if

(ZeroInitPadding) {

910 if

(!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,

911

SizeSoFar, ZeroFieldSize))

918 if

(!

Field

->isBitField()) {

920 if

(!AppendField(*Field, Layout.

getFieldOffset

(FieldNo) + OffsetBits,

921

EltInit, AllowOverwrite))

925 if

(

Field

->hasAttr<NoUniqueAddressAttr>())

926

AllowOverwrite =

true

;

929 if

(!AppendBitField(*Field, Layout.

getFieldOffset

(FieldNo) + OffsetBits,

930

EltInit, AllowOverwrite))

934 if

(ZeroInitPadding && !DoZeroInitPadding(Layout, AllowOverwrite, SizeSoFar))

940bool

ConstStructBuilder::DoZeroInitPadding(

942 bool

AllowOverwrite,

CharUnits

&SizeSoFar,

bool

&ZeroFieldSize) {

945 if

(SizeSoFar < StartOffset)

946 if

(!AppendBytes(SizeSoFar, getPadding(CGM, StartOffset - SizeSoFar),

950 if

(!

Field

.isBitField()) {

952

SizeSoFar = StartOffset + FieldSize;

953

ZeroFieldSize = FieldSize.

isZero

();

963

ZeroFieldSize = Info.

Size

== 0;

968bool

ConstStructBuilder::DoZeroInitPadding(

const ASTRecordLayout

&Layout,

972 if

(SizeSoFar < TotalSize)

973 if

(!AppendBytes(SizeSoFar, getPadding(CGM, TotalSize - SizeSoFar),

976

SizeSoFar = TotalSize;

980

llvm::Constant *ConstStructBuilder::Finalize(

QualType Type

) {

993 if

(!Builder.Build(ILE,

false

))

996 return

Builder.Finalize(ValTy);

1010 return

Builder.Finalize(ValTy);

1014

ConstantAggregateBuilder &Const,

1017 return

ConstStructBuilder(

Emitter

, Const, Offset)

1018

.Build(Updater,

true

);

1030 if

(llvm::GlobalVariable *Addr =

1038

assert(!

E

->isFileScope() &&

1039 "file-scope compound literal did not have constant initializer!"

);

1043 auto

GV =

new

llvm::GlobalVariable(

1046

llvm::GlobalValue::InternalLinkage,

C

,

".compoundliteral"

,

nullptr

,

1047

llvm::GlobalVariable::NotThreadLocal,

1055static

llvm::Constant *

1056

EmitArrayConstant(

CodeGenModule

&CGM, llvm::ArrayType *DesiredType,

1057

llvm::Type *CommonElementType, uint64_t ArrayBound,

1059

llvm::Constant *Filler) {

1061 uint64_t

NonzeroLength = ArrayBound;

1062 if

(Elements.size() < NonzeroLength && Filler->isNullValue())

1063

NonzeroLength = Elements.size();

1064 if

(NonzeroLength == Elements.size()) {

1065 while

(NonzeroLength > 0 && Elements[NonzeroLength - 1]->isNullValue())

1069 if

(NonzeroLength == 0)

1070 return

llvm::ConstantAggregateZero::get(DesiredType);

1073 uint64_t

TrailingZeroes = ArrayBound - NonzeroLength;

1074 if

(TrailingZeroes >= 8) {

1075

assert(Elements.size() >= NonzeroLength &&

1076 "missing initializer for non-zero element"

);

1080 if

(CommonElementType && NonzeroLength >= 8) {

1081

llvm::Constant *Initial = llvm::ConstantArray::get(

1082

llvm::ArrayType::get(CommonElementType, NonzeroLength),

1083 ArrayRef

(Elements).take_front(NonzeroLength));

1085

Elements[0] = Initial;

1087

Elements.resize(NonzeroLength + 1);

1091

CommonElementType ? CommonElementType : DesiredType->getElementType();

1092

FillerType = llvm::ArrayType::get(FillerType, TrailingZeroes);

1093

Elements.back() = llvm::ConstantAggregateZero::get(FillerType);

1094

CommonElementType =

nullptr

;

1095

}

else if

(Elements.size() != ArrayBound) {

1097

Elements.resize(ArrayBound, Filler);

1098 if

(Filler->getType() != CommonElementType)

1099

CommonElementType =

nullptr

;

1103 if

(CommonElementType)

1104 return

llvm::ConstantArray::get(

1105

llvm::ArrayType::get(CommonElementType, ArrayBound), Elements);

1109

Types.reserve(Elements.size());

1110 for

(llvm::Constant *Elt : Elements)

1111

Types.push_back(Elt->getType());

1112

llvm::StructType *SType =

1114 return

llvm::ConstantStruct::get(SType, Elements);

1123class

ConstExprEmitter

1127

llvm::LLVMContext &VMContext;

1130

: CGM(emitter.CGM),

Emitter

(emitter), VMContext(CGM.getLLVMContext()) {

1137

llvm::Constant *VisitStmt(

const Stmt

*S,

QualType T

) {

return nullptr

; }

1140 if

(llvm::Constant *Result =

Emitter

.tryEmitConstantExpr(CE))

1157 return Visit

(

GE

->getResultExpr(),

T

);

1166 return Visit

(

E

->getInitializer(),

T

);

1169

llvm::Constant *ProduceIntToIntCast(

const Expr

*

E

,

QualType

DestType) {

1173 if

(llvm::Constant *

C

=

Visit

(

E

, FromType))

1174 if

(

auto

*CI = dyn_cast<llvm::ConstantInt>(

C

)) {

1177 if

(DstWidth == SrcWidth)

1180

? CI->getValue().sextOrTrunc(DstWidth)

1181

: CI->getValue().zextOrTrunc(DstWidth);

1188 if

(

const auto

*ECE = dyn_cast<ExplicitCastExpr>(

E

))

1190 const Expr

*subExpr =

E

->getSubExpr();

1192 switch

(

E

->getCastKind()) {

1196 "Destination type is not union type!"

);

1198 auto

field =

E

->getTargetUnionField();

1200 auto C

=

Emitter

.tryEmitPrivateForMemory(subExpr, field->getType());

1201 if

(!

C

)

return nullptr

;

1203 auto

destTy = ConvertType(destType);

1204 if

(

C

->getType() == destTy)

return C

;

1210

Elts.push_back(

C

);

1211

Types.push_back(

C

->getType());

1212 unsigned

CurSize = CGM.

getDataLayout

().getTypeAllocSize(

C

->getType());

1213 unsigned

TotalSize = CGM.

getDataLayout

().getTypeAllocSize(destTy);

1215

assert(CurSize <= TotalSize &&

"Union size mismatch!"

);

1216 if

(

unsigned

NumPadBytes = TotalSize - CurSize) {

1217

llvm::Constant *Padding =

1219

Elts.push_back(Padding);

1220

Types.push_back(Padding->getType());

1223

llvm::StructType *STy = llvm::StructType::get(VMContext, Types,

false

);

1224 return

llvm::ConstantStruct::get(STy, Elts);

1227 case

CK_AddressSpaceConversion: {

1229 if

(!

C

)

return nullptr

;

1232

llvm::Type *destTy = ConvertType(

E

->

getType

());

1237 case

CK_LValueToRValue: {

1242 if

(

const auto

*

E

=

1243

dyn_cast<CompoundLiteralExpr>(subExpr->

IgnoreParens

()))

1244 return Visit

(

E

->getInitializer(), destType);

1248 case

CK_AtomicToNonAtomic:

1249 case

CK_NonAtomicToAtomic:

1251 case

CK_ConstructorConversion:

1252 return Visit

(subExpr, destType);

1254 case

CK_ArrayToPointerDecay:

1255 if

(

const auto

*S = dyn_cast<StringLiteral>(subExpr))

1258 case

CK_NullToPointer:

1259 if

(

Visit

(subExpr, destType))

1263 case

CK_IntToOCLSampler:

1264

llvm_unreachable(

"global sampler variables are not generated"

);

1266 case

CK_IntegralCast:

1267 return

ProduceIntToIntCast(subExpr, destType);

1269 case

CK_Dependent: llvm_unreachable(

"saw dependent cast!"

);

1271 case

CK_BuiltinFnToFnPtr:

1272

llvm_unreachable(

"builtin functions are handled elsewhere"

);

1274 case

CK_ReinterpretMemberPointer:

1275 case

CK_DerivedToBaseMemberPointer:

1276 case

CK_BaseToDerivedMemberPointer: {

1278 if

(!

C

)

return nullptr

;

1283 case

CK_ObjCObjectLValueCast:

1284 case

CK_ARCProduceObject:

1285 case

CK_ARCConsumeObject:

1286 case

CK_ARCReclaimReturnedObject:

1287 case

CK_ARCExtendBlockObject:

1288 case

CK_CopyAndAutoreleaseBlockObject:

1296 case

CK_LValueBitCast:

1297 case

CK_LValueToRValueBitCast:

1298 case

CK_NullToMemberPointer:

1299 case

CK_UserDefinedConversion:

1300 case

CK_CPointerToObjCPointerCast:

1301 case

CK_BlockPointerToObjCPointerCast:

1302 case

CK_AnyPointerToBlockPointerCast:

1303 case

CK_FunctionToPointerDecay:

1304 case

CK_BaseToDerived:

1305 case

CK_DerivedToBase:

1306 case

CK_UncheckedDerivedToBase:

1307 case

CK_MemberPointerToBoolean:

1308 case

CK_VectorSplat:

1309 case

CK_FloatingRealToComplex:

1310 case

CK_FloatingComplexToReal:

1311 case

CK_FloatingComplexToBoolean:

1312 case

CK_FloatingComplexCast:

1313 case

CK_FloatingComplexToIntegralComplex:

1314 case

CK_IntegralRealToComplex:

1315 case

CK_IntegralComplexToReal:

1316 case

CK_IntegralComplexToBoolean:

1317 case

CK_IntegralComplexCast:

1318 case

CK_IntegralComplexToFloatingComplex:

1319 case

CK_PointerToIntegral:

1320 case

CK_PointerToBoolean:

1321 case

CK_BooleanToSignedIntegral:

1322 case

CK_IntegralToPointer:

1323 case

CK_IntegralToBoolean:

1324 case

CK_IntegralToFloating:

1325 case

CK_FloatingToIntegral:

1326 case

CK_FloatingToBoolean:

1327 case

CK_FloatingCast:

1328 case

CK_FloatingToFixedPoint:

1329 case

CK_FixedPointToFloating:

1330 case

CK_FixedPointCast:

1331 case

CK_FixedPointToBoolean:

1332 case

CK_FixedPointToIntegral:

1333 case

CK_IntegralToFixedPoint:

1334 case

CK_ZeroToOCLOpaqueType:

1336 case

CK_HLSLVectorTruncation:

1337 case

CK_HLSLArrayRValue:

1340

llvm_unreachable(

"Invalid CastKind"

);

1351 return Visit

(

E

->getSubExpr(),

T

);

1362

llvm::APFloat Result =

1364

llvm::RoundingMode RM =

1366 if

(RM == llvm::RoundingMode::Dynamic)

1367

RM = llvm::RoundingMode::NearestTiesToEven;

1368

Result.convertFromAPInt(

Value

,

Value

.isSigned(), RM);

1377

assert(CAT &&

"can't emit array init for non-constant-bound array"

);

1379 const uint64_t

NumElements = CAT->getZExtSize();

1380 for

(

const auto

*

Init

: ILE->

inits

()) {

1381 if

(

const auto

*Embed =

1382

dyn_cast<EmbedExpr>(

Init

->IgnoreParenImpCasts())) {

1383

NumInitElements += Embed->getDataElementCount() - 1;

1384 if

(NumInitElements > NumElements) {

1385

NumInitElements = NumElements;

1393 uint64_t

NumInitableElts = std::min<uint64_t>(NumInitElements, NumElements);

1395 QualType

EltType = CAT->getElementType();

1398

llvm::Constant *fillC =

nullptr

;

1400

fillC =

Emitter

.tryEmitAbstractForMemory(filler, EltType);

1407 if

(fillC && fillC->isNullValue())

1408

Elts.reserve(NumInitableElts + 1);

1410

Elts.reserve(NumElements);

1412

llvm::Type *CommonElementType =

nullptr

;

1413 auto

Emit = [&](

const Expr

*

Init

,

unsigned

ArrayIndex) {

1414

llvm::Constant *

C

=

nullptr

;

1418 if

(ArrayIndex == 0)

1419

CommonElementType =

C

->getType();

1420 else if

(

C

->getType() != CommonElementType)

1421

CommonElementType =

nullptr

;

1422

Elts.push_back(

C

);

1426 unsigned

ArrayIndex = 0;

1427 QualType

DestTy = CAT->getElementType();

1428 for

(

unsigned

i = 0; i < ILE->

getNumInits

(); ++i) {

1430 if

(

auto

*EmbedS = dyn_cast<EmbedExpr>(

Init

->IgnoreParenImpCasts())) {

1434

llvm::Constant *

C

;

1435 for

(

unsigned

I = EmbedS->getStartingElementPos(),

1436

N = EmbedS->getDataElementCount();

1437

I != EmbedS->getStartingElementPos() + N; ++I) {

1442 C

=

Emitter

.tryEmitPrivateForMemory(

1443

withDestType(CGM.

getContext

(),

Init

, EmbedS->getType(), DestTy,

1449

Elts.push_back(

C

);

1452 if

((ArrayIndex - EmbedS->getDataElementCount()) == 0)

1453

CommonElementType =

C

->getType();

1454 else if

(

C

->getType() != CommonElementType)

1455

CommonElementType =

nullptr

;

1457 if

(!Emit(

Init

, ArrayIndex))

1463

llvm::ArrayType *Desired =

1465 return

EmitArrayConstant(CGM, Desired, CommonElementType, NumElements, Elts,

1469

llvm::Constant *EmitRecordInitialization(

const InitListExpr

*ILE,

1471 return

ConstStructBuilder::BuildStruct(

Emitter

, ILE,

T

);

1484 return

EmitArrayInitialization(ILE,

T

);

1487 return

EmitRecordInitialization(ILE,

T

);

1495 auto C

=

Visit

(

E

->getBase(), destType);

1499

ConstantAggregateBuilder

Const

(CGM);

1507 bool

HasFlexibleArray =

false

;

1509

HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember();

1510 return Const

.build(ValTy, HasFlexibleArray);

1515 if

(!

E

->getConstructor()->isTrivial())

1519 if

(

E

->getNumArgs()) {

1520

assert(

E

->getNumArgs() == 1 &&

"trivial ctor with > 1 argument"

);

1521

assert(

E

->getConstructor()->isCopyOrMoveConstructor() &&

1522 "trivial ctor has argument but isn't a copy/move ctor"

);

1524 const Expr

*Arg =

E

->getArg(0);

1526 "argument to copy ctor is of wrong type"

);

1530 if

(

const auto

*MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))

1531 return Visit

(MTE->getSubExpr(), Ty);

1551

assert(CAT &&

"String data not of constant array type!"

);

1556 return

llvm::ConstantDataArray::getString(VMContext, Str,

false

);

1560 return Visit

(

E

->getSubExpr(),

T

);

1564 if

(llvm::Constant *

C

=

Visit

(

U

->getSubExpr(),

T

))

1565 if

(

auto

*CI = dyn_cast<llvm::ConstantInt>(

C

))

1566 return

llvm::ConstantInt::get(CGM.

getLLVMContext

(), -CI->getValue());

1571 return Visit

(

E

->getSelectedExpr(),

T

);

1582

llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *

C

,

1583

AbstractState saved) {

1584

Abstract = saved.OldValue;

1586

assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&

1587 "created a placeholder while doing an abstract emission?"

);

1596 auto

state = pushAbstract();

1598 return

validateAndPopAbstract(

C

, state);

1603 auto

state = pushAbstract();

1605 return

validateAndPopAbstract(

C

, state);

1610 auto

state = pushAbstract();

1612 return

validateAndPopAbstract(

C

, state);

1628 auto

state = pushAbstract();

1630 C

= validateAndPopAbstract(

C

, state);

1633 "internal error: could not emit constant value \"abstractly\""

);

1642 bool

EnablePtrAuthFunctionTypeDiscrimination) {

1643 auto

state = pushAbstract();

1645 tryEmitPrivate

(value, destType, EnablePtrAuthFunctionTypeDiscrimination);

1646 C

= validateAndPopAbstract(

C

, state);

1649 "internal error: could not emit constant value \"abstractly\""

);

1656

initializeNonAbstract(

D

.getType().getAddressSpace());

1663

initializeNonAbstract(destAddrSpace);

1670

initializeNonAbstract(destAddrSpace);

1672

assert(

C

&&

"couldn't emit constant value non-abstractly?"

);

1677

assert(!Abstract &&

"cannot get current address for abstract constant"

);

1684

llvm::GlobalValue::PrivateLinkage,

1688

llvm::GlobalVariable::NotThreadLocal,

1691

PlaceholderAddresses.push_back(std::make_pair(

nullptr

, global));

1697

llvm::GlobalValue *placeholder) {

1698

assert(!PlaceholderAddresses.empty());

1699

assert(PlaceholderAddresses.back().first ==

nullptr

);

1700

assert(PlaceholderAddresses.back().second == placeholder);

1701

PlaceholderAddresses.back().first = signal;

1705 struct

ReplacePlaceholders {

1709

llvm::Constant *

Base

;

1710

llvm::Type *BaseValueTy =

nullptr

;

1713

llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;

1716

llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;

1724

ReplacePlaceholders(

CodeGenModule

&CGM, llvm::Constant *base,

1725 ArrayRef

<std::pair<llvm::Constant*,

1726

llvm::GlobalVariable*>> addresses)

1727

: CGM(CGM),

Base

(base),

1728

PlaceholderAddresses(addresses.begin(), addresses.end()) {

1731 void

replaceInInitializer(llvm::Constant *init) {

1733

BaseValueTy = init->getType();

1736

Indices.push_back(0);

1737

IndexValues.push_back(

nullptr

);

1740

findLocations(init);

1743

assert(IndexValues.size() == Indices.size() &&

"mismatch"

);

1744

assert(Indices.size() == 1 &&

"didn't pop all indices"

);

1747

assert(Locations.size() == PlaceholderAddresses.size() &&

1748 "missed a placeholder?"

);

1754 for

(

auto

&entry : Locations) {

1755

assert(entry.first->getName() ==

""

&&

"not a placeholder!"

);

1756

entry.first->replaceAllUsesWith(entry.second);

1757

entry.first->eraseFromParent();

1762 void

findLocations(llvm::Constant *init) {

1764 if

(

auto

agg = dyn_cast<llvm::ConstantAggregate>(init)) {

1765 for

(

unsigned

i = 0, e = agg->getNumOperands(); i != e; ++i) {

1766

Indices.push_back(i);

1767

IndexValues.push_back(

nullptr

);

1769

findLocations(agg->getOperand(i));

1771

IndexValues.pop_back();

1779 auto

it = PlaceholderAddresses.find(init);

1780 if

(it != PlaceholderAddresses.end()) {

1781

setLocation(it->second);

1786 if

(

auto expr

= dyn_cast<llvm::ConstantExpr>(init)) {

1787

init =

expr

->getOperand(0);

1794 void

setLocation(llvm::GlobalVariable *placeholder) {

1795

assert(!Locations.contains(placeholder) &&

1796 "already found location for placeholder!"

);

1801

assert(Indices.size() == IndexValues.size());

1802 for

(

size_t

i = Indices.size() - 1; i !=

size_t

(-1); --i) {

1803 if

(IndexValues[i]) {

1805 for

(

size_t

j = 0; j != i + 1; ++j) {

1806

assert(IndexValues[j] &&

1807

isa<llvm::ConstantInt>(IndexValues[j]) &&

1808

cast<llvm::ConstantInt>(IndexValues[j])->getZExtValue()

1815

IndexValues[i] = llvm::ConstantInt::get(CGM.

Int32Ty

, Indices[i]);

1818

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

1819

BaseValueTy,

Base

, IndexValues);

1821

Locations.insert({placeholder, location});

1827

assert(InitializedNonAbstract &&

1828 "finalizing emitter that was used for abstract emission?"

);

1829

assert(!Finalized &&

"finalizing emitter multiple times"

);

1830

assert(global->getInitializer());

1835 if

(!PlaceholderAddresses.empty()) {

1836

ReplacePlaceholders(

CGM

, global, PlaceholderAddresses)

1837

.replaceInInitializer(global->getInitializer());

1838

PlaceholderAddresses.clear();

1843

assert((!InitializedNonAbstract || Finalized || Failed) &&

1844 "not finalized after being initialized for non-abstract emission"

);

1845

assert(PlaceholderAddresses.empty() &&

"unhandled placeholders"

);

1851 type

.getQualifiers());

1860 if

(!

D

.hasLocalStorage()) {

1864

dyn_cast_or_null<CXXConstructExpr>(

D

.getInit())) {

1870

InConstantContext =

D

.hasConstantInitialization();

1873 const Expr

*

E

=

D

.getInit();

1874

assert(

E

&&

"No initializer to emit"

);

1878 if

(llvm::Constant *

C

= ConstExprEmitter(*this).Visit(

E

, nonMemoryDestType))

1884 if

(

APValue

*value =

D

.evaluateValue())

1927

assert(Schema &&

"applying trivial ptrauth schema"

);

1930 return

UnsignedPointer;

1932 unsigned

Key = Schema.

getKey

();

1935

llvm::GlobalValue *StorageAddress =

nullptr

;

1944

llvm::ConstantInt *Discriminator =

1948

UnsignedPointer, Key, StorageAddress, Discriminator);

1953 return

SignedPointer;

1957

llvm::Constant *

C

,

1961 QualType

destValueType = AT->getValueType();

1966 if

(innerSize == outerSize)

1969

assert(innerSize < outerSize &&

"emitted over-large constant for atomic"

);

1970

llvm::Constant *elts[] = {

1972

llvm::ConstantAggregateZero::get(

1973

llvm::ArrayType::get(

CGM

.

Int8Ty

, (outerSize - innerSize) / 8))

1975 return

llvm::ConstantStruct::getAnon(elts);

1979 if

(

C

->getType()->isIntegerTy(1) && !destType->

isBitIntType

()) {

1981

llvm::Constant *Res = llvm::ConstantFoldCastOperand(

1983

assert(Res &&

"Constant folding must succeed"

);

1988

ConstantAggregateBuilder Builder(

CGM

);

1992 auto

*CI = cast<llvm::ConstantInt>(

C

);

1993

llvm::Constant *Res = llvm::ConstantFoldCastOperand(

1995

: llvm::Instruction::ZExt,

2001

llvm::APInt

Value

= cast<llvm::ConstantInt>(Res)->getValue();

2002

Builder.addBits(

Value

,

0,

false

);

2003 return

Builder.build(DesiredTy,

false

);

2013

assert(!destType->

isVoidType

() &&

"can't emit a void constant"

);

2016 if

(llvm::Constant *

C

= ConstExprEmitter(*this).Visit(

E

, destType))

2041struct

ConstantLValue {

2042

llvm::Constant *

Value

;

2043 bool

HasOffsetApplied;

2045

ConstantLValue(llvm::Constant *value,

2046 bool

hasOffsetApplied =

false

)

2047

:

Value

(value), HasOffsetApplied(hasOffsetApplied) {}

2050

: ConstantLValue(address.getPointer()) {}

2054class

ConstantLValueEmitter :

public ConstStmtVisitor

<ConstantLValueEmitter,

2060 bool

EnablePtrAuthFunctionTypeDiscrimination;

2068 bool

EnablePtrAuthFunctionTypeDiscrimination =

true

)

2069

: CGM(emitter.CGM),

Emitter

(emitter),

Value

(value), DestType(destType),

2070

EnablePtrAuthFunctionTypeDiscrimination(

2071

EnablePtrAuthFunctionTypeDiscrimination) {}

2073

llvm::Constant *tryEmit();

2076

llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);

2079

ConstantLValue VisitStmt(

const Stmt

*S) {

return nullptr

; }

2088

ConstantLValue VisitCallExpr(

const CallExpr

*

E

);

2089

ConstantLValue VisitBlockExpr(

const BlockExpr

*

E

);

2091

ConstantLValue VisitMaterializeTemporaryExpr(

2094

ConstantLValue emitPointerAuthSignConstant(

const CallExpr

*

E

);

2095

llvm::Constant *emitPointerAuthPointer(

const Expr

*

E

);

2096 unsigned

emitPointerAuthKey(

const Expr

*

E

);

2097

std::pair<llvm::Constant *, llvm::ConstantInt *>

2098

emitPointerAuthDiscriminator(

const Expr

*

E

);

2100 bool

hasNonZeroOffset()

const

{

2101 return

!

Value

.getLValueOffset().isZero();

2105

llvm::Constant *getOffset() {

2106 return

llvm::ConstantInt::get(CGM.

Int64Ty

,

2107 Value

.getLValueOffset().getQuantity());

2111

llvm::Constant *applyOffset(llvm::Constant *

C

) {

2112 if

(!hasNonZeroOffset())

2115 return

llvm::ConstantExpr::getGetElementPtr(CGM.

Int8Ty

,

C

, getOffset());

2121

llvm::Constant *ConstantLValueEmitter::tryEmit() {

2132

assert(isa<llvm::IntegerType>(destTy) || isa<llvm::PointerType>(destTy));

2137 return

tryEmitAbsolute(destTy);

2141

ConstantLValue result = tryEmitBase(base);

2144

llvm::Constant *value = result.Value;

2145 if

(!value)

return nullptr

;

2148 if

(!result.HasOffsetApplied) {

2149

value = applyOffset(value);

2154 if

(isa<llvm::PointerType>(destTy))

2155 return

llvm::ConstantExpr::getPointerCast(value, destTy);

2157 return

llvm::ConstantExpr::getPtrToInt(value, destTy);

2163

ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {

2165 auto

destPtrTy = cast<llvm::PointerType>(destTy);

2166 if

(

Value

.isNullPointer()) {

2174 auto

intptrTy = CGM.

getDataLayout

().getIntPtrType(destPtrTy);

2175

llvm::Constant *

C

;

2176 C

= llvm::ConstantFoldIntegerCast(getOffset(), intptrTy,

false

,

2178

assert(

C

&&

"Must have folded, as Offset is a ConstantInt"

);

2179 C

= llvm::ConstantExpr::getIntToPtr(

C

, destPtrTy);

2194 auto

PtrAuthSign = [&](llvm::Constant *

C

) {

2197 if

(EnablePtrAuthFunctionTypeDiscrimination)

2201 if

(hasNonZeroOffset())

2202 return

ConstantLValue(

nullptr

);

2204 C

= applyOffset(

C

);

2206 C

, AuthInfo.

getKey

(),

nullptr

,

2208 return

ConstantLValue(

C

,

true

);

2211 return

ConstantLValue(

C

);

2214 if

(

const auto

*FD = dyn_cast<FunctionDecl>(

D

))

2217 if

(

const auto

*VD = dyn_cast<VarDecl>(

D

)) {

2219 if

(!VD->hasLocalStorage()) {

2220 if

(VD->isFileVarDecl() || VD->hasExternalStorage())

2223 if

(VD->isLocalVarDecl()) {

2230 if

(

const auto

*GD = dyn_cast<MSGuidDecl>(

D

))

2233 if

(

const auto

*GCD = dyn_cast<UnnamedGlobalConstantDecl>(

D

))

2236 if

(

const auto

*TPO = dyn_cast<TemplateParamObjectDecl>(

D

))

2247 return

Visit(base.

get

<

const Expr

*>());

2251

ConstantLValueEmitter::VisitConstantExpr(

const ConstantExpr

*

E

) {

2254 return

Visit(

E

->getSubExpr());

2260

CompoundLiteralEmitter.setInConstantContext(

Emitter

.isInConstantContext());

2261 return

tryEmitGlobalCompoundLiteral(CompoundLiteralEmitter,

E

);

2265

ConstantLValueEmitter::VisitStringLiteral(

const StringLiteral

*

E

) {

2270

ConstantLValueEmitter::VisitObjCEncodeExpr(

const ObjCEncodeExpr

*

E

) {

2287

ConstantLValueEmitter::VisitObjCBoxedExpr(

const ObjCBoxedExpr

*

E

) {

2288

assert(

E

->isExpressibleAsConstantInitializer() &&

2289 "this boxed expression can't be emitted as a compile-time constant"

);

2295

ConstantLValueEmitter::VisitPredefinedExpr(

const PredefinedExpr

*

E

) {

2300

ConstantLValueEmitter::VisitAddrLabelExpr(

const AddrLabelExpr

*

E

) {

2301

assert(

Emitter

.CGF &&

"Invalid address of label expression outside function"

);

2302

llvm::Constant *Ptr =

Emitter

.CGF->GetAddrOfLabel(

E

->getLabel());

2307

ConstantLValueEmitter::VisitCallExpr(

const CallExpr

*

E

) {

2308 unsigned

builtin =

E

->getBuiltinCallee();

2309 if

(builtin == Builtin::BI__builtin_function_start)

2313 if

(builtin == Builtin::BI__builtin_ptrauth_sign_constant)

2314 return

emitPointerAuthSignConstant(

E

);

2316 if

(builtin != Builtin::BI__builtin___CFStringMakeConstantString &&

2317

builtin != Builtin::BI__builtin___NSStringMakeConstantString)

2321 if

(builtin == Builtin::BI__builtin___NSStringMakeConstantString) {

2330

ConstantLValueEmitter::emitPointerAuthSignConstant(

const CallExpr

*

E

) {

2331

llvm::Constant *UnsignedPointer = emitPointerAuthPointer(

E

->getArg(0));

2332 unsigned

Key = emitPointerAuthKey(

E

->getArg(1));

2333 auto

[StorageAddress, OtherDiscriminator] =

2334

emitPointerAuthDiscriminator(

E

->getArg(2));

2337

UnsignedPointer, Key, StorageAddress, OtherDiscriminator);

2338 return

SignedPointer;

2341

llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(

const Expr

*

E

) {

2348

assert(

Result

.Val.isLValue());

2349 if

(isa<FunctionDecl>(

Result

.Val.getLValueBase().get<

const ValueDecl

*>()))

2350

assert(

Result

.Val.getLValueOffset().isZero());

2355unsigned

ConstantLValueEmitter::emitPointerAuthKey(

const Expr

*

E

) {

2359

std::pair<llvm::Constant *, llvm::ConstantInt *>

2360

ConstantLValueEmitter::emitPointerAuthDiscriminator(

const Expr

*

E

) {

2363 if

(

const auto

*

Call

= dyn_cast<CallExpr>(

E

)) {

2364 if

(

Call

->getBuiltinCallee() ==

2365

Builtin::BI__builtin_ptrauth_blend_discriminator) {

2367 Call

->getArg(0),

Call

->getArg(0)->getType());

2368 auto

*Extra = cast<llvm::ConstantInt>(

ConstantEmitter

(CGM).emitAbstract(

2369 Call

->getArg(1),

Call

->getArg(1)->getType()));

2375 if

(

Result

->getType()->isPointerTy())

2376 return

{

Result

,

nullptr

};

2377 return

{

nullptr

, cast<llvm::ConstantInt>(

Result

)};

2381

ConstantLValueEmitter::VisitBlockExpr(

const BlockExpr

*

E

) {

2382

StringRef functionName;

2384

functionName = CGF->CurFn->getName();

2386

functionName =

"global"

;

2392

ConstantLValueEmitter::VisitCXXTypeidExpr(

const CXXTypeidExpr

*

E

) {

2394 if

(

E

->isTypeOperand())

2402

ConstantLValueEmitter::VisitMaterializeTemporaryExpr(

2404

assert(

E

->getStorageDuration() ==

SD_Static

);

2411 bool

EnablePtrAuthFunctionTypeDiscrimination) {

2418 return

ConstantLValueEmitter(*

this

,

Value

, DestType,

2419

EnablePtrAuthFunctionTypeDiscrimination)

2425 Value

.getFixedPoint().getValue());

2430 Value

.getComplexIntReal());

2432 Value

.getComplexIntImag());

2435

llvm::StructType *STy =

2436

llvm::StructType::get(

Complex

[0]->getType(),

Complex

[1]->getType());

2437 return

llvm::ConstantStruct::get(STy,

Complex

);

2440 const

llvm::APFloat &

Init

=

Value

.getFloat();

2441 if

(&

Init

.getSemantics() == &llvm::APFloat::IEEEhalf() &&

2445 Init

.bitcastToAPInt());

2453 Value

.getComplexFloatReal());

2455 Value

.getComplexFloatImag());

2458

llvm::StructType *STy =

2459

llvm::StructType::get(

Complex

[0]->getType(),

Complex

[1]->getType());

2460 return

llvm::ConstantStruct::get(STy,

Complex

);

2463 unsigned

NumElts =

Value

.getVectorLength();

2466 for

(

unsigned

I = 0; I != NumElts; ++I) {

2476

llvm_unreachable(

"unsupported vector element type"

);

2478 return

llvm::ConstantVector::get(Inits);

2485 if

(!LHS || !RHS)

return nullptr

;

2489

LHS = llvm::ConstantExpr::getPtrToInt(LHS,

CGM

.

IntPtrTy

);

2490

RHS = llvm::ConstantExpr::getPtrToInt(RHS,

CGM

.

IntPtrTy

);

2491

llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);

2496 return

llvm::ConstantExpr::getTruncOrBitCast(AddrLabelDiff, ResultType);

2500 return

ConstStructBuilder::BuildStruct(*

this

,

Value

, DestType);

2503 unsigned

NumElements =

Value

.getArraySize();

2504 unsigned

NumInitElts =

Value

.getArrayInitializedElts();

2507

llvm::Constant *Filler =

nullptr

;

2508 if

(

Value

.hasArrayFiller()) {

2517 if

(Filler && Filler->isNullValue())

2518

Elts.reserve(NumInitElts + 1);

2520

Elts.reserve(NumElements);

2522

llvm::Type *CommonElementType =

nullptr

;

2523 for

(

unsigned

I = 0; I < NumInitElts; ++I) {

2526 if

(!

C

)

return nullptr

;

2529

CommonElementType =

C

->getType();

2530 else if

(

C

->getType() != CommonElementType)

2531

CommonElementType =

nullptr

;

2532

Elts.push_back(

C

);

2535

llvm::ArrayType *Desired =

2540

Desired = llvm::ArrayType::get(Desired->getElementType(), Elts.size());

2542 return

EmitArrayConstant(

CGM

, Desired, CommonElementType, NumElements, Elts,

2548

llvm_unreachable(

"Unknown APValue kind"

);

2553 return

EmittedCompoundLiterals.lookup(

E

);

2558 bool Ok

= EmittedCompoundLiterals.insert(std::make_pair(CLE, GV)).second;

2560

assert(

Ok

&&

"CLE has already been emitted!"

);

2565

assert(

E

->isFileScope() &&

"not a file-scope compound literal expr"

);

2567 return

tryEmitGlobalCompoundLiteral(emitter,

E

);

2587

llvm::Type *baseType,

2592 bool

asCompleteObject) {

2594

llvm::StructType *structure =

2598 unsigned

numElements = structure->getNumElements();

2599

std::vector<llvm::Constant *> elements(numElements);

2601 auto

CXXR = dyn_cast<CXXRecordDecl>(record);

2604 for

(

const auto

&I : CXXR->bases()) {

2605 if

(I.isVirtual()) {

2623

llvm::Type *baseType = structure->getElementType(fieldIndex);

2629 for

(

const auto

*Field : record->

fields

()) {

2632 if

(!Field->isBitField() &&

2640 if

(Field->getIdentifier())

2642 if

(

const auto

*FieldRD = Field->getType()->getAsRecordDecl())

2643 if

(FieldRD->findFirstNamedDataMember())

2649 if

(CXXR && asCompleteObject) {

2650 for

(

const auto

&I : CXXR->vbases()) {

2661 if

(elements[fieldIndex])

continue

;

2663

llvm::Type *baseType = structure->getElementType(fieldIndex);

2669 for

(

unsigned

i = 0; i != numElements; ++i) {

2671

elements[i] = llvm::Constant::getNullValue(structure->getElementType(i));

2674 return

llvm::ConstantStruct::get(structure, elements);

2679

llvm::Type *baseType,

2685 return

llvm::Constant::getNullValue(baseType);

2699

cast<llvm::PointerType>(

getTypes

().ConvertTypeForMem(

T

)),

T

);

2701 if

(

getTypes

().isZeroInitializable(

T

))

2702 return

llvm::Constant::getNullValue(

getTypes

().ConvertTypeForMem(

T

));

2705

llvm::ArrayType *ATy =

2706

cast<llvm::ArrayType>(

getTypes

().ConvertTypeForMem(

T

));

2710

llvm::Constant *Element =

2714 return

llvm::ConstantArray::get(ATy, Array);

2718

return ::EmitNullConstant(*

this

, RT->getDecl(),

true

);

2721 "Should only see pointers to data members here!"

);

2728

return ::EmitNullConstant(*

this

,

Record

,

false

);

Defines the clang::ASTContext interface.

Defines enum values for all the target-independent builtin functions.

static QualType getNonMemoryType(CodeGenModule &CGM, QualType type)

static llvm::Constant * EmitNullConstant(CodeGenModule &CGM, const RecordDecl *record, bool asCompleteObject)

static ConstantLValue emitConstantObjCStringLiteral(const StringLiteral *S, QualType T, CodeGenModule &CGM)

static llvm::Constant * EmitNullConstantForBase(CodeGenModule &CGM, llvm::Type *baseType, const CXXRecordDecl *base)

Emit the null constant for a base subobject.

llvm::MachO::Record Record

llvm::APInt getValue() const

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

APValue & getStructField(unsigned i)

const FieldDecl * getUnionField() const

APValue & getUnionValue()

bool isIndeterminate() const

@ Indeterminate

This object has an indeterminate value (C++ [basic.indet]).

@ None

There is no such object (it's outside its lifetime).

APValue & getStructBase(unsigned i)

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

const ConstantArrayType * getAsConstantArrayType(QualType T) const

CharUnits getTypeAlignInChars(QualType T) const

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

unsigned getIntWidth(QualType T) const

const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const

Return the APFloat 'semantics' for the specified scalar floating point type.

uint64_t getFieldOffset(const ValueDecl *FD) const

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

void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const

Emit the Objective-CC type encoding for the given type T into S.

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

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

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const

Return the uniqued reference to the type for an lvalue reference to the specified type.

const LangOptions & getLangOpts() const

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

QualType getQualifiedType(SplitQualType split) const

Un-split a SplitQualType.

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

bool hasSameUnqualifiedType(QualType T1, QualType T2) const

Determine whether the given types are equivalent after cvr-qualifiers have been removed.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

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

CharUnits getTypeSizeInChars(QualType T) const

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

const TargetInfo & getTargetInfo() const

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

unsigned getTargetAddressSpace(LangAS AS) const

uint64_t getCharWidth() const

Return the size of the character type, in bits.

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

bool hasOwnVFPtr() const

hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...

CharUnits getSize() const

getSize - Get the record size in characters.

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

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

const CXXRecordDecl * getPrimaryBase() const

getPrimaryBase - Get the primary base for this record.

CharUnits getNonVirtualSize() const

getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...

AddrLabelExpr - The GNU address of label extension, representing &&label.

Represents an array type, per C99 6.7.5.2 - Array Declarators.

QualType getElementType() const

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

Represents a base class of a C++ class.

Represents a call to a C++ constructor.

Represents a C++ constructor within a class.

bool isDefaultConstructor() const

Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...

A use of a default initializer in a constructor or in aggregate initialization.

Expr * getExpr()

Get the initialization expression that will be used.

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

Represents a C++ struct/union/class.

A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

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

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

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.

CharUnits alignTo(const CharUnits &Align) const

alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

ChooseExpr - GNU builtin-in function __builtin_choose_expr.

Expr * getChosenSubExpr() const

getChosenSubExpr - Return the subexpression chosen according to the condition.

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

Create a null member pointer of the given type.

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 llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)

Create a member pointer for the given field.

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 ConstantAddress GenerateConstantString(const StringLiteral *)=0

Generate a constant string object.

llvm::Value * getDiscriminator() const

CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...

unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const

llvm::StructType * getLLVMType() const

Return the "complete object" LLVM type associated with this record.

const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const

Return the BitFieldInfo that corresponds to the field FD.

bool isZeroInitializableAsBase() const

Check whether this struct can be C++ zero-initialized with a zeroinitializer when considered as a bas...

llvm::StructType * getBaseSubobjectLLVMType() const

Return the "base subobject" LLVM type associated with this record.

unsigned getLLVMFieldNo(const FieldDecl *FD) const

Return llvm::StructType element number that corresponds to the field FD.

unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const

Return the LLVM field index corresponding to the given virtual base.

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

ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD)

Get the address of a GUID.

void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)

Emit type info if type of an expression is a variably modified type.

llvm::Module & getModule() const

ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E)

Returns a pointer to a constant global variable for the given file-scope compound literal expression.

llvm::Constant * EmitNullConstantForBase(const CXXRecordDecl *Record)

Return a null constant appropriate for zero-initializing a base class with the given type.

llvm::Constant * getRawFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)

Return a function pointer for a reference to the given function.

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

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

llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)

Get target specific null pointer.

llvm::Constant * GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name)

Gets the address of a block which requires no captures.

CodeGenTypes & getTypes()

llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)

Returns LLVM linkage for a declarator.

llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)

const llvm::DataLayout & getDataLayout() const

void Error(SourceLocation loc, StringRef error)

Emit a general error that something can't be done.

CGCXXABI & getCXXABI() const

ConstantAddress GetWeakRefReference(const ValueDecl *VD)

Get a reference to the target of VD.

CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T)

Return the abstract pointer authentication schema for a pointer to the given function type.

llvm::Constant * GetFunctionStart(const ValueDecl *Decl)

llvm::GlobalVariable * getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E)

If it's been emitted already, returns the GlobalVariable corresponding to a compound literal.

std::optional< PointerAuthQualifier > getVTablePointerAuthentication(const CXXRecordDecl *thisClass)

llvm::Constant * getOrCreateStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)

ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)

Return a pointer to a constant CFString object for the given string.

ConstantAddress GetAddrOfConstantStringFromLiteral(const StringLiteral *S, StringRef Name=".str")

Return a pointer to a constant array for the given string literal.

ASTContext & getContext() const

ConstantAddress GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO)

Get the address of a template parameter object.

ConstantAddress GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD)

Get the address of a UnnamedGlobalConstant.

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.

void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE, llvm::GlobalVariable *GV)

Notes that CLE's GlobalVariable is GV.

const TargetCodeGenInfo & getTargetCodeGenInfo()

llvm::Constant * GetConstantArrayFromStringLiteral(const StringLiteral *E)

Return a constant array for the given string.

llvm::LLVMContext & getLLVMContext()

bool shouldZeroInitPadding() const

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, const Expr *Inner)

Returns a pointer to a global variable representing a temporary with static or thread storage duratio...

llvm::Constant * EmitNullConstant(QualType T)

Return the result of value-initializing the given type, i.e.

llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)

Sign a constant pointer using the given scheme, producing a constant with the same IR type.

ConstantAddress GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *)

Return a pointer to a constant array for the given ObjCEncodeExpr node.

llvm::Type * ConvertType(QualType T)

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

llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)

Given that T is a scalar type, return the IR type that should be used for load and store operations.

const CGRecordLayout & getCGRecordLayout(const RecordDecl *)

getCGRecordLayout - Return record layout info for the given record decl.

llvm::Type * ConvertTypeForMem(QualType T)

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

bool typeRequiresSplitIntoByteArray(QualType ASTTy, llvm::Type *LLVMTy=nullptr)

Check whether the given type needs to be laid out in memory using an opaque byte-array type because i...

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

static ConstantAddress invalid()

llvm::Constant * getPointer() const

llvm::Constant * tryEmitPrivateForMemory(const Expr *E, QualType T)

llvm::Constant * tryEmitForInitializer(const VarDecl &D)

Try to emit the initiaizer of the given declaration as an abstract constant.

llvm::Constant * tryEmitPrivateForVarInit(const VarDecl &D)

llvm::Constant * tryEmitPrivate(const Expr *E, QualType T)

void finalize(llvm::GlobalVariable *global)

llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)

Try to emit the initializer of the given declaration as an abstract constant.

llvm::Constant * emitAbstract(const Expr *E, QualType T)

Emit the result of the given expression as an abstract constant, asserting that it succeeded.

llvm::GlobalValue * getCurrentAddrPrivate()

Get the address of the current location.

llvm::Constant * tryEmitConstantExpr(const ConstantExpr *CE)

llvm::Constant * emitForMemory(llvm::Constant *C, QualType T)

llvm::Constant * emitNullForMemory(QualType T)

llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)

Try to emit the result of the given expression as an abstract constant.

void registerCurrentAddrPrivate(llvm::Constant *signal, llvm::GlobalValue *placeholder)

Register a 'signal' value with the emitter to inform it where to resolve a placeholder.

llvm::Constant * emitForInitializer(const APValue &value, LangAS destAddrSpace, QualType destType)

llvm::Constant * tryEmitAbstractForMemory(const Expr *E, QualType T)

bool isAbstract() const

Is the current emission context abstract?

llvm::Constant * tryEmitConstantSignedPointer(llvm::Constant *Ptr, PointerAuthQualifier Auth)

Try to emit a constant signed pointer, given a raw pointer and the destination ptrauth qualifier.

Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const

virtual llvm::Constant * getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const

Get target specific null pointer.

CompoundLiteralExpr - [C99 6.5.2.5].

ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.

Represents the canonical version of C arrays with a specified constant size.

uint64_t getZExtSize() const

Return the size zero-extended as a uint64_t.

ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...

APValue getAPValueResult() const

SourceLocation getBeginLoc() const LLVM_READONLY

bool hasAPValueResult() const

specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...

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

Decl * getMostRecentDecl()

Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...

Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...

This represents one expression.

const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const

Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

FPOptions getFPFeaturesInEffect(const LangOptions &LO) const

Returns the set of floating point options that apply to this expression.

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const

EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...

bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const

EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...

SourceLocation getExprLoc() const LLVM_READONLY

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

const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const

If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...

RoundingMode getRoundingMode() const

Represents a member of a struct/union/class.

const Expr * getSubExpr() const

bool isTrivial() const

Whether this function is "trivial" in some specialized C++ senses.

Represents a C11 generic selection.

Represents an implicitly-generated value initialization of an object of a given type.

Describes an C or C++ initializer list.

bool isTransparent() const

Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...

FieldDecl * getInitializedFieldInUnion()

If this initializes a union, specifies which field in the union to initialize.

unsigned getNumInits() const

Expr * getArrayFiller()

If this initializer list initializes an array with more elements than there are initializers in the l...

const Expr * getInit(unsigned Init) const

ArrayRef< Expr * > inits()

Represents a prvalue temporary that is written into memory so that a reference can bind to it.

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

ObjCBoxedExpr - used for generalized expression boxing.

ObjCEncodeExpr, used for @encode in Objective-C.

ObjCStringLiteral, used for Objective-C string literals i.e.

ParenExpr - This represents a parenthesized expression, e.g.

const Expr * getSubExpr() const

Pointer-authentication qualifiers.

bool isAddressDiscriminated() const

unsigned getExtraDiscriminator() const

PointerType - C99 6.7.5.1 - Pointer Declarators.

[C99 6.4.2.2] - A predefined identifier such as func.

A (possibly-)qualified type.

LangAS getAddressSpace() const

Return the address space of this type.

bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)

Represents a struct/union/class.

bool hasFlexibleArrayMember() const

field_iterator field_end() const

field_range fields() const

field_iterator field_begin() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

Encodes a location in the source.

StmtVisitorBase - This class implements a simple visitor for Stmt subclasses.

RetTy Visit(PTR(Stmt) S, ParamTys... P)

Stmt - This represents one statement.

StringLiteral - This represents a string literal expression, e.g.

uint32_t getCodeUnit(size_t i) const

Represents a reference to a non-type template parameter that has been substituted with a template arg...

Expr * getReplacement() const

virtual bool useFP16ConversionIntrinsics() const

Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...

Symbolic representation of typeid(T) for some type T.

The base class of the type hierarchy.

bool isSignedIntegerOrEnumerationType() const

Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...

bool isIncompleteArrayType() const

bool isSignedIntegerType() const

Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

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 isMemberDataPointerType() const

bool isBitIntType() const

bool isFloatingType() const

bool isUnsignedIntegerType() const

Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...

const T * getAs() const

Member-template getAs<specific type>'.

bool isRecordType() const

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

Expr * getSubExpr() 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.

Represents a GCC generic vector type.

QualType getElementType() const

bool isEmptyRecordForLayout(const ASTContext &Context, QualType T)

isEmptyRecordForLayout - Return true iff a structure contains only empty base classes (per isEmptyRec...

bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)

isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr

Matches expressions.

uint32_t Literal

Literals are represented as positive integers.

bool Const(InterpState &S, CodePtr OpPC, const T &Arg)

bool GE(InterpState &S, CodePtr OpPC)

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

@ Finalize

'finalize' clause, allowed on 'exit data' directive.

bool operator<(DeclarationName LHS, DeclarationName RHS)

Ordering on two declaration names.

@ SD_Static

Static storage duration.

@ Result

The result type of a method or function.

LangAS

Defines the address space values used by the address space qualifier of QualType.

const FunctionProtoType * T

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

@ Success

Template argument deduction was successful.

Structure with information about how a bitfield should be accessed.

unsigned Size

The total size of the bit-field, in bits.

llvm::IntegerType * Int64Ty

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * CharTy

char

llvm::IntegerType * Int32Ty

llvm::IntegerType * IntPtrTy

EvalResult is a struct with detailed info about an evaluated expression.


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