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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

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

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

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

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

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

44#include

45

46using namespace clang;

48

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

51

54 case Decl::BuiltinTemplate:

55 case Decl::TranslationUnit:

56 case Decl::ExternCContext:

57 case Decl::Namespace:

58 case Decl::UnresolvedUsingTypename:

59 case Decl::ClassTemplateSpecialization:

60 case Decl::ClassTemplatePartialSpecialization:

61 case Decl::VarTemplateSpecialization:

62 case Decl::VarTemplatePartialSpecialization:

63 case Decl::TemplateTypeParm:

64 case Decl::UnresolvedUsingValue:

65 case Decl::NonTypeTemplateParm:

66 case Decl::CXXDeductionGuide:

67 case Decl::CXXMethod:

68 case Decl::CXXConstructor:

69 case Decl::CXXDestructor:

70 case Decl::CXXConversion:

71 case Decl::Field:

72 case Decl::MSProperty:

73 case Decl::IndirectField:

74 case Decl::ObjCIvar:

75 case Decl::ObjCAtDefsField:

76 case Decl::ParmVar:

77 case Decl::ImplicitParam:

78 case Decl::ClassTemplate:

79 case Decl::VarTemplate:

80 case Decl::FunctionTemplate:

81 case Decl::TypeAliasTemplate:

82 case Decl::TemplateTemplateParm:

83 case Decl::ObjCMethod:

84 case Decl::ObjCCategory:

85 case Decl::ObjCProtocol:

86 case Decl::ObjCInterface:

87 case Decl::ObjCCategoryImpl:

88 case Decl::ObjCImplementation:

89 case Decl::ObjCProperty:

90 case Decl::ObjCCompatibleAlias:

91 case Decl::PragmaComment:

92 case Decl::PragmaDetectMismatch:

93 case Decl::AccessSpec:

94 case Decl::LinkageSpec:

95 case Decl::Export:

96 case Decl::ObjCPropertyImpl:

97 case Decl::FileScopeAsm:

98 case Decl::TopLevelStmt:

99 case Decl::Friend:

100 case Decl::FriendTemplate:

101 case Decl::Block:

102 case Decl::OutlinedFunction:

103 case Decl::Captured:

104 case Decl::UsingShadow:

105 case Decl::ConstructorUsingShadow:

106 case Decl::ObjCTypeParam:

107 case Decl::Binding:

108 case Decl::UnresolvedUsingIfExists:

109 case Decl::HLSLBuffer:

110 case Decl::HLSLRootSignature:

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

112 case Decl::Record:

113 case Decl::CXXRecord:

116 DI->EmitAndRetainType(

118 return;

119 case Decl::Enum:

122 DI->EmitAndRetainType(

124 return;

125 case Decl::Function:

126 case Decl::EnumConstant:

127 case Decl::StaticAssert:

128 case Decl::Label:

129 case Decl::Import:

130 case Decl::MSGuid:

131 case Decl::UnnamedGlobalConstant:

132 case Decl::TemplateParamObject:

133 case Decl::OMPThreadPrivate:

134 case Decl::OMPGroupPrivate:

135 case Decl::OMPAllocate:

136 case Decl::OMPCapturedExpr:

137 case Decl::OMPRequires:

138 case Decl::Empty:

139 case Decl::Concept:

140 case Decl::ImplicitConceptSpecialization:

141 case Decl::LifetimeExtendedTemporary:

142 case Decl::RequiresExprBody:

143

144 return;

145

146 case Decl::NamespaceAlias:

149 return;

150 case Decl::Using:

153 return;

154 case Decl::UsingEnum:

157 return;

158 case Decl::UsingPack:

160 EmitDecl(*Using, EvaluateConditionDecl);

161 return;

162 case Decl::UsingDirective:

165 return;

166 case Decl::Var:

167 case Decl::Decomposition: {

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

172 if (EvaluateConditionDecl)

174

175 return;

176 }

177

178 case Decl::OMPDeclareReduction:

180

181 case Decl::OMPDeclareMapper:

183

184 case Decl::OpenACCDeclare:

186 case Decl::OpenACCRoutine:

188

189 case Decl::Typedef:

190 case Decl::TypeAlias: {

193 DI->EmitAndRetainType(Ty);

196 return;

197 }

198 }

199}

200

201

202

205

206 return;

207

208

209

210

212

214 return;

215

216 llvm::GlobalValue::LinkageTypes Linkage =

217 CGM.getLLVMLinkageVarDefinition(&D);

218

219

220

221

222

224 }

225

227 return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);

228

231}

232

236

237

239 std::string ContextName;

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

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

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

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

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

249 else

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

251

253 return ContextName;

254}

255

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

258

259

260

261

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

263 return ExistingGV;

264

267

268

269 std::string Name;

270 if (D.hasAttr())

272 else

274

278

279

280

281 llvm::Constant *Init = nullptr;

283 D.hasAttr() || D.hasAttr())

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

285 else

287

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

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

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

292

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

295

298

301

302

304 llvm::Constant *Addr = GV;

305 if (AS != ExpectedAS) {

307 *this, GV, AS,

309 getContext().getTargetAddressSpace(ExpectedAS)));

310 }

311

313

314

315

317

318

319

322

323 if (!DC)

325 }

326

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

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

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

334 else {

335

336

338 }

340

343 }

344

346}

347

348

349

350

351

352llvm::GlobalVariable *

354 llvm::GlobalVariable *GV) {

357

358

359

362 CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");

364 CGM.ErrorUnsupported(D.getInit(), "flexible array initializer");

366

367

368 GV->setConstant(false);

369

371 }

372 return GV;

373 }

374

375 PGO->markStmtMaybeUsed(D.getInit());

376

377#ifndef NDEBUG

381 CGM.getDataLayout().getTypeAllocSize(Init->getType()));

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

383#endif

384

385 bool NeedsDtor =

387

388 GV->setConstant(

390 GV->replaceInitializer(Init);

391

393

395

396

397

399 }

400

401 return GV;

402}

403

405 llvm::GlobalValue::LinkageTypes Linkage) {

406

407

408

409 llvm::Constant *addr = CGM.getOrCreateStaticVarDecl(D, Linkage);

411

412

413

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

416

417

418

419

422

423

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

425

426 llvm::GlobalVariable *var =

428

429

430

431

432

434 D.hasAttr();

435

436 if (D.getInit() && !isCudaSharedVar) {

439 }

440

441 var->setAlignment(alignment.getAsAlign());

442

443 if (D.hasAttr())

444 CGM.AddGlobalAnnotations(&D, var);

445

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

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

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

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

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

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

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

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

454

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

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

457

458 if (D.hasAttr())

459 CGM.addUsedGlobal(var);

460 else if (D.hasAttr())

461 CGM.addUsedOrCompilerUsedGlobal(var);

462

463 if (CGM.getCodeGenOpts().KeepPersistentStorageVariables)

464 CGM.addUsedOrCompilerUsedGlobal(var);

465

466

467

468

469

470

471 llvm::Constant *castedAddr =

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

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

474 CGM.setStaticLocalDeclAddress(&D, castedAddr);

475

476 CGM.getSanitizerMetadata()->reportGlobal(var, D);

477

478

480 if (DI && CGM.getCodeGenOpts().hasReducedDebugInfo()) {

483 }

484}

