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

1

2

3

4

5

6

7

8

9

10

11

12

35#include "llvm/Analysis/ConstantFolding.h"

36#include "llvm/Analysis/ValueTracking.h"

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

38#include "llvm/IR/GlobalVariable.h"

39#include "llvm/IR/Instructions.h"

40#include "llvm/IR/Intrinsics.h"

41#include "llvm/IR/Type.h"

42#include

43

44using namespace clang;

45using namespace CodeGen;

46

48 "Clang max alignment greater than what LLVM supports?");

49

50void CodeGenFunction::EmitDecl(const Decl &D) {

52 case Decl::BuiltinTemplate:

53 case Decl::TranslationUnit:

54 case Decl::ExternCContext:

55 case Decl::Namespace:

56 case Decl::UnresolvedUsingTypename:

57 case Decl::ClassTemplateSpecialization:

58 case Decl::ClassTemplatePartialSpecialization:

59 case Decl::VarTemplateSpecialization:

60 case Decl::VarTemplatePartialSpecialization:

61 case Decl::TemplateTypeParm:

62 case Decl::UnresolvedUsingValue:

63 case Decl::NonTypeTemplateParm:

64 case Decl::CXXDeductionGuide:

65 case Decl::CXXMethod:

66 case Decl::CXXConstructor:

67 case Decl::CXXDestructor:

68 case Decl::CXXConversion:

69 case Decl::Field:

70 case Decl::MSProperty:

71 case Decl::IndirectField:

72 case Decl::ObjCIvar:

73 case Decl::ObjCAtDefsField:

74 case Decl::ParmVar:

75 case Decl::ImplicitParam:

76 case Decl::ClassTemplate:

77 case Decl::VarTemplate:

78 case Decl::FunctionTemplate:

79 case Decl::TypeAliasTemplate:

80 case Decl::TemplateTemplateParm:

81 case Decl::ObjCMethod:

82 case Decl::ObjCCategory:

83 case Decl::ObjCProtocol:

84 case Decl::ObjCInterface:

85 case Decl::ObjCCategoryImpl:

86 case Decl::ObjCImplementation:

87 case Decl::ObjCProperty:

88 case Decl::ObjCCompatibleAlias:

89 case Decl::PragmaComment:

90 case Decl::PragmaDetectMismatch:

91 case Decl::AccessSpec:

92 case Decl::LinkageSpec:

93 case Decl::Export:

94 case Decl::ObjCPropertyImpl:

95 case Decl::FileScopeAsm:

96 case Decl::TopLevelStmt:

97 case Decl::Friend:

98 case Decl::FriendTemplate:

99 case Decl::Block:

100 case Decl::OutlinedFunction:

101 case Decl::Captured:

102 case Decl::UsingShadow:

103 case Decl::ConstructorUsingShadow:

104 case Decl::ObjCTypeParam:

105 case Decl::Binding:

106 case Decl::UnresolvedUsingIfExists:

107 case Decl::HLSLBuffer:

108 llvm_unreachable("Declaration should not be in declstmts!");

109 case Decl::Record:

110 case Decl::CXXRecord:

114 return;

115 case Decl::Enum:

118 DI->EmitAndRetainType(getContext().getEnumType(cast(&D)));

119 return;

120 case Decl::Function:

121 case Decl::EnumConstant:

122 case Decl::StaticAssert:

123 case Decl::Label:

124 case Decl::Import:

125 case Decl::MSGuid:

126 case Decl::UnnamedGlobalConstant:

127 case Decl::TemplateParamObject:

128 case Decl::OMPThreadPrivate:

129 case Decl::OMPAllocate:

130 case Decl::OMPCapturedExpr:

131 case Decl::OMPRequires:

132 case Decl::Empty:

133 case Decl::Concept:

134 case Decl::ImplicitConceptSpecialization:

135 case Decl::LifetimeExtendedTemporary:

136 case Decl::RequiresExprBody:

137

138 return;

139

140 case Decl::NamespaceAlias:

142 DI->EmitNamespaceAlias(cast(D));

143 return;

144 case Decl::Using:

146 DI->EmitUsingDecl(cast(D));

147 return;

148 case Decl::UsingEnum:

150 DI->EmitUsingEnumDecl(cast(D));

151 return;

152 case Decl::UsingPack:

153 for (auto *Using : cast(D).expansions())

155 return;

156 case Decl::UsingDirective:

158 DI->EmitUsingDirective(cast(D));

159 return;

160 case Decl::Var:

161 case Decl::Decomposition: {

162 const VarDecl &VD = cast(D);

164 "Should not see file-scope variables inside a function!");

166 if (auto *DD = dyn_cast(&VD))

167 for (auto *B : DD->bindings())

168 if (auto *HD = B->getHoldingVar())

170 return;

171 }

172

173 case Decl::OMPDeclareReduction:

175

176 case Decl::OMPDeclareMapper:

178

179 case Decl::Typedef:

180 case Decl::TypeAlias: {

181 QualType Ty = cast(D).getUnderlyingType();

183 DI->EmitAndRetainType(Ty);

186 return;

187 }

188 }

189}

190

191

192

194 if (D.hasExternalStorage())

195

196 return;

197

198

199

200

202

203 if (D.getType()->isSamplerT())

204 return;

205

206 llvm::GlobalValue::LinkageTypes Linkage =

208

209

210

211

212

214 }

215

218

219 assert(D.hasLocalStorage());

221}

222

226

227

228 assert(D.isExternallyVisible() && "name shouldn't matter");

229 std::string ContextName;

231 if (auto *CD = dyn_cast(DC))

232 DC = cast(CD->getNonClosureContext());

233 if (const auto *FD = dyn_cast(DC))

235 else if (const auto *BD = dyn_cast(DC))

237 else if (const auto *OMD = dyn_cast(DC))

238 ContextName = OMD->getSelector().getAsString();

239 else

240 llvm_unreachable("Unknown context for static var decl");

241

242 ContextName += "." + D.getNameAsString();

243 return ContextName;

244}

245

247 const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage) {

248

249

250

251

252 if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&D])

253 return ExistingGV;

254

257

258

259 std::string Name;

260 if (D.hasAttr())

262 else

264

268

269

270

271 llvm::Constant *Init = nullptr;

273 D.hasAttr() || D.hasAttr())

274 Init = llvm::UndefValue::get(LTy);

275 else

277

278 llvm::GlobalVariable *GV = new llvm::GlobalVariable(

280 nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);

281 GV->setAlignment(getContext().getDeclAlign(&D).getAsAlign());

282

284 GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));

285

286 if (D.getTLSKind())

288

291

292

294 llvm::Constant *Addr = GV;

295 if (AS != ExpectedAS) {

297 *this, GV, AS, ExpectedAS,

299 getContext().getTargetAddressSpace(ExpectedAS)));

300 }

301

303

304

305

307

308

309

310 if (isa(DC) || isa(DC)) {

312

313 if (!DC)

314 return Addr;

315 }

316

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

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

322 else if (const auto *FD = dyn_cast(DC))

324 else {

325

326

327 assert(isa(DC) && "unexpected parent code decl");

328 }

330

333 }

334

335 return Addr;

336}

337

338

339

340

341

342llvm::GlobalVariable *

344 llvm::GlobalVariable *GV) {

346 llvm::Constant *Init = emitter.tryEmitForInitializer(D);

347

348

349

353 else if (D.hasFlexibleArrayInit(getContext()))

356

357

358 GV->setConstant(false);

359

361 }

362 return GV;

363 }

364

366

367#ifndef NDEBUG

369 D.getFlexibleArrayInitChars(getContext());

372 assert(VarSize == CstSize && "Emitted constant has unexpected size");

373#endif

374

375 bool NeedsDtor =

377

378 GV->setConstant(

379 D.getType().isConstantStorage(getContext(), true, !NeedsDtor));

380 GV->replaceInitializer(Init);

381

382 emitter.finalize(GV);

383

385

386

387

389 }

390

391 return GV;

392}

393

395 llvm::GlobalValue::LinkageTypes Linkage) {

396

397

398

401

402

403

405 setAddrOfLocalVar(&D, Address(addr, elemTy, alignment));

406

407

408

409

410 if (D.getType()->isVariablyModifiedType())

412

413

414 llvm::Type *expectedType = addr->getType();

415

416 llvm::GlobalVariable *var =

417 castllvm::GlobalVariable(addr->stripPointerCasts());

418

419

420

421

422

425

426 if (D.getInit() && !isCudaSharedVar)

428

430

431 if (D.hasAttr())

433

434 if (auto *SA = D.getAttr())

435 var->addAttribute("bss-section", SA->getName());

436 if (auto *SA = D.getAttr())

437 var->addAttribute("data-section", SA->getName());

438 if (auto *SA = D.getAttr())

439 var->addAttribute("rodata-section", SA->getName());

440 if (auto *SA = D.getAttr())

441 var->addAttribute("relro-section", SA->getName());

442

443 if (const SectionAttr *SA = D.getAttr())

444 var->setSection(SA->getName());

445

448 else if (D.hasAttr())

450

453

454

455

456

457

458

459 llvm::Constant *castedAddr =

460 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);

461 LocalDeclMap.find(&D)->second = Address(castedAddr, elemTy, alignment);

463

465

466

471 }

472}

473

474namespace {

477 CodeGenFunction::Destroyer *destroyer,

478 bool useEHCleanupForArray)

479 : addr(addr), type(type), destroyer(destroyer),