485

486namespace {

487 struct DestroyObject final : EHScopeStack::Cleanup {

490 bool useEHCleanupForArray)

491 : addr(addr), type(type), destroyer(destroyer),

492 useEHCleanupForArray(useEHCleanupForArray) {}

493

497 bool useEHCleanupForArray;

498

500

501 bool useEHCleanupForArray =

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

503

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

505 }

506 };

507

508 template

509 struct DestroyNRVOVariable : EHScopeStack::Cleanup {

510 DestroyNRVOVariable(Address addr, QualType type, llvm::Value *NRVOFlag)

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

512

513 llvm::Value *NRVOFlag;

514 Address Loc;

515 QualType Ty;

516

517 void Emit(CodeGenFunction &CGF, Flags flags) override {

518

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

520

521 llvm::BasicBlock *SkipDtorBB = nullptr;

522 if (NRVO) {

523

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

526 llvm::Value *DidNRVO =

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

530 }

531

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

533

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

535 }

536

537 virtual ~DestroyNRVOVariable() = default;

538 };

539

540 struct DestroyNRVOVariableCXX final

541 : DestroyNRVOVariable {

542 DestroyNRVOVariableCXX(Address addr, QualType type,

543 const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag)

544 : DestroyNRVOVariable(addr, type, NRVOFlag),

545 Dtor(Dtor) {}

546

547 const CXXDestructorDecl *Dtor;

548

549 void emitDestructorCall(CodeGenFunction &CGF) {

551 false,

552 false, Loc, Ty);

553 }

554 };

555

556 struct DestroyNRVOVariableC final

557 : DestroyNRVOVariable {

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

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

560

561 void emitDestructorCall(CodeGenFunction &CGF) {

563 }

564 };

565

566 struct CallStackRestore final : EHScopeStack::Cleanup {

567 Address Stack;

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

569 bool isRedundantBeforeReturn() override { return true; }

570 void Emit(CodeGenFunction &CGF, Flags flags) override {

572 CGF.Builder.CreateStackRestore(V);

573 }

574 };

575

576 struct KmpcAllocFree final : EHScopeStack::Cleanup {

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

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

579 : AddrSizePair(AddrSizePair) {}

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

583 }

584 };

585

586 struct ExtendGCLifetime final : EHScopeStack::Cleanup {

587 const VarDecl &Var;

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

589

590 void Emit(CodeGenFunction &CGF, Flags flags) override {

591

592

593 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,

594 Var.getType(), VK_LValue, SourceLocation());

596 SourceLocation());

598 }

599 };

600

601 struct CallCleanupFunction final : EHScopeStack::Cleanup {

602 llvm::Constant *CleanupFn;

603 const CGFunctionInfo &FnInfo;

604 const VarDecl &Var;

605 const CleanupAttr *Attribute;

606

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

608 const VarDecl *Var, const CleanupAttr *Attr)

609 : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Attribute(Attr) {}

610

611 void Emit(CodeGenFunction &CGF, Flags flags) override {

612 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,

614

615

617

618

619

620

621

622

623

625 llvm::Value *Arg =

627

628 CallArgList Args;

631 GlobalDecl GD = GlobalDecl(Attribute->getFunctionDecl());

633 CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args,

634 nullptr, false,

635 Attribute->getLoc());

636 }

637 };

638}

639

640

641

645 switch (lifetime) {

647 llvm_unreachable("present but none");

648

650

651 break;

652

655 (var.hasAttr()

658

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

662 break;

663 }

665

666 break;

667

669

670

673 true);

674 break;

675 }

676}

677

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

680

681

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

683

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

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

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

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

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

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

690 return true;

691 }

692 }

693 }

694

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

696

698 return true;

699

700 return false;

701}

702

704 if (decl) return false;

708}

709

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

712 bool needsCast = false;

713

715 switch (castExpr->getCastKind()) {

716

717 case CK_NoOp:

718 case CK_BitCast:

719 case CK_BlockPointerToObjCPointerCast:

720 needsCast = true;

721 break;

722

723

724

725 case CK_LValueToRValue: {

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

728 return false;

729

730

731 LValue srcLV = CGF.EmitLValue(srcExpr);

732

733

734 auto srcAddr = srcLV.getAddress();

735 if (needsCast) {

736 srcAddr = srcAddr.withElementType(destLV.getAddress().getElementType());

737 }

738

739

742 } else {

745 }

746 return true;

747 }

748

749

750 default:

751 return false;

752 }

753

754 init = castExpr->getSubExpr();

755 }

756 return false;

757}

758

764

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

768 return;

769

772 return;

773

774

775

776 auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign;

777 auto CheckHandler = SanitizerHandler::TypeMismatch;

780 llvm::Constant *StaticData[] = {

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

784 EmitCheck({{IsNotNull, CheckOrdinal}}, CheckHandler, StaticData, RHS);

785}

786

788 LValue lvalue, bool capturedByInit) {

790 if (!lifetime) {

791 llvm::Value *Value;

795 } else {

797 }

798 if (capturedByInit)

802 return;

803 }

804

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

806 init = DIE->getExpr();

807

808

809

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

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

813 }

814

815

816

817

818

819 bool accessedByInit = false;

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

822 if (accessedByInit) {

823 LValue tempLV = lvalue;

824

825 if (capturedByInit) {

826

827

830 false));

831 }

832

834 llvm::Value *zero = CGM.getNullPointer(ty, tempLV.getType());

835

836

839

840

841 else

843 }

844

845

846 llvm::Value *value = nullptr;

847

848 switch (lifetime) {

850 llvm_unreachable("present but none");

851

855 break;

856 }

857

858

859

860 [[fallthrough]];

861 }

862

865 break;

866

868

869

871 return;

872 }

873

874

875

876

878

880 if (accessedByInit)

882 else

884 return;

885 }

886

889 break;

890 }

891

893

895

896

897

898

903 return;

904 }

905

907}

908

909

910

912 unsigned &NumStores) {

913

917 return true;

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

922

923

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

928 return false;

929 }

930 return true;

931 }

932

933 if (llvm::ConstantDataSequential *CDS =

934 dyn_castllvm::ConstantDataSequential(Init)) {

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

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

938 return false;

939 }

940 return true;

941 }

942

943

944 return false;

945}

946

947

948

949void CodeGenFunction::emitStoresForInitAfterBZero(llvm::Constant *Init,

950 Address Loc, bool isVolatile,

951 bool IsAutoInit) {

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

954

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

960 if (IsAutoInit)

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

962 return;

963 }

964

965 if (llvm::ConstantDataSequential *CDS =

966 dyn_castllvm::ConstantDataSequential(Init)) {

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

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

969

970

972 emitStoresForInitAfterBZero(

973 Elt, Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,

974 IsAutoInit);

975 }

976 return;

977 }

978

980 "Unknown value type!");

981

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

984

985

987 emitStoresForInitAfterBZero(Elt,

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

989 isVolatile, IsAutoInit);

990 }

991}

992

993

994

995

997 uint64_t GlobalSize) {

998

1000

1001

1002

1003

1004

1005 unsigned StoreBudget = 6;

1006 uint64_t SizeLimit = 32;

1007

1008 return GlobalSize > SizeLimit &&

1010}

1011

1012

1013

1014

1015

1016

1018 uint64_t GlobalSize,

1019 const llvm::DataLayout &DL) {

1020 uint64_t SizeLimit = 32;

1021 if (GlobalSize <= SizeLimit)

1022 return nullptr;

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

1024}

1025

1026

1027

1028

1030 uint64_t GlobalByteSize) {

1031

1032 uint64_t ByteSizeLimit = 64;

1034 return false;

1035 if (GlobalByteSize <= ByteSizeLimit)

1036 return true;

1037 return false;

1038}

1039

1041

1042

1044 llvm::Type *Ty) {

1047 else

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

1049}

1050

1052 llvm::Constant *constant);

1053

1054

1057 llvm::StructType *STy,

1058 llvm::Constant *constant) {

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

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

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

1062 unsigned SizeSoFar = 0;

1064 bool NestedIntact = true;

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

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

1067 if (SizeSoFar < CurOff) {

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

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

1071 }

1072 llvm::Constant *CurOp;

1073 if (constant->isZeroValue())

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

1075 else

1078 if (CurOp != NewOp)

1079 NestedIntact = false;

1080 Values.push_back(NewOp);

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

1082 }

1083 unsigned TotalSize = Layout->getSizeInBytes();

1084 if (SizeSoFar < TotalSize) {

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

1087 }

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

1089 return constant;

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

1091}

1092

1093

1094

1096 llvm::Constant *constant) {

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

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

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

1102 uint64_t Size = ArrayTy->getNumElements();

1103 if (!Size)

1104 return constant;

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

1106 bool ZeroInitializer = constant->isNullValue();

1107 llvm::Constant *OpValue, *PaddedOp;

1108 if (ZeroInitializer) {

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

1111 }

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

1113 if (!ZeroInitializer) {

1114 OpValue = constant->getAggregateElement(Op);

1116 }

1117 Values.push_back(PaddedOp);

1118 }

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

1120 if (NewElemTy == ElemTy)

1121 return constant;

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

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

1124 }

1125

1126

1127

1128 return constant;

1129}

1130

1132 llvm::Constant *Constant,

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

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

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

1137 return CC->getNameAsString();

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

1139 return CD->getNameAsString();

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

1142 return OM->getNameAsString();

1144 return "";

1146 return "";

1147 } else {

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

1149 }

1150 };

1151

1152

1153

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

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

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

1157 bool isConstant = true;

1158 llvm::GlobalVariable *InsertBefore = nullptr;

1159 unsigned AS =

1161 std::string Name;

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

1166 else

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

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

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

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

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

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

1173 CacheEntry = GV;

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

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

1176 }

1177

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

1179}

1180

1184 llvm::Constant *Constant,

1188}

1189

1190void CodeGenFunction::emitStoresForConstant(const VarDecl &D, Address Loc,

1191 bool isVolatile,

1192 llvm::Constant *constant,

1193 bool IsAutoInit) {

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

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

1196 if (!ConstantSize)

1197 return;

1198

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

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

1201 if (canDoSingleStore) {

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

1204 if (IsAutoInit)

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

1206 return;

1207 }

1208

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

1210

1211

1212

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

1215 SizeVal, isVolatile);

1217

1218 if (IsAutoInit)

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

1220

1221 bool valueAlreadyCorrect =

1223 if (!valueAlreadyCorrect) {

1225 emitStoresForInitAfterBZero(constant, Loc, isVolatile, IsAutoInit);

1226 }

1227 return;

1228 }

1229

1230

1231 llvm::Value *Pattern =

1233 if (Pattern) {

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

1238 Value = AP.getLimitedValue();

1239 }

1240 auto *I = Builder.CreateMemSet(

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

1243 if (IsAutoInit)

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

1245 return;

1246 }

1247

1248

1249

1250 bool IsTrivialAutoVarInitPattern =

1251 CGM.getContext().getLangOpts().getTrivialAutoVarInit() ==

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

1255 if (STy == Loc.getElementType() || IsTrivialAutoVarInitPattern) {

1256 const llvm::StructLayout *Layout =

1257 CGM.getDataLayout().getStructLayout(STy);

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

1259 CharUnits CurOff =

1261 Address EltPtr = Builder.CreateConstInBoundsByteGEP(

1263 emitStoresForConstant(D, EltPtr, isVolatile,

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

1265 }

1266 return;

1267 }

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

1269 if (ATy == Loc.getElementType() || IsTrivialAutoVarInitPattern) {

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

1271 Address EltPtr = Builder.CreateConstGEP(

1273 emitStoresForConstant(D, EltPtr, isVolatile,

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

1275 }

1276 return;

1277 }

1278 }

1279 }

1280

1281

1282 auto *I =

1283 Builder.CreateMemCpy(Loc,

1286 SizeVal, isVolatile);

1288

1289 if (IsAutoInit)

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

1291}

1292

1293void CodeGenFunction::emitStoresForZeroInit(const VarDecl &D, Address Loc,

1294 bool isVolatile) {

1296 llvm::Constant *constant =

1298 emitStoresForConstant(D, Loc, isVolatile, constant,

1299 true);

1300}

1301

1302void CodeGenFunction::emitStoresForPatternInit(const VarDecl &D, Address Loc,

1303 bool isVolatile) {

1308 emitStoresForConstant(D, Loc, isVolatile, constant,

1309 true);

1310}

1311

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

1315 return true;

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

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

1319 return true;

1320 return false;

1321}

1322

1324 llvm::Constant *constant) {

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

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

1329 return constant;

1331 return constant;

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

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

1336 }

1337 if (Ty->isStructTy())

1339 if (Ty->isArrayTy())

1341 assert(Ty->isVectorTy());

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

1343}

1344

1345

1346

1347

1353

1354

1355

1357 if (!ShouldEmitLifetimeMarkers)

1358 return false;

1359

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

1361 CGM.getDataLayout().getAllocaAddrSpace() &&

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

1363 llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {Addr});

1364 C->setDoesNotThrow();

1365 return true;

1366}

1367

1369 if (!ShouldEmitLifetimeMarkers)

1370 return;

1371

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

1373 CGM.getDataLayout().getAllocaAddrSpace() &&

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

1375 llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Addr});

1376 C->setDoesNotThrow();

1377}

1378

1381 llvm::Value *V = Builder.CreateLoad(Addr, "fake.use");

1382 llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMFakeUseFn(), {V});

1383 C->setDoesNotThrow();

1384 C->setTailCallKind(llvm::CallInst::TCK_NoTail);

1385}

1386

1389

1390

1393

1394

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

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