480 useEHCleanupForArray(useEHCleanupForArray) {}

481

484 CodeGenFunction::Destroyer *destroyer;

485 bool useEHCleanupForArray;

486

488

489 bool useEHCleanupForArray =

490 flags.isForNormalCleanup() && this->useEHCleanupForArray;

491

492 CGF.emitDestroy(addr, type, destroyer, useEHCleanupForArray);

493 }

494 };

495

496 template

499 : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {}

500

501 llvm::Value *NRVOFlag;

504

506

507 bool NRVO = flags.isForNormalCleanup() && NRVOFlag;

508

509 llvm::BasicBlock *SkipDtorBB = nullptr;

510 if (NRVO) {

511

512 llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused");

514 llvm::Value *DidNRVO =

516 CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);

518 }

519

520 static_cast<Derived *>(this)->emitDestructorCall(CGF);

521

522 if (NRVO) CGF.EmitBlock(SkipDtorBB);

523 }

524

525 virtual ~DestroyNRVOVariable() = default;

526 };

527

528 struct DestroyNRVOVariableCXX final

529 : DestroyNRVOVariable {

532 : DestroyNRVOVariable(addr, type, NRVOFlag),

533 Dtor(Dtor) {}

534

536

539 false,

540 false, Loc, Ty);

541 }

542 };

543

544 struct DestroyNRVOVariableC final

545 : DestroyNRVOVariable {

546 DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)

547 : DestroyNRVOVariable(addr, Ty, NRVOFlag) {}

548

551 }

552 };

553

556 CallStackRestore(Address Stack) : Stack(Stack) {}

557 bool isRedundantBeforeReturn() override { return true; }

560 CGF.Builder.CreateStackRestore(V);

561 }

562 };

563

565 std::pair<llvm::Value *, llvm::Value *> AddrSizePair;

566 KmpcAllocFree(const std::pair<llvm::Value *, llvm::Value *> &AddrSizePair)

567 : AddrSizePair(AddrSizePair) {}

568 void Emit(CodeGenFunction &CGF, Flags EmissionFlags) override {

571 }

572 };

573

576 ExtendGCLifetime(const VarDecl *var) : Var(*var) {}

577

579

580

586 }

587 };

588

590 llvm::Constant *CleanupFn;

593

594 CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,

596 : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}

597

601

602

604

605

606

607

608

609

610

612 llvm::Value *Arg =

614

620 }

621 };

622}

623

624

625

629 switch (lifetime) {

631 llvm_unreachable("present but none");

632

634

635 break;

636

639 (var.hasAttr()

642

644 CGF.pushDestroy(cleanupKind, addr, var.getType(), destroyer,

646 break;

647 }

649

650 break;

651

653

654

657 true);

658 break;

659 }

660}

661

663 if (const Expr *e = dyn_cast(s)) {

664

665

666 s = e = e->IgnoreParenCasts();

667

668 if (const DeclRefExpr *ref = dyn_cast(e))

669 return (ref->getDecl() == &var);

670 if (const BlockExpr *be = dyn_cast(e)) {

671 const BlockDecl *block = be->getBlockDecl();

672 for (const auto &I : block->captures()) {

673 if (I.getVariable() == &var)

674 return true;

675 }

676 }

677 }

678

679 for (const Stmt *SubStmt : s->children())

680

682 return true;

683

684 return false;

685}

686

688 if (decl) return false;

689 if (!isa(decl)) return false;

690 const VarDecl *var = cast(decl);

692}

693

695 const LValue &destLV, const Expr *init) {

696 bool needsCast = false;

697

699 switch (castExpr->getCastKind()) {

700

701 case CK_NoOp:

702 case CK_BitCast:

703 case CK_BlockPointerToObjCPointerCast:

704 needsCast = true;

705 break;

706

707

708

709 case CK_LValueToRValue: {

710 const Expr *srcExpr = castExpr->getSubExpr();

712 return false;

713

714

716

717

719 if (needsCast) {

721 }

722

723

726 } else {

729 }

730 return true;

731 }

732

733

734 default:

735 return false;

736 }

737

738 init = castExpr->getSubExpr();

739 }

740 return false;

741}

742

747}

748

751 if (SanOpts.has(SanitizerKind::NullabilityAssign))

752 return;

753

756 return;

757

758

759

760 SanitizerScope SanScope(this);

762 llvm::Constant *StaticData[] = {

764 llvm::ConstantInt::get(Int8Ty, 0),

767 SanitizerHandler::TypeMismatch, StaticData, RHS);

768}

769

771 LValue lvalue, bool capturedByInit) {

773 if (!lifetime) {

775 if (capturedByInit)

779 return;

780 }

781

782 if (const CXXDefaultInitExpr *DIE = dyn_cast(init))

783 init = DIE->getExpr();

784

785

786

787 if (auto *EWC = dyn_cast(init)) {

788 CodeGenFunction::RunCleanupsScope Scope(*this);

789 return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit);

790 }

791

792

793

794

795

796 bool accessedByInit = false;

798 accessedByInit = (capturedByInit || isAccessedBy(D, init));

799 if (accessedByInit) {

800 LValue tempLV = lvalue;

801

802 if (capturedByInit) {

803

804

806 cast(D),

807 false));

808 }

809

812

813

816

817

818 else

820 }

821

822

823 llvm::Value *value = nullptr;

824

825 switch (lifetime) {

827 llvm_unreachable("present but none");

828

830 if (D || !isa(D) || !cast(D)->isARCPseudoStrong()) {

832 break;

833 }

834

835

836

837 [[fallthrough]];

838 }

839

842 break;

843

845

846

848 return;

849 }

850

851

852

853

855

857 if (accessedByInit)

859 else

861 return;

862 }

863

866 break;

867 }

868

870

872

873

874

875

880 return;

881 }

882

884}

885

886

887

889 unsigned &NumStores) {

890

891 if (isallvm::ConstantAggregateZero(Init) ||

892 isallvm::ConstantPointerNull(Init) ||

893 isallvm::UndefValue(Init))

894 return true;

895 if (isallvm::ConstantInt(Init) || isallvm::ConstantFP(Init) ||

896 isallvm::ConstantVector(Init) || isallvm::BlockAddress(Init) ||

897 isallvm::ConstantExpr(Init))

898 return Init->isNullValue() || NumStores--;

899

900

901 if (isallvm::ConstantArray(Init) || isallvm::ConstantStruct(Init)) {

902 for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {

903 llvm::Constant *Elt = castllvm::Constant(Init->getOperand(i));

905 return false;

906 }

907 return true;

908 }

909

910 if (llvm::ConstantDataSequential *CDS =

911 dyn_castllvm::ConstantDataSequential(Init)) {

912 for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {

913 llvm::Constant *Elt = CDS->getElementAsConstant(i);

915 return false;

916 }

917 return true;

918 }

919

920

921 return false;

922}

923

924

925

929 bool IsAutoInit) {

930 assert(Init->isNullValue() && !isallvm::UndefValue(Init) &&

931 "called emitStoresForInitAfterBZero for zero or undef value.");

932

933 if (isallvm::ConstantInt(Init) || isallvm::ConstantFP(Init) ||

934 isallvm::ConstantVector(Init) || isallvm::BlockAddress(Init) ||

935 isallvm::ConstantExpr(Init)) {

936 auto *I = Builder.CreateStore(Init, Loc, isVolatile);

937 if (IsAutoInit)

938 I->addAnnotationMetadata("auto-init");

939 return;

940 }

941

942 if (llvm::ConstantDataSequential *CDS =

943 dyn_castllvm::ConstantDataSequential(Init)) {

944 for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {

945 llvm::Constant *Elt = CDS->getElementAsConstant(i);

946

947

948 if (!Elt->isNullValue() && !isallvm::UndefValue(Elt))

950 CGM, Elt, Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,

951 Builder, IsAutoInit);

952 }

953 return;

954 }

955

956 assert((isallvm::ConstantStruct(Init) || isallvm::ConstantArray(Init)) &&

957 "Unknown value type!");

958

959 for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {

960 llvm::Constant *Elt = castllvm::Constant(Init->getOperand(i));

961

962

963 if (!Elt->isNullValue() && !isallvm::UndefValue(Elt))

965 Builder.CreateConstInBoundsGEP2_32(Loc, 0, i),

966 isVolatile, Builder, IsAutoInit);

967 }

968}

969

970

971

972

974 uint64_t GlobalSize) {

975

976 if (isallvm::ConstantAggregateZero(Init)) return true;

977

978

979

980

981

982 unsigned StoreBudget = 6;

983 uint64_t SizeLimit = 32;

984

985 return GlobalSize > SizeLimit &&

987}

988

989

990

991

992

993

995 uint64_t GlobalSize,

996 const llvm::DataLayout &DL) {

997 uint64_t SizeLimit = 32;

998 if (GlobalSize <= SizeLimit)

999 return nullptr;

1000 return llvm::isBytewiseValue(Init, DL);

1001}

1002

1003

1004

1005

1007 uint64_t GlobalByteSize) {

1008

1009 uint64_t ByteSizeLimit = 64;

1011 return false;

1012 if (GlobalByteSize <= ByteSizeLimit)

1013 return true;

1014 return false;

1015}

1016

1018

1019

1021 llvm::Type *Ty) {

1022 if (isPattern == IsPattern::Yes)

1024 else

1025 return llvm::Constant::getNullValue(Ty);

1026}

1027

1029 llvm::Constant *constant);

1030

1031

1034 llvm::StructType *STy,

1035 llvm::Constant *constant) {

1036 const llvm::DataLayout &DL = CGM.getDataLayout();

1037 const llvm::StructLayout *Layout = DL.getStructLayout(STy);

1038 llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext());

1039 unsigned SizeSoFar = 0;

1041 bool NestedIntact = true;

1042 for (unsigned i = 0, e = STy->getNumElements(); i != e; i++) {

1043 unsigned CurOff = Layout->getElementOffset(i);

1044 if (SizeSoFar < CurOff) {

1045 assert(!STy->isPacked());

1046 auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar);

1048 }

1049 llvm::Constant *CurOp;

1050 if (constant->isZeroValue())

1051 CurOp = llvm::Constant::getNullValue(STy->getElementType(i));

1052 else

1053 CurOp = castllvm::Constant(constant->getAggregateElement(i));

1055 if (CurOp != NewOp)

1056 NestedIntact = false;

1057 Values.push_back(NewOp);

1058 SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType());

1059 }

1060 unsigned TotalSize = Layout->getSizeInBytes();

1061 if (SizeSoFar < TotalSize) {

1062 auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar);

1064 }

1065 if (NestedIntact && Values.size() == STy->getNumElements())

1066 return constant;

1067 return llvm::ConstantStruct::getAnon(Values, STy->isPacked());

1068}

1069

1070

1071

1073 llvm::Constant *constant) {

1074 llvm::Type *OrigTy = constant->getType();

1075 if (const auto STy = dyn_castllvm::StructType(OrigTy))

1077 if (auto *ArrayTy = dyn_castllvm::ArrayType(OrigTy)) {

1079 uint64_t Size = ArrayTy->getNumElements();

1080 if (!Size)

1081 return constant;

1082 llvm::Type *ElemTy = ArrayTy->getElementType();

1083 bool ZeroInitializer = constant->isNullValue();

1084 llvm::Constant *OpValue, *PaddedOp;

1085 if (ZeroInitializer) {

1086 OpValue = llvm::Constant::getNullValue(ElemTy);

1088 }

1089 for (unsigned Op = 0; Op != Size; ++Op) {

1090 if (!ZeroInitializer) {

1091 OpValue = constant->getAggregateElement(Op);

1093 }

1094 Values.push_back(PaddedOp);

1095 }

1096 auto *NewElemTy = Values[0]->getType();

1097 if (NewElemTy == ElemTy)

1098 return constant;

1099 auto *NewArrayTy = llvm::ArrayType::get(NewElemTy, Size);

1100 return llvm::ConstantArray::get(NewArrayTy, Values);

1101 }

1102

1103

1104

1105 return constant;

1106}

1107

1109 llvm::Constant *Constant,

1111 auto FunctionName = [&](const DeclContext *DC) -> std::string {

1112 if (const auto *FD = dyn_cast(DC)) {

1113 if (const auto *CC = dyn_cast(FD))

1114 return CC->getNameAsString();

1115 if (const auto *CD = dyn_cast(FD))

1116 return CD->getNameAsString();

1118 } else if (const auto *OM = dyn_cast(DC)) {

1119 return OM->getNameAsString();

1120 } else if (isa(DC)) {

1121 return "";

1122 } else if (isa(DC)) {

1123 return "";

1124 } else {

1125 llvm_unreachable("expected a function or method");

1126 }

1127 };

1128

1129

1130

1131 llvm::GlobalVariable *&CacheEntry = InitializerConstants[&D];

1132 if (!CacheEntry || CacheEntry->getInitializer() != Constant) {

1133 auto *Ty = Constant->getType();

1134 bool isConstant = true;

1135 llvm::GlobalVariable *InsertBefore = nullptr;

1136 unsigned AS =

1138 std::string Name;

1139 if (D.hasGlobalStorage())

1142 Name = ("__const." + FunctionName(DC) + "." + D.getName()).str();

1143 else

1144 llvm_unreachable("local variable has no parent function or method");

1145 llvm::GlobalVariable *GV = new llvm::GlobalVariable(

1146 getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,

1147 Constant, Name, InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);

1148 GV->setAlignment(Align.getAsAlign());

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

1150 CacheEntry = GV;

1151 } else if (CacheEntry->getAlignment() < uint64_t(Align.getQuantity())) {

1152 CacheEntry->setAlignment(Align.getAsAlign());

1153 }

1154

1155 return Address(CacheEntry, CacheEntry->getValueType(), Align);

1156}

1157

1161 llvm::Constant *Constant,

1165}

1166

1170 llvm::Constant *constant, bool IsAutoInit) {

1171 auto *Ty = constant->getType();

1172 uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty);

1173 if (!ConstantSize)

1174 return;

1175

1176 bool canDoSingleStore = Ty->isIntOrIntVectorTy() ||

1177 Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy();

1178 if (canDoSingleStore) {

1179 auto *I = Builder.CreateStore(constant, Loc, isVolatile);

1180 if (IsAutoInit)

1181 I->addAnnotationMetadata("auto-init");

1182 return;

1183 }

1184

1185 auto *SizeVal = llvm::ConstantInt::get(CGM.IntPtrTy, ConstantSize);

1186

1187

1188

1190 auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(CGM.Int8Ty, 0),

1191 SizeVal, isVolatile);

1192 if (IsAutoInit)

1193 I->addAnnotationMetadata("auto-init");

1194

1195 bool valueAlreadyCorrect =

1196 constant->isNullValue() || isallvm::UndefValue(constant);

1197 if (!valueAlreadyCorrect) {

1198 Loc = Loc.withElementType(Ty);

1200 IsAutoInit);

1201 }

1202 return;

1203 }

1204

1205

1206 llvm::Value *Pattern =

1208 if (Pattern) {

1209 uint64_t Value = 0x00;

1210 if (!isallvm::UndefValue(Pattern)) {

1211 const llvm::APInt &AP = castllvm::ConstantInt(Pattern)->getValue();

1212 assert(AP.getBitWidth() <= 8);

1213 Value = AP.getLimitedValue();

1214 }

1215 auto *I = Builder.CreateMemSet(

1216 Loc, llvm::ConstantInt::get(CGM.Int8Ty, Value), SizeVal, isVolatile);

1217 if (IsAutoInit)

1218 I->addAnnotationMetadata("auto-init");

1219 return;

1220 }

1221

1222

1223

1224 bool IsTrivialAutoVarInitPattern =

1228 if (auto *STy = dyn_castllvm::StructType(Ty)) {

1229 if (STy == Loc.getElementType() ||

1230 (STy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {

1231 const llvm::StructLayout *Layout =

1233 for (unsigned i = 0; i != constant->getNumOperands(); i++) {

1236 Address EltPtr = Builder.CreateConstInBoundsByteGEP(

1237 Loc.withElementType(CGM.Int8Ty), CurOff);

1239 constant->getAggregateElement(i), IsAutoInit);

1240 }

1241 return;

1242 }

1243 } else if (auto *ATy = dyn_castllvm::ArrayType(Ty)) {

1244 if (ATy == Loc.getElementType() ||

1245 (ATy != Loc.getElementType() && IsTrivialAutoVarInitPattern)) {

1246 for (unsigned i = 0; i != ATy->getNumElements(); i++) {

1247 Address EltPtr = Builder.CreateConstGEP(

1248 Loc.withElementType(ATy->getElementType()), i);

1250 constant->getAggregateElement(i), IsAutoInit);

1251 }

1252 return;

1253 }

1254 }

1255 }

1256

1257

1258 auto *I =

1259 Builder.CreateMemCpy(Loc,

1261 CGM, D, Builder, constant, Loc.getAlignment()),

1262 SizeVal, isVolatile);

1263 if (IsAutoInit)

1264 I->addAnnotationMetadata("auto-init");

1265}

1266

1270 llvm::Type *ElTy = Loc.getElementType();

1271 llvm::Constant *constant =

1272 constWithPadding(CGM, IsPattern::No, llvm::Constant::getNullValue(ElTy));

1274 true);

1275}

1276

1280 llvm::Type *ElTy = Loc.getElementType();

1283 assert(!isallvm::UndefValue(constant));

1285 true);

1286}

1287

1289 auto *Ty = constant->getType();

1290 if (isallvm::UndefValue(constant))

1291 return true;

1292 if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())

1293 for (llvm::Use &Op : constant->operands())

1295 return true;

1296 return false;

1297}

1298

1300 llvm::Constant *constant) {

1301 auto *Ty = constant->getType();

1302 if (isallvm::UndefValue(constant))

1304 if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))

1305 return constant;

1307 return constant;

1309 for (unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {

1310 auto *OpValue = castllvm::Constant(constant->getOperand(Op));

1311 Values[Op] = replaceUndef(CGM, isPattern, OpValue);

1312 }

1313 if (Ty->isStructTy())

1314 return llvm::ConstantStruct::get(castllvm::StructType(Ty), Values);

1315 if (Ty->isArrayTy())

1316 return llvm::ConstantArray::get(castllvm::ArrayType(Ty), Values);

1317 assert(Ty->isVectorTy());

1318 return llvm::ConstantVector::get(Values);

1319}

1320

1321

1322

1323

1328}

1329

1330

1331

1332