1400 else {

1401

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

1404 StringRef NameRef = Name.toStringRef(Buffer);

1406 VLAExprNames.push_back(&Ident);

1407 auto SizeExprAddr =

1409 Builder.CreateStore(VlaSize.NumElts, SizeExprAddr);

1410 Dimensions.emplace_back(SizeExprAddr.getPointer(),

1412 }

1413 Type1D = VlaSize.Type;

1414 }

1415

1416 if (!EmitDebugInfo)

1417 return;

1418

1419

1420

1421

1422 unsigned NameIdx = 0;

1423 for (auto &VlaSize : Dimensions) {

1424 llvm::Metadata *MD;

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

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

1427 else {

1428

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

1431 SizeTy->getScalarSizeInBits(), false);

1436 ArtificialDecl->setImplicit();

1437

1440 }

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

1443 }

1444}

1445

1446

1447

1449 return 4 * C.getTypeSize(C.UnsignedIntTy);

1450}

1451

1452

1453

1457

1458

1459 if (!FuncDecl)

1460 return false;

1462 return false;

1463

1464 if (D.isImplicit() && &D != CXXABIThisDecl)

1465 return false;

1467

1469 return false;

1470

1472 return false;

1473

1474 if (FuncDecl->hasAttr() || FuncDecl->hasAttr())

1475 return false;

1476 return true;

1477}

1478

1479

1480

1484 assert(

1487

1489

1491 emission.IsEscapingByRef = isEscapingByRef;

1492

1494

1495

1498

1500 bool EmitDebugInfo = DI && CGM.getCodeGenOpts().hasReducedDebugInfo();

1501

1505 if (CGM.getLangOpts().OpenMPIRBuilder)

1507 else

1508 OpenMPLocalAddr =

1510 ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D)

1512

1514

1516 address = OpenMPLocalAddr;

1517 AllocaAddr = OpenMPLocalAddr;

1519

1520

1521

1522

1523

1524

1525

1526

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

1532

1533

1534

1535

1536

1537

1538 bool NeedsDtor =

1542 (CGM.getCodeGenOpts().MergeAllConstants && !NRVO &&

1543 !isEscapingByRef &&

1546

1547

1549 assert(emission.wasEmittedAsGlobal());

1550 return emission;

1551 }

1552

1553

1554 emission.IsConstantAggregate = true;

1555 }

1556

1557

1558

1559

1560

1561 if (NRVO) {

1562

1563

1564

1565 AllocaAddr =

1568 address = MaybeCastStackAddressSpace(AllocaAddr, Ty.getAddressSpace());

1569

1571 if (const auto *CXXRD = dyn_cast(RD);

1572 (CXXRD && !CXXRD->hasTrivialDestructor()) ||

1573 RD->isNonTrivialToPrimitiveDestroy()) {

1574

1575

1576

1582

1583

1585 emission.NRVOFlag = NRVOFlag.getPointer();

1586 }

1587 }

1588 } else {

1590 llvm::Type *allocaTy;

1591 if (isEscapingByRef) {

1593 allocaTy = byrefInfo.Type;

1594 allocaAlignment = byrefInfo.ByrefAlignment;

1595 } else {

1597 allocaAlignment = alignment;

1598 }

1599

1600

1601

1602

1604 allocaAlignment, D.getName(),

1605 nullptr, &AllocaAddr);

1606

1607

1608

1609

1610 bool IsMSCatchParam =

1612

1613

1614

1616

1617

1618

1619

1620

1621

1622

1623

1624

1625

1626

1627

1628

1629 if (Bypasses.IsBypassed(&D) &&

1631 emission.UseLifetimeMarkers =

1633 }

1634 } else {

1636 }

1637 }

1638 } else {

1640

1641

1642

1643

1644

1645

1646 bool VarAllocated = false;

1647 if (getLangOpts().OpenMPIsTargetDevice) {

1648 auto &RT = CGM.getOpenMPRuntime();

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

1650

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

1652 RT.getKmpcAllocShared(*this, &D);

1653

1654

1656 CGM.getContext().getDeclAlign(&D),

1658 address = Base.getAddress();

1659

1660

1661

1662

1664

1665

1666 VarAllocated = true;

1667 }

1668 }

1669

1670 if (!VarAllocated) {

1671 if (!DidCallStackSave) {

1672

1675

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

1678 Builder.CreateStore(V, Stack);

1679

1680 DidCallStackSave = true;

1681

1682

1683

1685 }

1686

1689

1690

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

1692 &AllocaAddr);

1693 }

1694

1695

1696

1697

1699 }

1700

1701 setAddrOfLocalVar(&D, address);

1702 emission.Addr = address;

1703 emission.AllocaAddr = AllocaAddr;

1704

1705

1707 Address DebugAddr = address;

1710

1711

1712 if (UsePointerValue) {

1715 }

1716 (void)DI->EmitDeclareOfAutoVariable(&D, AllocaAddr.getPointer(), Builder,

1717 UsePointerValue);

1718 }

1719

1722

1723

1727

1728

1729

1730

1731

1732

1733 if (CGM.getCodeGenOpts().getExtendVariableLiveness() ==

1738 }

1739

1740 return emission;

1741}

1742

1744

1745

1746

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

1752 return true;

1753 return false;

1754}

1755

1756

1757

1759

1760

1762

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

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

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

1767 return true;

1768 }

1769

1770

1771 return false;

1772 }

1773

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

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

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

1779 return true;

1780 }

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

1782

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

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

1785 const Expr *Init = VD->getInit();

1787 return true;

1788 }

1789 }

1790 }

1791 else

1792

1793

1794 return true;

1795 return false;

1796 }

1797

1800 return true;

1801

1802 return false;

1803}

1804

1805

1806

1809 return true;

1810

1815 !Construct->requiresZeroInitialization())

1816 return true;

1817

1818 return false;

1819}

1820

1821void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,

1825 auto trivialAutoVarInitMaxSize =

1828 bool isVolatile = type.isVolatileQualified();

1829 if (!Size.isZero()) {

1830

1831

1832

1833

1834

1836 switch (trivialAutoVarInit) {

1838 llvm_unreachable("Uninitialized handled by caller");

1841 return;

1842 if (trivialAutoVarInitMaxSize > 0 &&

1843 allocSize > trivialAutoVarInitMaxSize)

1844 return;

1845 emitStoresForZeroInit(D, Loc, isVolatile);

1846 break;

1849 return;

1850 if (trivialAutoVarInitMaxSize > 0 &&

1851 allocSize > trivialAutoVarInitMaxSize)

1852 return;

1853 emitStoresForPatternInit(D, Loc, isVolatile);

1854 break;

1855 }

1856 return;

1857 }

1858

1859

1860

1861

1862

1863

1865 if (!VlaType)

1866 return;

1868 auto SizeVal = VlaSize.NumElts;

1870 switch (trivialAutoVarInit) {

1872 llvm_unreachable("Uninitialized handled by caller");

1873

1876 return;

1877 if (!EltSize.isOne())

1878 SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize));

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

1880 SizeVal, isVolatile);

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

1882 break;

1883 }

1884

1886 if (CGM.stopAutoInit())

1887 return;

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

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

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

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

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

1897 "vla.iszerosized");

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

1900 if (!EltSize.isOne())