1334 llvm::Value *Addr) {

1335 if (!ShouldEmitLifetimeMarkers)

1336 return nullptr;

1337

1338 assert(Addr->getType()->getPointerAddressSpace() ==

1340 "Pointer should be in alloca address space");

1341 llvm::Value *SizeV = llvm::ConstantInt::get(

1342 Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue());

1343 llvm::CallInst *C =

1345 C->setDoesNotThrow();

1346 return SizeV;

1347}

1348

1350 assert(Addr->getType()->getPointerAddressSpace() ==

1352 "Pointer should be in alloca address space");

1353 llvm::CallInst *C =

1355 C->setDoesNotThrow();

1356}

1357

1360

1361

1364

1365

1367 while (getContext().getAsVariableArrayType(Type1D)) {

1369 if (auto *C = dyn_castllvm::ConstantInt(VlaSize.NumElts))

1371 else {

1372

1373 Twine Name = Twine("__vla_expr") + Twine(VLAExprCounter++);

1375 StringRef NameRef = Name.toStringRef(Buffer);

1377 VLAExprNames.push_back(&Ident);

1378 auto SizeExprAddr =

1381 Dimensions.emplace_back(SizeExprAddr.getPointer(),

1383 }

1384 Type1D = VlaSize.Type;

1385 }

1386

1387 if (!EmitDebugInfo)

1388 return;

1389

1390

1391

1392

1393 unsigned NameIdx = 0;

1394 for (auto &VlaSize : Dimensions) {

1395 llvm::Metadata *MD;

1396 if (auto *C = dyn_castllvm::ConstantInt(VlaSize.NumElts))

1397 MD = llvm::ConstantAsMetadata::get(C);

1398 else {

1399

1400 const IdentifierInfo *NameIdent = VLAExprNames[NameIdx++];

1402 SizeTy->getScalarSizeInBits(), false);

1407 ArtificialDecl->setImplicit();

1408

1411 }

1412 assert(MD && "No Size expression debug node created");

1414 }

1415}

1416

1417

1418

1419CodeGenFunction::AutoVarEmission

1422 assert(

1425

1426 AutoVarEmission emission(D);

1427

1428 bool isEscapingByRef = D.isEscapingByref();

1429 emission.IsEscapingByRef = isEscapingByRef;

1430

1432

1433

1436

1439

1445 else

1446 OpenMPLocalAddr =

1450

1451 bool NRVO = getLangOpts().ElideConstructors && D.isNRVOVariable();

1452

1454 address = OpenMPLocalAddr;

1455 AllocaAddr = OpenMPLocalAddr;

1457

1458

1459

1460

1461

1462

1463

1464

1466 (D.isConstexpr() ||

1468 getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) &&

1469 D.getInit()->isConstantInitializer(getContext(), false)))) {

1470

1471

1472

1473

1474

1475

1476 bool NeedsDtor =

1481 !isEscapingByRef &&

1484

1485

1487 assert(emission.wasEmittedAsGlobal());

1488 return emission;

1489 }

1490

1491

1492 emission.IsConstantAggregate = true;

1493 }

1494

1495

1496

1497

1498

1499 if (NRVO) {

1500

1501

1502

1504 AllocaAddr =

1507 ;

1508

1510 const auto *RD = RecordTy->getDecl();

1511 const auto *CXXRD = dyn_cast(RD);

1512 if ((CXXRD && !CXXRD->hasTrivialDestructor()) ||

1513 RD->isNonTrivialToPrimitiveDestroy()) {

1514

1515

1516

1522

1523

1525 emission.NRVOFlag = NRVOFlag.getPointer();

1526 }

1527 }

1528 } else {

1530 llvm::Type *allocaTy;

1531 if (isEscapingByRef) {

1533 allocaTy = byrefInfo.Type;

1534 allocaAlignment = byrefInfo.ByrefAlignment;

1535 } else {

1537 allocaAlignment = alignment;

1538 }

1539

1540

1541

1542

1543 address = CreateTempAlloca(allocaTy, allocaAlignment, D.getName(),

1544 nullptr, &AllocaAddr);

1545

1546

1547

1548

1549 bool IsMSCatchParam =

1551

1552

1553

1555

1556

1557

1558

1559

1560

1561

1562

1563

1564

1565

1566

1567

1571 emission.SizeForLifetimeMarkers =

1573 }

1574 } else {

1575 assert(!emission.useLifetimeMarkers());

1576 }

1577 }

1578 } else {

1580

1581

1582

1583

1584

1585

1586 bool VarAllocated = false;

1587 if (getLangOpts().OpenMPIsTargetDevice) {

1589 if (RT.isDelayedVariableLengthDecl(*this, &D)) {

1590

1591 std::pair<llvm::Value *, llvm::Value *> AddrSizePair =

1593

1594

1598 address = Base.getAddress();

1599

1600

1601

1602

1604

1605

1606 VarAllocated = true;

1607 }

1608 }

1609

1610 if (!VarAllocated) {

1611 if (!DidCallStackSave) {

1612

1615

1616 llvm::Value *V = Builder.CreateStackSave();

1619

1620 DidCallStackSave = true;

1621

1622

1623

1625 }

1626

1629

1630

1631 address = CreateTempAlloca(llvmTy, alignment, "vla", VlaSize.NumElts,

1632 &AllocaAddr);

1633 }

1634

1635

1636

1637

1639 }

1640

1641 setAddrOfLocalVar(&D, address);

1642 emission.Addr = address;

1643 emission.AllocaAddr = AllocaAddr;

1644

1645

1647 Address DebugAddr = address;

1650

1651

1652 if (UsePointerValue) {

1655 }

1657 UsePointerValue);

1658 }

1659

1662

1663

1664 if (emission.useLifetimeMarkers())

1666 emission.getOriginalAllocatedAddress(),

1667 emission.getSizeForLifetimeMarkers());

1668

1669 return emission;

1670}

1671

1673

1674

1675

1677 if (const Expr *E = dyn_cast(S))

1679 for (const Stmt *SubStmt : S->children())

1681 return true;

1682 return false;

1683}

1684

1685

1686

1688

1689

1691

1692 if (const BlockExpr *BE = dyn_cast(E)) {

1694 for (const auto &I : Block->captures()) {

1695 if (I.getVariable() == &Var)

1696 return true;

1697 }

1698

1699

1700 return false;

1701 }

1702

1703 if (const StmtExpr *SE = dyn_cast(E)) {

1705 for (const auto *BI : CS->body())

1706 if (const auto *BIE = dyn_cast(BI)) {

1708 return true;

1709 }

1710 else if (const auto *DS = dyn_cast(BI)) {

1711

1712 for (const auto *I : DS->decls()) {

1713 if (const auto *VD = dyn_cast((I))) {

1716 return true;

1717 }

1718 }

1719 }

1720 else

1721

1722

1723 return true;

1724 return false;

1725 }

1726

1729 return true;

1730

1731 return false;

1732}

1733

1734

1735

1738 return true;

1739

1744 !Construct->requiresZeroInitialization())

1745 return true;

1746

1747 return false;

1748}

1749

1750void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,

1754 auto trivialAutoVarInitMaxSize =

1757 bool isVolatile = type.isVolatileQualified();

1758 if (Size.isZero()) {

1759

1760

1761

1762

1763

1764 auto allocSize = CGM.getDataLayout().getTypeAllocSize(Loc.getElementType());

1765 switch (trivialAutoVarInit) {

1767 llvm_unreachable("Uninitialized handled by caller");

1770 return;

1771 if (trivialAutoVarInitMaxSize > 0 &&

1772 allocSize > trivialAutoVarInitMaxSize)

1773 return;

1775 break;

1778 return;

1779 if (trivialAutoVarInitMaxSize > 0 &&

1780 allocSize > trivialAutoVarInitMaxSize)

1781 return;

1783 break;

1784 }

1785 return;

1786 }

1787

1788

1789

1790

1791

1792

1794 if (!VlaType)

1795 return;

1797 auto SizeVal = VlaSize.NumElts;

1799 switch (trivialAutoVarInit) {

1801 llvm_unreachable("Uninitialized handled by caller");

1802

1805 return;

1806 if (!EltSize.isOne())

1809 SizeVal, isVolatile);

1810 I->addAnnotationMetadata("auto-init");

1811 break;

1812 }

1813

1816 return;

1817 llvm::Type *ElTy = Loc.getElementType();

1821 llvm::BasicBlock *SetupBB = createBasicBlock("vla-setup.loop");

1822 llvm::BasicBlock *LoopBB = createBasicBlock("vla-init.loop");

1823 llvm::BasicBlock *ContBB = createBasicBlock("vla-init.cont");

1824 llvm::Value *IsZeroSizedVLA = Builder.CreateICmpEQ(

1825 SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0),

1826 "vla.iszerosized");

1827 Builder.CreateCondBr(IsZeroSizedVLA, ContBB, SetupBB);

1829 if (!EltSize.isOne())

1831 llvm::Value *BaseSizeInChars =

1835 Begin.emitRawPointer(*this),

1836 SizeVal, "vla.end");

1837 llvm::BasicBlock *OriginBB = Builder.GetInsertBlock();

1839 llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur");

1840 Cur->addIncoming(Begin.emitRawPointer(*this), OriginBB);

1841 CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize);

1842 auto *I =

1845 CGM, D, Builder, Constant, ConstantAlign),

1846 BaseSizeInChars, isVolatile);

1847 I->addAnnotationMetadata("auto-init");

1848 llvm::Value *Next =

1850 llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone");

1851 Builder.CreateCondBr(Done, ContBB, LoopBB);