1901 SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize));

1902 llvm::Value *BaseSizeInChars =

1907 SizeVal, "vla.end");

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

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

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

1913 auto *I =

1914 Builder.CreateMemCpy(Address(Cur, Int8Ty, CurAlign),

1916 CGM, D, Builder, Constant, ConstantAlign),

1917 BaseSizeInChars, isVolatile);

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

1919 llvm::Value *Next =

1920 Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next");

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

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

1923 Cur->addIncoming(Next, LoopBB);

1925 } break;

1926 }

1927}

1928

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

1931

1932

1933 if (emission.wasEmittedAsGlobal()) return;

1934

1935 const VarDecl &D = *emission.Variable;

1939

1940

1942

1943

1944

1947 PGO->markStmtMaybeUsed(Init);

1948 return;

1949 }

1951 }

1952

1953

1954 if (emission.IsEscapingByRef)

1956

1957

1958

1959

1960 if (Init &&

1961 type.isNonTrivialToPrimitiveDefaultInitialize() ==

1964 if (emission.IsEscapingByRef)

1967 return;

1968 }

1969

1970

1971

1972

1973 bool capturedByInit =

1975

1976 bool locIsByrefHeader = !capturedByInit;

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

1979

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

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

1982 };

1983

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

1987 hasNoTrivialAutoVarInitAttr(CurFuncDecl))

1990

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

1992 if (trivialAutoVarInit ==

1994 return;

1995

1996

1997 if (emission.IsEscapingByRef && !locIsByrefHeader)

1999

2000 return emitZeroOrPatternForAutoVarInit(type, D, Loc);

2001 };

2002

2004 return initializeWhatIsTechnicallyUninitialized(Loc);

2005

2006 llvm::Constant *constant = nullptr;

2007 if (emission.IsConstantAggregate ||

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

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

2012 (trivialAutoVarInit !=

2018

2019

2020

2021

2022

2023

2026 }

2027

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

2029 CGM.getTypes().typeRequiresSplitIntoByteArray(type)) {

2030

2031

2032

2033 llvm::Type *LoadType =

2034 CGM.getTypes().convertTypeForLoadStore(type, constant->getType());

2035 constant = llvm::ConstantFoldLoadFromConst(

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

2037 }

2038 }

2039

2040 if (!constant) {

2041 if (trivialAutoVarInit !=

2043

2044

2045

2046

2047

2048

2049

2050

2052 initializeWhatIsTechnicallyUninitialized(Loc);

2053 }

2054 }

2058 }

2059

2060 PGO->markStmtMaybeUsed(Init);

2061

2062 if (!emission.IsConstantAggregate) {

2063

2067 }

2068

2070 type.isVolatileQualified(), constant,

2071 false);

2072}

2073

2075 if (auto *DD = dyn_cast_if_present(VD)) {

2076 for (auto *B : DD->flat_bindings())

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

2079 }

2080}

2081

2082

2083

2084

2085

2086

2087

2088

2089

2090

2091

2093 LValue lvalue, bool capturedByInit) {

2095

2096 if (type->isReferenceType()) {

2098 if (capturedByInit)

2101 return;

2102 }

2106 return;

2109 if (capturedByInit)

2112 return;

2113 }

2115 if (type->isAtomicType()) {

2117 } else {

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

2123

2128 }

2129 return;

2130 }

2131 llvm_unreachable("bad evaluation kind");

2132}

2133

2134

2139

2140

2141

2143

2144 const VarDecl *var = emission.Variable;

2146

2149

2150 switch (dtorKind) {

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

2153

2155

2156

2157 if (emission.NRVOFlag) {

2158 assert(type->isArrayType());

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

2161 emission.NRVOFlag);

2162 return;

2163 }

2164 break;

2165

2167

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

2169

2170

2172

2173

2174 if (!var->hasAttr())

2176 break;

2177

2179 break;

2180

2183 if (emission.NRVOFlag) {

2184 assert(type->isArrayType());

2185 EHStack.pushCleanup(cleanupKind, addr,

2186 emission.NRVOFlag, type);

2187 return;

2188 }

2189 break;

2190 }

2191

2192

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

2194

2195

2196

2197 bool useEHCleanup = (cleanupKind & EHCleanup);

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

2199 useEHCleanup);

2200}

2201

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

2204

2205

2206 if (emission.wasEmittedAsGlobal()) return;

2207

2208

2209

2211

2212 const VarDecl &D = *emission.Variable;

2213

2214

2217

2218

2220 D.hasAttr()) {

2222 }

2223

2224

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

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

2227

2228 llvm::Constant *F = CGM.GetAddrOfFunction(FD);

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

2230

2231 const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD);

2233 CA);

2234 }

2235

2236

2237

2238

2239 if (emission.IsEscapingByRef &&

2245 false,

2247 }

2248}

2249

2252 switch (kind) {

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

2262 }

2263 llvm_unreachable("Unknown DestructionKind");

2264}

2265

2266

2267

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

2272

2274}

2275

2276

2277

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

2281

2285}

2286

2293

2296 bool useEHCleanupForArray) {

2298 useEHCleanupForArray);

2299}

2300

2301

2302

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

2306

2310}

2311

2314 bool useEHCleanupForArray) {

2315 llvm::Instruction *DominatingIP =

2316 Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));

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

2319 {EHStack.stable_begin(), DominatingIP});

2320}

2321

2323 EHStack.pushCleanup(Kind, SPMem);

2324}

2325

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

2328 EHStack.pushCleanup(Kind, AddrSizePair);

2329}

2330

2334 bool useEHCleanupForArray) {

2335

2336

2338

2339

2340

2341

2342

2344 useEHCleanupForArray);

2345

2346

2347

2350 useEHCleanupForArray);

2351 }

2352

2353

2354

2355 using ConditionalCleanupType =

2359

2360

2361

2364

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

2369

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

2371

2372

2373

2374

2375

2376

2379 cleanupKind, ActiveFlagForLifetimeExt, SavedAddr, type, destroyer,

2380 useEHCleanupForArray);

2381}

2382

2383

2384

2385

2386

2387

2388

2389

2390

2391

2392

2393

2396 bool useEHCleanupForArray) {

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

2400

2402

2406

2407

2408 bool checkZeroLength = true;

2409

2410

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

2412

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

2414 checkZeroLength = false;

2415 }

2416

2418 llvm::Value *end =

2421 checkZeroLength, useEHCleanupForArray);

2422}

2423

2424

2425

2426

2427

2428

2429

2430

2431

2432

2433

2435 llvm::Value *end,

2439 bool checkZeroLength,

2440 bool useEHCleanup) {

2442

2443

2444

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

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

2447

2448 if (checkZeroLength) {

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

2450 "arraydestroy.isempty");

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

2452 }

2453

2454

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

2457 llvm::PHINode *elementPast =

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

2459 elementPast->addIncoming(end, entryBB);

2460

2461

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

2464 llvm::Value *element = Builder.CreateInBoundsGEP(

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

2466

2467 if (useEHCleanup)

2469 destroyer);

2470

2471

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

2473 elementType);

2474

2475 if (useEHCleanup)

2477

2478

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

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

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

2482

2483

2485}

2486

2487

2488

2490 llvm::Value *begin, llvm::Value *end,

2494

2495

2496 unsigned arrayDepth = 0;

2498

2500 arrayDepth++;

2502 }

2503

2504 if (arrayDepth) {

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

2506

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

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

2512 }

2513

2514

2515

2516

2518 true, false);

2519}

2520

2521namespace {

2522

2523

2524

2525 class RegularPartialArrayDestroy final : public EHScopeStack::Cleanup {

2526 llvm::Value *ArrayBegin;

2527 llvm::Value *ArrayEnd;

2528 QualType ElementType;

2530 CharUnits ElementAlign;

2531 public:

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

2533 QualType elementType, CharUnits elementAlign,

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

2536 ElementType(elementType), Destroyer(destroyer),

2537 ElementAlign(elementAlign) {}

2538

2539 void Emit(CodeGenFunction &CGF, Flags flags) override {

2541 ElementType, ElementAlign, Destroyer);

2542 }

2543 };

2544

2545

2546

2547

2548 class IrregularPartialArrayDestroy final : public EHScopeStack::Cleanup {

2549 llvm::Value *ArrayBegin;

2550 Address ArrayEndPointer;

2551 QualType ElementType;

2553 CharUnits ElementAlign;

2554 public:

2555 IrregularPartialArrayDestroy(llvm::Value *arrayBegin,

2556 Address arrayEndPointer,

2557 QualType elementType,

2558 CharUnits elementAlign,

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

2561 ElementType(elementType), Destroyer(destroyer),

2562 ElementAlign(elementAlign) {}

2563

2564 void Emit(CodeGenFunction &CGF, Flags flags) override {

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

2567 ElementType, ElementAlign, Destroyer);

2568 }

2569 };

2570}

2571

2572

2573

2574

2575

2576

2577

2579 Address arrayEndPointer,

2585 elementAlign, destroyer);

2586}

2587

2588

2589

2590

2591

2592

2593

2595 llvm::Value *arrayEnd,

2600 arrayBegin, arrayEnd,

2601 elementType, elementAlign,

2602 destroyer);

2603}

2604

2605

2607 if (LifetimeStartFn)

2608 return LifetimeStartFn;

2609 LifetimeStartFn = llvm::Intrinsic::getOrInsertDeclaration(

2611 return LifetimeStartFn;

2612}

2613

2614

2616 if (LifetimeEndFn)

2617 return LifetimeEndFn;

2618 LifetimeEndFn = llvm::Intrinsic::getOrInsertDeclaration(

2620 return LifetimeEndFn;

2621}

2622

2623

2625 if (FakeUseFn)

2626 return FakeUseFn;

2627 FakeUseFn = llvm::Intrinsic::getOrInsertDeclaration(

2628 &getModule(), llvm::Intrinsic::fake_use);

2629 return FakeUseFn;

2630}

2631

2632namespace {

2633

2634

2635

2636

2637 struct ConsumeARCParameter final : EHScopeStack::Cleanup {

2638 ConsumeARCParameter(llvm::Value *param,

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

2641

2642 llvm::Value *Param;

2644

2647 }

2648 };

2649}

2650

2651

2652

2654 unsigned ArgNo) {

2655 bool NoDebugInfo = false;

2656

2658 "Invalid argument to EmitParmDecl");

2659

2660

2661

2664

2666

2667

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

2669

2670

2676 return;

2677 }

2678

2679

2680 NoDebugInfo =

2682 }

2683

2686 bool DoStore = false;

2688 bool UseIndirectDebugAddress = false;

2689

2690

2694

2695

2696 auto AllocaAS = CGM.getASTAllocaAddressSpace();

2699

2700

2701

2705 if (UseIndirectDebugAddress) {

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

2710 }

2711

2713 auto DestLangAS =

2715 if (SrcLangAS != DestLangAS) {

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

2717 CGM.getDataLayout().getAllocaAddrSpace());

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

2721 getTargetHooks().performAddrSpaceCast(*this, V, SrcLangAS, T, true),

2723 }

2724

2725

2726

2727

2734 "unexpected destructor type");

2738 }

2739 }

2740 } else {

2741

2742 Address OpenMPLocalAddr =

2744 ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D)

2747 DeclPtr = OpenMPLocalAddr;

2748 AllocaPtr = DeclPtr;

2749 } else {

2750

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

2753 }

2754 DoStore = true;

2755 }

2756

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

2758

2760 if (IsScalar) {

2763

2764

2765

2766

2767 bool isConsumed = D.hasAttr();

2768

2769

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

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

2775 }

2776

2777

2779 ArgVal = Builder.CreateLoad(DeclPtr);

2780

2782 if (!isConsumed) {

2783 if (CGM.getCodeGenOpts().OptimizationLevel == 0) {

2784

2785

2786

2787 llvm::Value *Null = CGM.EmitNullConstant(D.getType());

2790 DoStore = false;

2791 }

2792 else

2793

2794

2795

2797 }

2798 } else {

2799

2800 if (isConsumed) {

2804 precise);

2805 }

2806

2809 DoStore = false;

2810 }

2811 }

2812

2813

2815 }

2816 }

2817

2818

2819 if (DoStore)

2821

2822 setAddrOfLocalVar(&D, DeclPtr);

2823

2824

2825

2826

2827 if (CGM.getCodeGenOpts().getExtendVariableLiveness() ==

2829 (CGM.getCodeGenOpts().getExtendVariableLiveness() ==

2831 &D == CXXABIThisDecl)) {

2834 }

2835

2836

2838 if (CGM.getCodeGenOpts().hasReducedDebugInfo() && CurFuncIsThunk &&

2839 !NoDebugInfo) {

2840 llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable(

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

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

2843 DI->getParamDbgMappings().insert({Var, DILocalVar});

2844 }

2845 }

2846

2847 if (D.hasAttr())

2849

2850

2851

2852

2853 if (requiresReturnValueNullabilityCheck()) {

2857 RetValNullabilityPrecondition =

2858 Builder.CreateAnd(RetValNullabilityPrecondition,

2860 }

2861 }

2862}

2863

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

2867 return;

2869}

2870

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

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

2875 return;

2877}

2878

2883

2888

2892

2897

2898

2899 if (!VD->hasGlobalStorage())

2900 continue;

2901

2902

2903

2904

2905

2906

2907

2908

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

2911 if (!Entry)

2912 continue;

2913

2914

2915

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

2919 continue;

2920

2921 llvm::PointerType *PTy = llvm::PointerType::get(getLLVMContext(), TargetAS);

2922

2923

2924

2925

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

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

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

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

2930 Entry->replaceAllUsesWith(DummyGV);

2931

2932 Entry->mutateType(PTy);

2933 llvm::Constant *NewPtrForOldDecl =

2934 llvm::ConstantExpr::getAddrSpaceCast(Entry, DummyGV->getType());

2935

2936

2937

2938 DummyGV->replaceAllUsesWith(NewPtrForOldDecl);

2939 DummyGV->eraseFromParent();

2940 }