1852 Cur->addIncoming(Next, LoopBB);

1854 } break;

1855 }

1856}

1857

1859 assert(emission.Variable && "emission was not valid!");

1860

1861

1862 if (emission.wasEmittedAsGlobal()) return;

1863

1864 const VarDecl &D = *emission.Variable;

1867

1868

1870

1871

1872

1876 return;

1877 }

1879 }

1880

1881

1882 if (emission.IsEscapingByRef)

1884

1885

1886

1887

1888 if (Init &&

1889 type.isNonTrivialToPrimitiveDefaultInitialize() ==

1892 if (emission.IsEscapingByRef)

1895 return;

1896 }

1897

1898

1899

1900

1901 bool capturedByInit =

1903

1904 bool locIsByrefHeader = !capturedByInit;

1906 locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr;

1907

1908 auto hasNoTrivialAutoVarInitAttr = [&](const Decl *D) {

1909 return D && D->hasAttr();

1910 };

1911

1913 ((D.isConstexpr() || D.getAttr() ||

1914 hasNoTrivialAutoVarInitAttr(type->getAsTagDecl()) ||

1915 hasNoTrivialAutoVarInitAttr(CurFuncDecl))

1918

1919 auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {

1920 if (trivialAutoVarInit ==

1922 return;

1923

1924

1925 if (emission.IsEscapingByRef && !locIsByrefHeader)

1927

1928 return emitZeroOrPatternForAutoVarInit(type, D, Loc);

1929 };

1930

1932 return initializeWhatIsTechnicallyUninitialized(Loc);

1933

1934 llvm::Constant *constant = nullptr;

1935 if (emission.IsConstantAggregate ||

1936 D.mightBeUsableInConstantExpressions(getContext())) {

1937 assert(!capturedByInit && "constant init contains a capturing block?");

1939 if (constant && !constant->isZeroValue() &&

1940 (trivialAutoVarInit !=

1944 ? IsPattern::Yes

1945 : IsPattern::No;

1946

1947

1948

1949

1950

1951

1954 }

1955

1956 if (constant && type->isBitIntType() &&

1958

1959

1960

1961 llvm::Type *LoadType =

1963 constant = llvm::ConstantFoldLoadFromConst(

1964 constant, LoadType, llvm::APInt::getZero(32), CGM.getDataLayout());

1965 }

1966 }

1967

1968 if (!constant) {

1969 if (trivialAutoVarInit !=

1971

1972

1973

1974

1975

1976

1977

1978

1980 initializeWhatIsTechnicallyUninitialized(Loc);

1981 }

1982 }

1986 }

1987

1989

1990 if (!emission.IsConstantAggregate) {

1991

1995 }

1996

1998 type.isVolatileQualified(), Builder, constant,

1999 false);

2000}

2001

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2013 LValue lvalue, bool capturedByInit) {

2015

2016 if (type->isReferenceType()) {

2018 if (capturedByInit)

2021 return;

2022 }

2026 return;

2029 if (capturedByInit)

2032 return;

2033 }

2035 if (type->isAtomicType()) {

2037 } else {

2039 if (isa(D))

2041 else if (auto *FD = dyn_cast(D))

2043

2048 }

2049 return;

2050 }

2051 llvm_unreachable("bad evaluation kind");

2052}

2053

2054

2056 const CodeGenFunction::AutoVarEmission &emission,

2059

2060

2061

2062 Address addr = emission.getObjectAddress(*this);

2063

2064 const VarDecl *var = emission.Variable;

2066

2069

2070 switch (dtorKind) {

2072 llvm_unreachable("no cleanup for trivially-destructible variable");

2073

2075

2076

2077 if (emission.NRVOFlag) {

2078 assert(type->isArrayType());

2080 EHStack.pushCleanup(cleanupKind, addr, type, dtor,

2081 emission.NRVOFlag);

2082 return;

2083 }

2084 break;

2085

2087

2088 if (var->isARCPseudoStrong()) return;

2089

2090

2092

2093

2094 if (var->hasAttr())

2096 break;

2097

2099 break;

2100

2103 if (emission.NRVOFlag) {

2104 assert(type->isArrayType());

2105 EHStack.pushCleanup(cleanupKind, addr,

2106 emission.NRVOFlag, type);

2107 return;

2108 }

2109 break;

2110 }

2111

2112

2113 if (!destroyer) destroyer = getDestroyer(dtorKind);

2114

2115

2116

2117 bool useEHCleanup = (cleanupKind & EHCleanup);

2118 EHStack.pushCleanup(cleanupKind, addr, type, destroyer,

2119 useEHCleanup);

2120}

2121

2123 assert(emission.Variable && "emission was not valid!");

2124

2125

2126 if (emission.wasEmittedAsGlobal()) return;

2127

2128

2129

2131

2132 const VarDecl &D = *emission.Variable;

2133

2134

2137

2138

2140 D.hasAttr()) {

2142 }

2143

2144

2145 if (const CleanupAttr *CA = D.getAttr()) {

2146 const FunctionDecl *FD = CA->getFunctionDecl();

2147

2149 assert(F && "Could not find function!");

2150

2153 }

2154

2155

2156

2157

2158 if (emission.IsEscapingByRef &&

2161 if (emission.Variable->getType().isObjCGCWeak())

2164 false,

2166 }

2167}

2168

2171 switch (kind) {

2172 case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor");

2181 }

2182 llvm_unreachable("Unknown DestructionKind");

2183}

2184

2185

2186

2189 assert(dtorKind && "cannot push destructor for trivial type");

2191

2193}

2194

2195

2196

2199 assert(dtorKind && "cannot push destructor for trivial type");

2200

2204}

2205

2208 bool useEHCleanupForArray) {

2209 pushFullExprCleanup(cleanupKind, addr, type,

2210 destroyer, useEHCleanupForArray);

2211}

2212

2213

2214

2217 assert(dtorKind && "cannot push destructor for trivial type");

2218

2222}

2223

2226 bool useEHCleanupForArray) {

2227 llvm::Instruction *DominatingIP =

2229 pushDestroy(cleanupKind, addr, type, destroyer, useEHCleanupForArray);

2232}

2233

2235 EHStack.pushCleanup(Kind, SPMem);

2236}

2237

2239 CleanupKind Kind, std::pair<llvm::Value *, llvm::Value *> AddrSizePair) {

2240 EHStack.pushCleanup(Kind, AddrSizePair);

2241}

2242

2245 Destroyer *destroyer,

2246 bool useEHCleanupForArray) {

2247

2248

2250

2251

2252

2253

2254

2256 useEHCleanupForArray);

2257

2258

2259

2260 return pushCleanupAfterFullExprWithActiveFlag(

2262 useEHCleanupForArray);

2263 }

2264

2265

2266

2267 using ConditionalCleanupType =

2271

2272

2273

2274 AllocaTrackerRAII DeactivationAllocas(*this);

2276

2277 pushCleanupAndDeferDeactivation(

2278 cleanupKind, SavedAddr, type, destroyer, useEHCleanupForArray);

2281

2282 cleanup.AddAuxAllocas(std::move(DeactivationAllocas).Take());

2283

2284

2285

2286

2287

2288

2290 pushCleanupAfterFullExprWithActiveFlag(

2291 cleanupKind, ActiveFlagForLifetimeExt, SavedAddr, type, destroyer,

2292 useEHCleanupForArray);

2293}

2294

2295

2296

2297

2298

2299

2300

2301

2302

2303

2304

2305

2307 Destroyer *destroyer,

2308 bool useEHCleanupForArray) {

2311 return destroyer(*this, addr, type);

2312

2314

2318

2319

2320 bool checkZeroLength = true;

2321

2322

2323 if (llvm::ConstantInt *constLength = dyn_castllvm::ConstantInt(length)) {

2324

2325 if (constLength->isZero()) return;

2326 checkZeroLength = false;

2327 }

2328

2330 llvm::Value *end =

2333 checkZeroLength, useEHCleanupForArray);

2334}

2335

2336

2337

2338

2339

2340

2341

2342

2343

2344

2345

2347 llvm::Value *end,

2350 Destroyer *destroyer,

2351 bool checkZeroLength,

2352 bool useEHCleanup) {

2354

2355

2356

2357 llvm::BasicBlock *bodyBB = createBasicBlock("arraydestroy.body");

2358 llvm::BasicBlock *doneBB = createBasicBlock("arraydestroy.done");

2359

2360 if (checkZeroLength) {

2361 llvm::Value *isEmpty = Builder.CreateICmpEQ(begin, end,

2362 "arraydestroy.isempty");

2363 Builder.CreateCondBr(isEmpty, doneBB, bodyBB);

2364 }

2365

2366

2367 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();

2369 llvm::PHINode *elementPast =

2370 Builder.CreatePHI(begin->getType(), 2, "arraydestroy.elementPast");

2371 elementPast->addIncoming(end, entryBB);

2372

2373

2374 llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true);

2377 llvmElementType, elementPast, negativeOne, "arraydestroy.element");

2378

2379 if (useEHCleanup)

2381 destroyer);

2382

2383

2384 destroyer(*this, Address(element, llvmElementType, elementAlign),

2385 elementType);

2386

2387 if (useEHCleanup)

2389

2390

2391 llvm::Value *done = Builder.CreateICmpEQ(element, begin, "arraydestroy.done");

2392 Builder.CreateCondBr(done, doneBB, bodyBB);

2393 elementPast->addIncoming(element, Builder.GetInsertBlock());