2941}

2942

2943std::optional

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

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

2947 unsigned UserAlign =

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

2951

2952

2953

2954

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

2957 }

2958 }

2959 return std::nullopt;

2960}

Defines the clang::ASTContext interface.

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

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

Definition CGDecl.cpp:1758

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.

Definition CGDecl.cpp:2489

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

Definition CGDecl.cpp:911

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

Generate a constant filled with either a pattern or zeroes.

Definition CGDecl.cpp:1043

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.

Definition CGDecl.cpp:1095

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

Definition CGDecl.cpp:1017

IsPattern

Definition CGDecl.cpp:1040

@ Yes

Definition CGDecl.cpp:1040

@ No

Definition CGDecl.cpp:1040

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

Definition CGDecl.cpp:1029

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

Definition CGDecl.cpp:1323

static bool shouldExtendLifetime(const ASTContext &Context, const Decl *FuncDecl, const VarDecl &D, ImplicitParamDecl *CXXABIThisDecl)

Definition CGDecl.cpp:1454

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

Definition CGDecl.cpp:710

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

Definition CGDecl.cpp:996

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

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

Definition CGDecl.cpp:1055

static bool containsUndef(llvm::Constant *constant)

Definition CGDecl.cpp:1312

static uint64_t maxFakeUseAggregateSize(const ASTContext &C)

Return the maximum size of an aggregate for which we generate a fake use intrinsic when -fextend-vari...

Definition CGDecl.cpp:1448

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

Definition CGDecl.cpp:678

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

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

Definition CGDecl.cpp:642

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

Definition CGDecl.cpp:1181

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

Definition CGDecl.cpp:759

static std::string getStaticDeclName(CIRGenModule &cgm, const VarDecl &d)

This file defines OpenACC nodes for declarative directives.

This file defines OpenMP nodes for declarative directives.

FormatToken * Next

The next token in the unwrapped line.

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.

static const NamedDecl * getDefinition(const Decl *D)

__device__ __2f16 float __ockl_bool s

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

CharUnits getTypeAlignInChars(QualType T) const

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

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.

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.

llvm::PointerType * getType() const

Return the type of the pointer value.

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)

A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.

static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)

Apply TemporaryLocation if it is valid.

static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)

Set the IRBuilder to not attach debug locations.

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.

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.

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

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 void emitUserDefinedReduction(CodeGenFunction *CGF, const OMPDeclareReductionDecl *D)

Emit code for the specified user defined reduction construct.

void add(RValue rvalue, QualType type)

Address getAllocatedAddress() const

Returns the raw, allocated address, which is not necessarily the address of the object itself.

bool useLifetimeMarkers() const

RawAddress getOriginalAllocatedAddress() const

Returns the address for the original alloca instruction.

Address getObjectAddress(CodeGenFunction &CGF) const

Returns the address of the object within this declaration.

llvm::Value * getDirectValue() const

Address getIndirectAddress() const

llvm::Value * getAnyValue() const

Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.

RAII object to set/unset CodeGenFunction::IsSanitizerScope.

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

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

emitArrayDestroy - Destroys all the elements of the given array, beginning from last to first.

Definition CGDecl.cpp:2434

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

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

void EmitARCMoveWeak(Address dst, Address src)

void @objc_moveWeak(i8** dest, i8** src) Disregards the current value in dest.

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

emitDestroy - Immediately perform the destruction of the given object.

Definition CGDecl.cpp:2394

static Destroyer destroyNonTrivialCStruct

AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)

Determine whether a field initialization may overlap some other object.

void emitByrefStructureInit(const AutoVarEmission &emission)

Initialize the structural components of a __block variable, i.e.

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

EmitARCUnsafeUnretainedScalarExpr - Semantically equivalent to immediately releasing the resut of Emi...

SanitizerSet SanOpts

Sanitizers enabled for this function.

void pushStackRestore(CleanupKind kind, Address SPMem)

Definition CGDecl.cpp:2322

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 EmitARCInitWeak(Address addr, llvm::Value *value)

i8* @objc_initWeak(i8** addr, i8* value) Returns value.

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

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

static bool hasScalarEvaluationKind(QualType T)

llvm::Type * ConvertType(QualType T)

void EmitFakeUse(Address Addr)

Definition CGDecl.cpp:1379

static Destroyer destroyARCWeak

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

pushEHDestroy - Push the standard destructor for the given type as an EH-only cleanup.

Definition CGDecl.cpp:2268

llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)

CleanupKind getARCCleanupKind()

Retrieves the default cleanup kind for an ARC cleanup.

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

bool CurFuncIsThunk

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

void EmitAtomicInit(Expr *E, LValue lvalue)

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

pushRegularPartialArrayCleanup - Push an EH cleanup to destroy already-constructed elements of the gi...

Definition CGDecl.cpp:2594

void EmitAutoVarDecl(const VarDecl &D)

EmitAutoVarDecl - Emit an auto variable declaration.

Definition CGDecl.cpp:1348

llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)

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

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

Enter a cleanup to destroy a __block variable.

void EmitAutoVarInit(const AutoVarEmission &emission)

Definition CGDecl.cpp:1929

llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack

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

createBasicBlock - Create an LLVM basic block.

void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)

See CGDebugInfo::addInstToCurrentSourceAtom.

const LangOptions & getLangOpts() const

RValue EmitReferenceBindingToExpr(const Expr *E)

Emits a reference binding to the passed in expression.

AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)

EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.

Definition CGDecl.cpp:1482

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

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

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

pushDestroy - Push the standard destructor for the given type as at least a normal cleanup.

Definition CGDecl.cpp:2278

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

Definition CGDecl.cpp:787

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.

Definition CGDecl.cpp:765

const CodeGen::CGBlockInfo * BlockInfo

static Destroyer destroyCXXObject

@ TCK_NonnullAssign

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

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

const BlockByrefInfo & getBlockByrefInfo(const VarDecl *var)

BuildByrefInfo - This routine changes a __block variable declared as T x into:

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

pushIrregularPartialArrayCleanup - Push a NormalAndEHCleanup to destroy already-constructed elements ...

Definition CGDecl.cpp:2578

const Decl * CurCodeDecl

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

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

Definition CGDecl.cpp:2251

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

Release the given object.

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

static bool cxxDestructorCanThrow(QualType T)

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

llvm::Constant * EmitCheckTypeDescriptor(QualType T)

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

void initFullExprCleanupWithFlag(RawAddress ActiveFlag)

void pushCleanupAndDeferDeactivation(CleanupKind Kind, As... A)

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

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

const TargetInfo & getTarget() const

void defaultInitNonTrivialCStructVar(LValue Dst)

void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)

Definition CGDecl.cpp:404

bool isInConditionalBranch() const

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

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

Definition CGDecl.cpp:2326

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

Definition CGDecl.cpp:2303

VlaSizePair getVLAElements1D(const VariableArrayType *vla)

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

void pushFullExprCleanup(CleanupKind kind, As... A)

pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.

static Destroyer destroyARCStrongImprecise

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

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

void EmitExtendGCLifetime(llvm::Value *object)

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

LValue EmitDeclRefLValue(const DeclRefExpr *E)

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

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

CGDebugInfo * getDebugInfo()

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

EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...

bool EmitLifetimeStart(llvm::Value *Addr)

Emit a lifetime.begin marker if some criteria are satisfied.

Definition CGDecl.cpp:1356

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

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

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

EmitComplexExpr - Emit the computation of the specified expression of complex 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,...

const TargetCodeGenInfo & getTargetHooks() const

void EmitLifetimeEnd(llvm::Value *Addr)

Definition CGDecl.cpp:1368

void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind, RawAddress ActiveFlag, As... A)

VlaSizePair getVLASize(const VariableArrayType *vla)

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

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

Enter a destroy cleanup for the given local variable.

Definition CGDecl.cpp:2135

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

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

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

const Decl * CurFuncDecl

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

void EmitAutoVarCleanups(const AutoVarEmission &emission)

Definition CGDecl.cpp:2202

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.

Definition CGDecl.cpp:1387

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)

Definition CGDecl.cpp:2331

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

EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.

Definition CGDecl.cpp:2653

Address ReturnValuePointer

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

bool needsEHCleanup(QualType::DestructionKind kind)

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

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

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

Definition CGDecl.cpp:353

CleanupKind getCleanupKind(QualType::DestructionKind kind)

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

Retain the given object, with normal retain semantics.

llvm::Type * ConvertTypeForMem(QualType T)

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

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 setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)

void EmitVarDecl(const VarDecl &D)

EmitVarDecl - Emit a local variable declaration.

Definition CGDecl.cpp:203

void EmitAggExpr(const Expr *E, AggValueSlot AS)

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

VarBypassDetector Bypasses

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

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

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

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

Store into a strong object.

RawAddress createCleanupActiveFlag()

const CGFunctionInfo * CurFnInfo

void EmitDecl(const Decl &D, bool EvaluateConditionDecl=false)

EmitDecl - Emit a declaration.

Definition CGDecl.cpp:52

std::pair< llvm::Value *, llvm::Value * > ComplexPairTy

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

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

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

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

i8* @objc_storeWeak(i8** addr, i8* value) Returns value.

void EnsureInsertPoint()

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

llvm::LLVMContext & getLLVMContext()

static Destroyer destroyARCStrongPrecise

void EmitARCCopyWeak(Address dst, Address src)

void @objc_copyWeak(i8** dest, i8** src) Disregards the current value in dest.

void EmitVariablyModifiedType(QualType Ty)

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

void MaybeEmitDeferredVarDeclInit(const VarDecl *var)

Definition CGDecl.cpp:2074

bool isTrivialInitializer(const Expr *Init)

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

Definition CGDecl.cpp:1807

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

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

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.

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

EmitBlock - Emit the given block.

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

Definition CGDecl.cpp:2092

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.

Definition CGDecl.cpp:2606

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

Definition CGDecl.cpp:1131

void EmitOpenACCDeclare(const OpenACCDeclareDecl *D, CodeGenFunction *CGF=nullptr)

Definition CGDecl.cpp:2879

const LangOptions & getLangOpts() const

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

CodeGenTypes & getTypes()

llvm::Function * getLLVMFakeUseFn()

Lazily declare the @llvm.fake.use intrinsic.

Definition CGDecl.cpp:2624

void EmitOMPAllocateDecl(const OMPAllocateDecl *D)

Emit a code for the allocate directive.

Definition CGDecl.cpp:2893

const llvm::DataLayout & getDataLayout() const

CGOpenMPRuntime & getOpenMPRuntime()

Return a reference to the configured OpenMP runtime.

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

Definition CGDecl.cpp:256

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

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.

Definition CGDecl.cpp:2871

llvm::Function * getLLVMLifetimeEndFn()

Lazily declare the @llvm.lifetime.end intrinsic.

Definition CGDecl.cpp:2615

bool supportsCOMDAT() const

void EmitOMPRequiresDecl(const OMPRequiresDecl *D)

Emit a code for requires directive.

Definition CGDecl.cpp:2889

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.

Definition CGDecl.cpp:2944

llvm::LLVMContext & getLLVMContext()

llvm::GlobalValue * GetGlobalValue(StringRef Ref)

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

Emit a code for declare reduction construct.

Definition CGDecl.cpp:2864

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

void EmitOpenACCRoutine(const OpenACCRoutineDecl *D, CodeGenFunction *CGF=nullptr)

Definition CGDecl.cpp:2884

llvm::ConstantInt * getSize(CharUnits numChars)

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

llvm::Type * ConvertTypeForMem(QualType T)

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

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

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

void finalize(llvm::GlobalVariable *global)

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.

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

LValue - This represents an lvalue references.

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

const Qualifiers & getQuals() 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()

Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, 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...

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

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

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.

bool isConstantInitializer(ASTContext &Ctx, bool ForRef, const Expr **Culprit=nullptr) const

isConstantInitializer - Returns true if this expression can be emitted to IR as a constant,...

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.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

std::string getNameAsString() const

Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...

bool isExternallyVisible() const

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.

Pointer-authentication qualifiers.

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

@ 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 isObjCGCWeak() const

true when Type is objc's weak.

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.

PointerAuthQualifier getPointerAuth() const

ObjCLifetime getObjCLifetime() const

bool isParamDestroyedInCallee() 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.

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isConstantSizeType() const

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

RecordDecl * castAsRecordDecl() const

bool isVariablyModifiedType() const

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

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

Whether this variable is (C++11) constexpr.

TLSKind getTLSKind() const

bool hasFlexibleArrayInit(const ASTContext &Ctx) const

Whether this variable has a flexible array member initialized with one or more elements.

bool hasGlobalStorage() const

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

CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const

If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...

bool mightBeUsableInConstantExpressions(const ASTContext &C) const

Determine whether this variable's value might be usable in a constant expression, according to the re...

bool isNRVOVariable() const

Determine whether this local variable can be used with the named return value optimization (NRVO).

bool isExceptionVariable() const

Determine whether this variable is the exception variable in a C++ catch statememt or an Objective-C ...

QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const

Would the destruction of this variable have any effect, and if so, what kind?

const Expr * getInit() const

bool hasExternalStorage() const

Returns true if a variable has extern or private_extern storage.

bool isARCPseudoStrong() const

Determine whether this variable is an ARC pseudo-__strong variable.

bool hasLocalStorage() const

Returns true if a variable with function scope is a non-static local variable.

bool isLocalVarDecl() const

Returns true for local variable declarations other than parameters.

StorageDuration getStorageDuration() const

Get the storage duration of this variable, per C++ [basic.stc].

bool isEscapingByref() const

Indicates the capture is a __block variable that is captured by a block that can potentially escape (...

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

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.

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

@ Ctor_Base

Base object ctor.

bool isa(CodeGen::Address addr)

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

const FunctionProtoType * T

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

U cast(CodeGen::Address addr)

@ 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 * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * SizeTy

llvm::IntegerType * IntPtrTy

llvm::PointerType * Int8PtrTy

llvm::PointerType * AllocaInt8PtrTy