2394

2395

2397}

2398

2399

2400

2402 llvm::Value *begin, llvm::Value *end,

2406

2407

2408 unsigned arrayDepth = 0;

2410

2411 if (!isa(arrayType))

2412 arrayDepth++;

2414 }

2415

2416 if (arrayDepth) {

2417 llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);

2418

2421 elemTy, begin, gepIndices, "pad.arraybegin");

2423 elemTy, end, gepIndices, "pad.arrayend");

2424 }

2425

2426

2427

2428

2430 true, false);

2431}

2432

2433namespace {

2434

2435

2436

2438 llvm::Value *ArrayBegin;

2439 llvm::Value *ArrayEnd;

2441 CodeGenFunction::Destroyer *Destroyer;

2443 public:

2444 RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,

2446 CodeGenFunction::Destroyer *destroyer)

2447 : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),

2448 ElementType(elementType), Destroyer(destroyer),

2449 ElementAlign(elementAlign) {}

2450

2453 ElementType, ElementAlign, Destroyer);

2454 }

2455 };

2456

2457

2458

2459

2461 llvm::Value *ArrayBegin;

2462 Address ArrayEndPointer;

2464 CodeGenFunction::Destroyer *Destroyer;

2466 public:

2467 IrregularPartialArrayDestroy(llvm::Value *arrayBegin,

2468 Address arrayEndPointer,

2471 CodeGenFunction::Destroyer *destroyer)

2472 : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),

2473 ElementType(elementType), Destroyer(destroyer),

2474 ElementAlign(elementAlign) {}

2475

2477 llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);

2479 ElementType, ElementAlign, Destroyer);

2480 }

2481 };

2482}

2483

2484

2485

2486

2487

2488

2489

2491 Address arrayEndPointer,

2494 Destroyer *destroyer) {

2495 pushFullExprCleanup(

2497 elementAlign, destroyer);

2498}

2499

2500

2501

2502

2503

2504

2505

2507 llvm::Value *arrayEnd,

2510 Destroyer *destroyer) {

2511 pushFullExprCleanup(EHCleanup,

2512 arrayBegin, arrayEnd,

2513 elementType, elementAlign,

2514 destroyer);

2515}

2516

2517

2519 if (LifetimeStartFn)

2520 return LifetimeStartFn;

2521 LifetimeStartFn = llvm::Intrinsic::getOrInsertDeclaration(

2523 return LifetimeStartFn;

2524}

2525

2526

2528 if (LifetimeEndFn)

2529 return LifetimeEndFn;

2530 LifetimeEndFn = llvm::Intrinsic::getOrInsertDeclaration(

2532 return LifetimeEndFn;

2533}

2534

2535namespace {

2536

2537

2538

2539

2541 ConsumeARCParameter(llvm::Value *param,

2543 : Param(param), Precise(precise) {}

2544

2545 llvm::Value *Param;

2547

2550 }

2551 };

2552}

2553

2554

2555

2557 unsigned ArgNo) {

2558 bool NoDebugInfo = false;

2559

2560 assert((isa(D) || isa(D)) &&

2561 "Invalid argument to EmitParmDecl");

2562

2563

2564

2565 if (!isallvm::GlobalValue(Arg.getAnyValue()))

2566 Arg.getAnyValue()->setName(D.getName());

2567

2569

2570

2571 if (auto IPD = dyn_cast(&D)) {

2572

2573

2575 llvm::Value *V = Arg.isIndirect()

2577 : Arg.getDirectValue();

2579 return;

2580 }

2581

2582

2583 NoDebugInfo =

2585 }

2586

2589 bool DoStore = false;

2591 bool UseIndirectDebugAddress = false;

2592

2593

2594 if (Arg.isIndirect()) {

2595 DeclPtr = Arg.getIndirectAddress();

2597

2598

2602

2603

2604

2608 if (UseIndirectDebugAddress) {

2611 D.getName() + ".indirect_addr");

2613 }

2614

2616 auto DestLangAS =

2618 if (SrcLangAS != DestLangAS) {

2619 assert(getContext().getTargetAddressSpace(SrcLangAS) ==

2622 auto *T = llvm::PointerType::get(getLLVMContext(), DestAS);

2623 DeclPtr =

2625 *this, V, SrcLangAS, DestLangAS, T, true),

2627 }

2628

2629

2630

2631

2638 "unexpected destructor type");

2640 CalleeDestructedParamCleanups[cast(&D)] =

2642 }

2643 }

2644 } else {

2645

2646 Address OpenMPLocalAddr =

2651 DeclPtr = OpenMPLocalAddr;

2652 AllocaPtr = DeclPtr;

2653 } else {

2654

2656 D.getName() + ".addr", &AllocaPtr);

2657 }

2658 DoStore = true;

2659 }

2660

2661 llvm::Value *ArgVal = (DoStore ? Arg.getDirectValue() : nullptr);

2662

2664 if (IsScalar) {

2667

2668

2669

2670

2671 bool isConsumed = D.hasAttr();

2672

2673

2674 if (D.isARCPseudoStrong()) {

2676 "pseudo-strong variable isn't strong?");

2677 assert(qs.hasConst() && "pseudo-strong variable should be const!");

2679 }

2680

2681

2682 if (Arg.isIndirect() && !ArgVal)

2684

2686 if (!isConsumed) {

2688

2689

2690

2694 DoStore = false;

2695 }

2696 else

2697

2698

2699

2701 }

2702 } else {

2703

2704 if (isConsumed) {

2708 precise);

2709 }

2710

2713 DoStore = false;

2714 }

2715 }

2716

2717

2719 }

2720 }

2721

2722

2723 if (DoStore)

2725

2726 setAddrOfLocalVar(&D, DeclPtr);

2727

2728

2731 !NoDebugInfo) {

2733 &D, AllocaPtr.getPointer(), ArgNo, Builder, UseIndirectDebugAddress);

2734 if (const auto *Var = dyn_cast_or_null(&D))

2736 }

2737 }

2738

2739 if (D.hasAttr())

2741

2742

2743

2744

2745 if (requiresReturnValueNullabilityCheck()) {

2748 SanitizerScope SanScope(this);

2749 RetValNullabilityPrecondition =

2750 Builder.CreateAnd(RetValNullabilityPrecondition,

2751 Builder.CreateIsNotNull(Arg.getAnyValue()));

2752 }

2753 }

2754}

2755

2758 if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && D->isUsed()))

2759 return;

2761}

2762

2765 if (!LangOpts.OpenMP || LangOpts.OpenMPSimd ||

2766 (!LangOpts.EmitAllDecls && D->isUsed()))

2767 return;

2769}

2770

2773}

2774

2776 for (const Expr *E : D->varlist()) {

2777 const auto *DE = cast(E);

2778 const auto *VD = cast(DE->getDecl());

2779

2780

2782 continue;

2783

2784

2785

2786

2787

2788

2789

2790

2792 llvm::GlobalValue *Entry = GetGlobalValue(MangledName);

2793 if (!Entry)

2794 continue;

2795

2796

2797

2801 if (Entry->getType()->getAddressSpace() == TargetAS)

2802 continue;

2803

2804

2806 llvm::PointerType *PTy = llvm::PointerType::get(Ty, TargetAS);

2807

2808

2809

2810

2811 llvm::GlobalVariable *DummyGV = new llvm::GlobalVariable(

2812 getModule(), Entry->getValueType(), false,

2813 llvm::GlobalValue::CommonLinkage, nullptr, "dummy", nullptr,

2814 llvm::GlobalVariable::NotThreadLocal, Entry->getAddressSpace());

2815 Entry->replaceAllUsesWith(DummyGV);

2816

2817 Entry->mutateType(PTy);

2818 llvm::Constant *NewPtrForOldDecl =

2819 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(

2820 Entry, DummyGV->getType());

2821

2822

2823

2824 DummyGV->replaceAllUsesWith(NewPtrForOldDecl);

2825 DummyGV->eraseFromParent();

2826 }

2827}

2828

2829std::optional

2831 if (const auto *AA = VD->getAttr()) {

2832 if (Expr *Alignment = AA->getAlignment()) {

2833 unsigned UserAlign =

2834 Alignment->EvaluateKnownConstInt(getContext()).getExtValue();

2837

2838

2839

2840

2842 std::max(UserAlign, NaturalAlign.getQuantity()));

2843 }

2844 }

2845 return std::nullopt;

2846}

Defines the clang::ASTContext interface.

static void emitStoresForInitAfterBZero(CodeGenModule &CGM, llvm::Constant *Init, Address Loc, bool isVolatile, CGBuilderTy &Builder, bool IsAutoInit)

For inits that canEmitInitWithFewStoresAfterBZero returned true for, emit the scalar stores that woul...

static bool isCapturedBy(const VarDecl &, const Expr *)

Determines whether the given __block variable is potentially captured by the given expression.

static void emitPartialArrayDestroy(CodeGenFunction &CGF, llvm::Value *begin, llvm::Value *end, QualType type, CharUnits elementAlign, CodeGenFunction::Destroyer *destroyer)

Perform partial array destruction as if in an EH cleanup.

static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D, Address Loc, bool isVolatile, CGBuilderTy &Builder)

static bool canEmitInitWithFewStoresAfterBZero(llvm::Constant *Init, unsigned &NumStores)

Decide whether we can emit the non-zero parts of the specified initializer with equal or fewer than N...

static llvm::Constant * patternOrZeroFor(CodeGenModule &CGM, IsPattern isPattern, llvm::Type *Ty)

Generate a constant filled with either a pattern or zeroes.

static llvm::Constant * constWithPadding(CodeGenModule &CGM, IsPattern isPattern, llvm::Constant *constant)

Replace all padding bytes in a given constant with either a pattern byte or 0x00.

static llvm::Value * shouldUseMemSetToInitialize(llvm::Constant *Init, uint64_t GlobalSize, const llvm::DataLayout &DL)

Decide whether we should use memset to initialize a local variable instead of using a memcpy from a c...

static std::string getStaticDeclName(CodeGenModule &CGM, const VarDecl &D)

static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, Address Loc, bool isVolatile, CGBuilderTy &Builder, llvm::Constant *constant, bool IsAutoInit)

static bool shouldSplitConstantStore(CodeGenModule &CGM, uint64_t GlobalByteSize)

Decide whether we want to split a constant structure or array store into a sequence of its fields' st...

static llvm::Constant * replaceUndef(CodeGenModule &CGM, IsPattern isPattern, llvm::Constant *constant)

static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF, const LValue &destLV, const Expr *init)

static bool shouldUseBZeroPlusStoresToInitialize(llvm::Constant *Init, uint64_t GlobalSize)

Decide whether we should use bzero plus some stores to initialize a local variable instead of using a...

static llvm::Constant * constStructWithPadding(CodeGenModule &CGM, IsPattern isPattern, llvm::StructType *STy, llvm::Constant *constant)

Helper function for constWithPadding() to deal with padding in structures.

static bool containsUndef(llvm::Constant *constant)

static bool isAccessedBy(const VarDecl &var, const Stmt *s)

static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var, Address addr, Qualifiers::ObjCLifetime lifetime)

EmitAutoVarWithLifetime - Does the setup required for an automatic variable with lifetime.

static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM, const VarDecl &D, CGBuilderTy &Builder, llvm::Constant *Constant, CharUnits Align)

static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D, Address Loc, bool isVolatile, CGBuilderTy &Builder)

static void drillIntoBlockVariable(CodeGenFunction &CGF, LValue &lvalue, const VarDecl *var)

CodeGenFunction::ComplexPairTy ComplexPairTy

This file defines OpenMP nodes for declarative directives.

static const RecordType * getRecordType(QualType QT)

Checks that the passed in QualType either is of RecordType or points to RecordType.

static const NamedDecl * getDefinition(const Decl *D)

__device__ __2f16 float __ockl_bool s

CharUnits getTypeAlignInChars(QualType T) const

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

QualType getPointerType(QualType T) const

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

const LangOptions & getLangOpts() const

QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const

getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...

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

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

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

CharUnits getTypeSizeInChars(QualType T) const

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

const VariableArrayType * getAsVariableArrayType(QualType T) const

unsigned getTargetAddressSpace(LangAS AS) const

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

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

ArrayRef< Capture > captures() const

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

Represents a call to a C++ constructor.

Represents a C++ constructor within a class.

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

Represents a C++ destructor within a class.

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

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.

CharUnits alignmentOfArrayElement(CharUnits elementSize) const

Given that this is the alignment of the first element of an array, return the minimum alignment of an...

bool isOne() const

isOne - Test whether the quantity equals one.

static CharUnits fromQuantity(QuantityType Quantity)

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

bool hasReducedDebugInfo() const

Check if type and variable info should be emitted.

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

bool getIndirectByVal() const

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

CharUnits getAlignment() const

llvm::Type * getElementType() const

Return the type of the values stored in this address.

Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const

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

Address withElementType(llvm::Type *ElemTy) const

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

KnownNonNull_t isKnownNonNull() const

Whether the pointer is known not to be null.

static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)

static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)

Apply TemporaryLocation if it is valid.

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

llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)

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

llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")

Emit a load from an i1 flag variable.

llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)

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

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

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

void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)

Emit information about a global variable.

Param2DILocTy & getParamDbgMappings()

llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)

Emit call to llvm.dbg.declare for an argument variable declaration.

llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)

Emit call to llvm.dbg.declare for an automatic variable declaration.

void setLocation(SourceLocation Loc)

Update the current source location.

void registerVLASizeExpression(QualType Ty, llvm::Metadata *SizeExpr)

Register VLA size expression debug node with the qualified type.

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

const_arg_iterator arg_begin() const

MutableArrayRef< ArgInfo > arguments()

virtual void EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF, const VarDecl &D)

Emit the IR required for a work-group-local variable declaration, and add an entry to CGF's LocalDecl...

Allows to disable automatic handling of functions used in target regions as those marked as omp decla...

virtual void getKmpcFreeShared(CodeGenFunction &CGF, const std::pair< llvm::Value *, llvm::Value * > &AddrSizePair)

Get call to __kmpc_free_shared.

void emitUserDefinedMapper(const OMPDeclareMapperDecl *D, CodeGenFunction *CGF=nullptr)

Emit the function for the user defined mapper construct.

virtual void processRequiresDirective(const OMPRequiresDecl *D)

Perform check on requires decl to ensure that target architecture supports unified addressing.

virtual std::pair< llvm::Value *, llvm::Value * > getKmpcAllocShared(CodeGenFunction &CGF, const VarDecl *VD)

Get call to __kmpc_alloc_shared.

virtual void emitUserDefinedReduction(CodeGenFunction *CGF, const OMPDeclareReductionDecl *D)

Emit code for the specified user defined reduction construct.

virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)

Gets the OpenMP-specific address of the local variable.

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 emitAutoVarTypeCleanup(const AutoVarEmission &emission, QualType::DestructionKind dtorKind)

void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, bool LoadBlockVarAddr, bool CanThrow)

Enter a cleanup to destroy a __block variable.

llvm::Value * EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr)

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)

ContainsLabel - Return true if the statement contains a label in it.

static Destroyer destroyNonTrivialCStruct

static bool cxxDestructorCanThrow(QualType T)

Check if T is a C++ class that has a destructor that can throw.

SanitizerSet SanOpts

Sanitizers enabled for this function.

RawAddress createCleanupActiveFlag()

llvm::DenseMap< const VarDecl *, llvm::Value * > NRVOFlags

A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...

void EmitARCMoveWeak(Address dst, Address src)

void EmitAutoVarDecl(const VarDecl &D)

EmitAutoVarDecl - Emit an auto variable declaration.

void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr)

void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)

EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...

void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)

static bool hasScalarEvaluationKind(QualType T)

const BlockByrefInfo & getBlockByrefInfo(const VarDecl *var)

void EmitDecl(const Decl &D)

EmitDecl - Emit a declaration.

void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)

RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")

CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...

llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)

emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...

VlaSizePair getVLASize(const VariableArrayType *vla)

Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...

CleanupKind getARCCleanupKind()

Retrieves the default cleanup kind for an ARC cleanup.

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)

LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

EmitLValue - Emit code to compute a designator that specifies the location of the expression.

void EmitExtendGCLifetime(llvm::Value *object)

EmitExtendGCLifetime - Given a pointer to an Objective-C object, make sure it survives garbage collec...

llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack

llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)

void EmitVariablyModifiedType(QualType Ty)

EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...

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

createBasicBlock - Create an LLVM basic block.

const LangOptions & getLangOpts() const

llvm::Constant * EmitCheckTypeDescriptor(QualType T)

Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.

void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)

void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)

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

EmitBlock - Emit the given block.

void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind, Address addr, QualType type)

llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)

CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...

const CodeGen::CGBlockInfo * BlockInfo

void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)

EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...

void emitByrefStructureInit(const AutoVarEmission &emission)

ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)

EmitComplexExpr - Emit the computation of the specified expression of complex type,...

@ TCK_NonnullAssign

Checking the value assigned to a _Nonnull pointer. Must not be null.

llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)

llvm::Type * ConvertTypeForMem(QualType T)

llvm::Value * EmitARCUnsafeUnretainedScalarExpr(const Expr *expr)

void EmitAutoVarInit(const AutoVarEmission &emission)

void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)

DominatingValue< T >::saved_type saveValueInCond(T value)

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 EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)

static Destroyer destroyCXXObject

void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)

Emit local annotations for the local variable V, declared by D.

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

void EmitAtomicInit(Expr *E, LValue lvalue)

const TargetInfo & getTarget() const

bool isInConditionalBranch() const

isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...

void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)

void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)

Emit code in this function to perform a guarded variable initialization.

void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)

void initFullExprCleanupWithFlag(RawAddress ActiveFlag)

void EmitARCCopyWeak(Address dst, Address src)

void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)

Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...

void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)

void defaultInitNonTrivialCStructVar(LValue Dst)

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)

Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...

bool isTrivialInitializer(const Expr *Init)

Determine whether the given initializer is trivial in the sense that it requires no code to be genera...

CGDebugInfo * getDebugInfo()

Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, bool followForward=true)

BuildBlockByrefAddress - Computes the location of the data in a variable which is declared as __block...

LValue EmitDeclRefLValue(const DeclRefExpr *E)

AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)

Determine whether a field initialization may overlap some other object.

llvm::Value * EmitARCRetainAutoreleaseScalarExpr(const Expr *expr)

const TargetCodeGenInfo & getTargetHooks() const

RValue EmitReferenceBindingToExpr(const Expr *E)

Emits a reference binding to the passed in expression.

void EmitAggExpr(const Expr *E, AggValueSlot AS)

EmitAggExpr - Emit the computation of the specified expression of aggregate type.

VlaSizePair getVLAElements1D(const VariableArrayType *vla)

Return the number of elements for a single dimension for the given array type.

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

void EmitVarDecl(const VarDecl &D)

EmitVarDecl - Emit a local variable declaration.

ASTContext & getContext() const

llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)

EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...

void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)

Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.

void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)

const Decl * CurFuncDecl

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

AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)

void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)

Address ReturnValuePointer

ReturnValuePointer - The temporary alloca to hold a pointer to sret.

void EmitAutoVarCleanups(const AutoVarEmission &emission)

llvm::GlobalVariable * AddInitializerToStaticVarDecl(const VarDecl &D, llvm::GlobalVariable *GV)

AddInitializerToStaticVarDecl - Add the initializer for 'D' to the global variable that has already b...

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

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

static Destroyer destroyARCWeak

bool needsEHCleanup(QualType::DestructionKind kind)

Determines whether an EH cleanup is required to destroy a type with the given destruction kind.

CleanupKind getCleanupKind(QualType::DestructionKind kind)

llvm::Type * ConvertType(QualType T)

void EmitARCInitWeak(Address addr, llvm::Value *value)

static Destroyer destroyARCStrongPrecise

VarBypassDetector Bypasses

llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)

void pushStackRestore(CleanupKind kind, Address SPMem)

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

void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)

EmitStoreOfComplex - Store a complex number into the specified l-value.

const CGFunctionInfo * CurFnInfo

void pushKmpcAllocFree(CleanupKind Kind, std::pair< llvm::Value *, llvm::Value * > AddrSizePair)

void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)

EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

static Destroyer destroyARCStrongImprecise

void EnsureInsertPoint()

EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.

llvm::LLVMContext & getLLVMContext()

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo)

Emits the alloca and debug information for the size expressions for each dimension of an array.

llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)

void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)

void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)

EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...

bool hasLabelBeenSeenInCurrentScope() const

Return true if a label was seen in the current scope.

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

StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)

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

Set visibility, dllimport/dllexport and dso_local.

llvm::Module & getModule() const

void setStaticLocalDeclAddress(const VarDecl *D, llvm::Constant *C)

llvm::Function * getLLVMLifetimeStartFn()

Lazily declare the @llvm.lifetime.start intrinsic.

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.

Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant, CharUnits Align)

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

Get target specific null pointer.

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

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

const LangOptions & getLangOpts() const

CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)

CodeGenTypes & getTypes()

CGOpenCLRuntime & getOpenCLRuntime()

Return a reference to the configured OpenCL runtime.

void addUsedGlobal(llvm::GlobalValue *GV)

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

void EmitOMPAllocateDecl(const OMPAllocateDecl *D)

Emit a code for the allocate directive.

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

Returns LLVM linkage for a declarator.

const llvm::DataLayout & getDataLayout() const

void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV)

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

CGOpenMPRuntime & getOpenMPRuntime()

Return a reference to the configured OpenMP runtime.

SanitizerMetadata * getSanitizerMetadata()

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

llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)

void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV)

Add global annotations that are set on D, for the global GV.

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

void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, CodeGenFunction *CGF=nullptr)

Emit a code for declare mapper construct.

llvm::Function * getLLVMLifetimeEndFn()

Lazily declare the @llvm.lifetime.end intrinsic.

bool supportsCOMDAT() const

void EmitOMPRequiresDecl(const OMPRequiresDecl *D)

Emit a code for requires directive.

const TargetCodeGenInfo & getTargetCodeGenInfo()

const CodeGenOptions & getCodeGenOpts() const

StringRef getMangledName(GlobalDecl GD)

std::optional< CharUnits > getOMPAllocateAlignment(const VarDecl *VD)

Return the alignment specified in an allocate directive, if present.

llvm::LLVMContext & getLLVMContext()

llvm::GlobalValue * GetGlobalValue(StringRef Ref)

void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, CodeGenFunction *CGF=nullptr)

Emit a code for declare reduction construct.

llvm::Constant * EmitNullConstant(QualType T)

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

LangAS GetGlobalConstantAddressSpace() const

Return the AST address space of constant literal, which is used to emit the constant literal as globa...

LangAS GetGlobalVarAddressSpace(const VarDecl *D)

Return the AST address space of the underlying global variable for D, as determined by its declaratio...

llvm::ConstantInt * getSize(CharUnits numChars)

Emit the given number of characters as a value of type size_t.

void markStmtMaybeUsed(const Stmt *S)

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.

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

const CGFunctionInfo & arrangeFunctionDeclaration(const FunctionDecl *FD)

Free functions are functions that are compatible with an ordinary C function pointer type.

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

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

A cleanup scope which generates the cleanup blocks lazily.

Information for lazily generating a cleanup.

ConditionalCleanup stores the saved form of its parameters, then restores them and performs the clean...

stable_iterator stable_begin() const

Create a stable reference to the top of the EH stack.

iterator begin() const

Returns an iterator pointing to the innermost EH scope.

LValue - This represents an lvalue references.

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

Address getAddress() const

void setNonGC(bool Value)

void setAddress(Address address)

Qualifiers::ObjCLifetime getObjCLifetime() const

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

static RValue get(llvm::Value *V)

An abstract representation of an aligned address.

llvm::Value * getPointer() const

static RawAddress invalid()

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

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

virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const

setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...

bool IsBypassed(const VarDecl *D) const

Returns true if the variable declaration was by bypassed by any goto or switch statement.

CompoundStmt - This represents a group of statements like { stmt stmt }.

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

A reference to a declared variable, function, enum, etc.

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

const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const

If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...

Decl * getNonClosureContext()

Find the innermost non-closure ancestor of this declaration, walking up through blocks,...

SourceLocation getLocation() const

bool isUsed(bool CheckUsedAttr=true) const

Whether any (re-)declaration of the entity was used, meaning that a definition is required.

DeclContext * getDeclContext()

This represents one expression.

Expr * IgnoreParenCasts() LLVM_READONLY

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

Expr * IgnoreParens() LLVM_READONLY

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

bool isLValue() const

isLValue - True if this expression is an "l-value" according to the rules of the current language.

SourceLocation getExprLoc() const LLVM_READONLY

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

Represents a function declaration or definition.

GlobalDecl - represents a global declaration.

const Decl * getDecl() const

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

IdentifierInfo & getOwn(StringRef Name)

Gets an IdentifierInfo for the given name without consulting external sources.

This represents '#pragma omp allocate ...' directive.

This represents '#pragma omp declare mapper ...' directive.

This represents '#pragma omp declare reduction ...' directive.

This represents '#pragma omp requires...' directive.

A (possibly-)qualified type.

@ DK_objc_strong_lifetime

@ PDIK_Struct

The type is a struct containing a field whose type is not PCK_Trivial.

LangAS getAddressSpace() const

Return the address space of this type.

bool isConstant(const ASTContext &Ctx) const

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

QualType getNonReferenceType() const

If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...

QualType getUnqualifiedType() const

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

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

bool isPODType(const ASTContext &Context) const

Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).

The collection of all-type qualifiers we support.

@ OCL_Strong

Assigning into this object requires the old value to be released and the new value to be retained.

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

ObjCLifetime getObjCLifetime() const

bool isParamDestroyedInCallee() const

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

RecordDecl * getDecl() const

Scope - A scope is a transient data structure that is used while parsing the program.

static const uint64_t MaximumAlignment

Encodes a location in the source.

StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).

Stmt - This represents one statement.

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

bool isConstantSizeType() const

Return true if this is not a variable sized type, according to the rules of C99 6....

const T * castAs() const

Member-template castAs.

bool isVariablyModifiedType() const

Whether this type is a variably-modified type (C99 6.7.5).

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

std::optional< NullabilityKind > getNullability() const

Determine the nullability of the given type.

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.

static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)

bool hasGlobalStorage() const

Returns true for all variables that do not have local storage.

const Expr * getInit() const

bool isLocalVarDecl() const

Returns true for local variable declarations other than parameters.

Defines the clang::TargetInfo interface.

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

llvm::Constant * initializationPatternFor(CodeGenModule &, llvm::Type *)

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

ARCPreciseLifetime_t

Does an ARC strong l-value have precise lifetime?

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const AstTypeMatcher< ArrayType > arrayType

Matches all kinds of arrays.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr

Matches any cast nodes of Clang's AST.

constexpr Variable var(Literal L)

Returns the variable of L.

tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")

Clean up any erroneous/redundant code in the given Ranges in Code.

bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Descriptor *Desc)

bool Zero(InterpState &S, CodePtr OpPC)

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

@ Ctor_Base

Base object ctor.

@ NonNull

Values of this type can never be null.

Linkage

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

@ SD_Automatic

Automatic storage duration (most local variables).

@ Dtor_Base

Base object dtor.

@ Dtor_Complete

Complete object dtor.

LangAS

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

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

const FunctionProtoType * T

@ ThreadPrivateVar

Parameter for Thread private variable.

float __ovld __cnfn length(float)

Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)

static Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)

Gets the OpenMP-specific address of the local variable /p VD.

llvm::IntegerType * Int64Ty

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * SizeTy

llvm::IntegerType * IntPtrTy

llvm::PointerType * Int8PtrTy

llvm::PointerType * AllocaInt8PtrTy

LangAS getASTAllocaAddressSpace() const

A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.

bool has(SanitizerMask K) const

Check if a certain (single) sanitizer is enabled.