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"
50 "Clang max alignment greater than what LLVM supports?");
54 case Decl::BuiltinTemplate:
55 case Decl::TranslationUnit:
56 case Decl::ExternCContext:
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:
68 case Decl::CXXConstructor:
69 case Decl::CXXDestructor:
70 case Decl::CXXConversion:
72 case Decl::MSProperty:
73 case Decl::IndirectField:
75 case Decl::ObjCAtDefsField:
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:
96 case Decl::ObjCPropertyImpl:
97 case Decl::FileScopeAsm:
98 case Decl::TopLevelStmt:
100 case Decl::FriendTemplate:
102 case Decl::OutlinedFunction:
104 case Decl::UsingShadow:
105 case Decl::ConstructorUsingShadow:
106 case Decl::ObjCTypeParam:
108 case Decl::UnresolvedUsingIfExists:
109 case Decl::HLSLBuffer:
110 case Decl::HLSLRootSignature:
111 llvm_unreachable(
"Declaration should not be in declstmts!");
113 case Decl::CXXRecord:
116 DI->EmitAndRetainType(
122 DI->EmitAndRetainType(
126 case Decl::EnumConstant:
127 case Decl::StaticAssert:
128 case Decl::ExplicitInstantiation:
132 case Decl::UnnamedGlobalConstant:
133 case Decl::TemplateParamObject:
134 case Decl::OMPThreadPrivate:
135 case Decl::OMPGroupPrivate:
136 case Decl::OMPAllocate:
137 case Decl::OMPCapturedExpr:
138 case Decl::OMPRequires:
141 case Decl::ImplicitConceptSpecialization:
142 case Decl::LifetimeExtendedTemporary:
143 case Decl::RequiresExprBody:
147 case Decl::CXXExpansionStmt: {
149 assert(ESD->getInstantiations() &&
"expansion statement not expanded?");
154 case Decl::NamespaceAlias:
162 case Decl::UsingEnum:
166 case Decl::UsingPack:
168 EmitDecl(*Using, EvaluateConditionDecl);
170 case Decl::UsingDirective:
175 case Decl::Decomposition: {
178 "Should not see file-scope variables inside a function!");
180 if (EvaluateConditionDecl)
186 case Decl::OMPDeclareReduction:
189 case Decl::OMPDeclareMapper:
192 case Decl::OpenACCDeclare:
194 case Decl::OpenACCRoutine:
198 case Decl::TypeAlias: {
201 DI->EmitAndRetainType(Ty);
224 llvm::GlobalValue::LinkageTypes
Linkage =
225 CGM.getLLVMLinkageVarDefinition(&D);
235 return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*
this, D);
247 std::string ContextName;
249 if (
auto *CD = dyn_cast<CapturedDecl>(DC))
251 if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
253 else if (
const auto *BD = dyn_cast<BlockDecl>(DC))
255 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(DC))
256 ContextName = OMD->getSelector().getAsString();
258 llvm_unreachable(
"Unknown context for static var decl");
270 if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&D])
289 llvm::Constant *
Init =
nullptr;
291 D.
hasAttr<CUDASharedAttr>() || D.
hasAttr<LoaderUninitializedAttr>())
292 Init = llvm::UndefValue::get(LTy);
296 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
298 nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
299 GV->setAlignment(
getContext().getDeclAlign(&D).getAsAlign());
302 GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
312 llvm::Constant *
Addr = GV;
313 if (AS != ExpectedAS) {
317 getContext().getTargetAddressSpace(ExpectedAS)));
336 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
338 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
340 else if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
360llvm::GlobalVariable *
362 llvm::GlobalVariable *GV) {
370 CGM.ErrorUnsupported(D.
getInit(),
"constant l-value expression");
372 CGM.ErrorUnsupported(D.
getInit(),
"flexible array initializer");
376 GV->setConstant(
false);
383 PGO->markStmtMaybeUsed(D.
getInit());
389 CGM.getDataLayout().getTypeAllocSize(
Init->getType()));
390 assert(VarSize == CstSize &&
"Emitted constant has unexpected size");
398 GV->replaceInitializer(
Init);
413 llvm::GlobalValue::LinkageTypes
Linkage) {
417 llvm::Constant *addr =
CGM.getOrCreateStaticVarDecl(D,
Linkage);
423 setAddrOfLocalVar(&D,
Address(addr, elemTy, alignment));
432 llvm::Type *expectedType = addr->getType();
434 llvm::GlobalVariable *var =
444 if (D.
getInit() && !isCudaSharedVar) {
452 CGM.AddGlobalAnnotations(&D, var);
454 if (
auto *SA = D.
getAttr<PragmaClangBSSSectionAttr>())
455 var->addAttribute(
"bss-section", SA->getName());
456 if (
auto *SA = D.
getAttr<PragmaClangDataSectionAttr>())
457 var->addAttribute(
"data-section", SA->getName());
458 if (
auto *SA = D.
getAttr<PragmaClangRodataSectionAttr>())
459 var->addAttribute(
"rodata-section", SA->getName());
460 if (
auto *SA = D.
getAttr<PragmaClangRelroSectionAttr>())
461 var->addAttribute(
"relro-section", SA->getName());
463 if (
const SectionAttr *SA = D.
getAttr<SectionAttr>())
464 var->setSection(SA->getName());
467 CGM.addUsedGlobal(var);
468 else if (D.
hasAttr<UsedAttr>())
469 CGM.addUsedOrCompilerUsedGlobal(var);
471 if (
CGM.getCodeGenOpts().KeepPersistentStorageVariables)
472 CGM.addUsedOrCompilerUsedGlobal(var);
479 llvm::Constant *castedAddr =
480 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
481 LocalDeclMap.find(&D)->second =
Address(castedAddr, elemTy, alignment);
482 CGM.setStaticLocalDeclAddress(&D, castedAddr);
484 CGM.getSanitizerMetadata()->reportGlobal(var, D);
488 if (DI &&
CGM.getCodeGenOpts().hasReducedDebugInfo()) {
495 struct DestroyObject final : EHScopeStack::Cleanup {
498 bool useEHCleanupForArray)
499 : addr(addr),
type(
type), destroyer(destroyer),
500 useEHCleanupForArray(useEHCleanupForArray) {}
505 bool useEHCleanupForArray;
509 bool useEHCleanupForArray =
510 flags.isForNormalCleanup() && this->useEHCleanupForArray;
516 template <
class Derived>
517 struct DestroyNRVOVariable : EHScopeStack::Cleanup {
518 DestroyNRVOVariable(Address addr, QualType
type, llvm::Value *NRVOFlag)
519 : NRVOFlag(NRVOFlag), Loc(addr), Ty(
type) {}
521 llvm::Value *NRVOFlag;
525 void Emit(CodeGenFunction &CGF, Flags flags)
override {
527 bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
529 llvm::BasicBlock *SkipDtorBB =
nullptr;
534 llvm::Value *DidNRVO =
536 CGF.
Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
540 static_cast<Derived *
>(
this)->emitDestructorCall(CGF);
545 virtual ~DestroyNRVOVariable() =
default;
548 struct DestroyNRVOVariableCXX final
549 : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
550 DestroyNRVOVariableCXX(Address addr, QualType
type,
551 const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag)
552 : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr,
type, NRVOFlag),
555 const CXXDestructorDecl *
Dtor;
557 void emitDestructorCall(CodeGenFunction &CGF) {
564 struct DestroyNRVOVariableC final
565 : DestroyNRVOVariable<DestroyNRVOVariableC> {
566 DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)
567 : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
569 void emitDestructorCall(CodeGenFunction &CGF) {
574 struct CallStackRestore final : EHScopeStack::Cleanup {
576 CallStackRestore(Address Stack) : Stack(Stack) {}
577 void Emit(CodeGenFunction &CGF, Flags flags)
override {
583 struct KmpcAllocFree final : EHScopeStack::Cleanup {
584 std::pair<llvm::Value *, llvm::Value *> AddrSizePair;
585 KmpcAllocFree(
const std::pair<llvm::Value *, llvm::Value *> &AddrSizePair)
586 : AddrSizePair(AddrSizePair) {}
587 void Emit(CodeGenFunction &CGF, Flags EmissionFlags)
override {
593 struct ExtendGCLifetime final : EHScopeStack::Cleanup {
595 ExtendGCLifetime(
const VarDecl *var) : Var(*
var) {}
597 void Emit(CodeGenFunction &CGF, Flags flags)
override {
600 DeclRefExpr DRE(CGF.
getContext(),
const_cast<VarDecl *
>(&Var),
false,
601 Var.getType(),
VK_LValue, SourceLocation());
608 struct CallCleanupFunction final : EHScopeStack::Cleanup {
609 llvm::Constant *CleanupFn;
610 const CGFunctionInfo &FnInfo;
612 const CleanupAttr *Attribute;
614 CallCleanupFunction(llvm::Constant *CleanupFn,
const CGFunctionInfo *Info,
615 const VarDecl *Var,
const CleanupAttr *Attr)
616 : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Attribute(Attr) {}
618 void Emit(CodeGenFunction &CGF, Flags flags)
override {
619 DeclRefExpr DRE(CGF.
getContext(),
const_cast<VarDecl *
>(&Var),
false,
638 GlobalDecl GD = GlobalDecl(Attribute->getFunctionDecl());
640 CGF.
EmitCall(FnInfo, Callee, ReturnValueSlot(), Args,
642 Attribute->getLoc());
654 llvm_unreachable(
"present but none");
662 (var.hasAttr<ObjCPreciseLifetimeAttr>()
667 CGF.
pushDestroy(cleanupKind, addr, var.getType(), destroyer,
686 if (
const Expr *e = dyn_cast<Expr>(s)) {
689 s = e = e->IgnoreParenCasts();
691 if (
const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e))
692 return (ref->getDecl() == &var);
693 if (
const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
694 const BlockDecl *block = be->getBlockDecl();
695 for (
const auto &I : block->
captures()) {
696 if (I.getVariable() == &var)
711 if (!
decl)
return false;
718 const LValue &destLV,
const Expr *init) {
719 bool needsCast =
false;
726 case CK_BlockPointerToObjCPointerCast:
732 case CK_LValueToRValue: {
741 auto srcAddr = srcLV.getAddress();
743 srcAddr = srcAddr.withElementType(destLV.getAddress().getElementType());
774 if (!
SanOpts.has(SanitizerKind::NullabilityAssign))
783 auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign;
784 auto CheckHandler = SanitizerHandler::TypeMismatch;
788 IsNotNull =
CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this, RHS, MPT);
792 llvm::Constant *StaticData[] = {
794 llvm::ConstantInt::get(
Int8Ty, 0),
800 LValue lvalue,
bool capturedByInit) {
818 init = DIE->getExpr();
822 if (
auto *EWC = dyn_cast<ExprWithCleanups>(init)) {
824 return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit);
831 bool accessedByInit =
false;
833 accessedByInit = (capturedByInit ||
isAccessedBy(D, init));
834 if (accessedByInit) {
837 if (capturedByInit) {
846 llvm::Value *zero =
CGM.getNullPointer(ty, tempLV.
getType());
858 llvm::Value *value =
nullptr;
862 llvm_unreachable(
"present but none");
924 unsigned &NumStores) {
933 return Init->isNullValue() || NumStores--;
937 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
945 if (llvm::ConstantDataSequential *CDS =
946 dyn_cast<llvm::ConstantDataSequential>(
Init)) {
947 for (
unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
948 llvm::Constant *Elt = CDS->getElementAsConstant(i);
961void CodeGenFunction::emitStoresForInitAfterBZero(llvm::Constant *
Init,
965 "called emitStoresForInitAfterBZero for zero or undef value.");
970 auto *I =
Builder.CreateStore(
Init, Loc, isVolatile);
973 I->addAnnotationMetadata(
"auto-init");
977 if (llvm::ConstantDataSequential *CDS =
978 dyn_cast<llvm::ConstantDataSequential>(
Init)) {
979 for (
unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
980 llvm::Constant *Elt = CDS->getElementAsConstant(i);
984 emitStoresForInitAfterBZero(
985 Elt,
Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,
992 "Unknown value type!");
994 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
999 emitStoresForInitAfterBZero(Elt,
1000 Builder.CreateConstInBoundsGEP2_32(Loc, 0, i),
1001 isVolatile, IsAutoInit);
1009 uint64_t GlobalSize) {
1017 unsigned StoreBudget = 6;
1018 uint64_t SizeLimit = 32;
1020 return GlobalSize > SizeLimit &&
1030 uint64_t GlobalSize,
1031 const llvm::DataLayout &DL) {
1032 uint64_t SizeLimit = 32;
1033 if (GlobalSize <= SizeLimit)
1035 return llvm::isBytewiseValue(
Init, DL);
1042 uint64_t GlobalByteSize) {
1044 uint64_t ByteSizeLimit = 64;
1047 if (GlobalByteSize <= ByteSizeLimit)
1060 return llvm::Constant::getNullValue(Ty);
1064 llvm::Constant *constant);
1069 llvm::StructType *STy,
1070 llvm::Constant *constant) {
1072 const llvm::StructLayout *Layout = DL.getStructLayout(STy);
1073 llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.
getLLVMContext());
1074 unsigned SizeSoFar = 0;
1076 bool NestedIntact =
true;
1077 for (
unsigned i = 0, e = STy->getNumElements(); i != e; i++) {
1078 unsigned CurOff = Layout->getElementOffset(i);
1079 if (SizeSoFar < CurOff) {
1080 assert(!STy->isPacked());
1081 auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar);
1084 llvm::Constant *CurOp;
1085 if (constant->isNullValue())
1086 CurOp = llvm::Constant::getNullValue(STy->getElementType(i));
1091 NestedIntact =
false;
1092 Values.push_back(NewOp);
1093 SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType());
1095 unsigned TotalSize = Layout->getSizeInBytes();
1096 if (SizeSoFar < TotalSize) {
1097 auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar);
1100 if (NestedIntact && Values.size() == STy->getNumElements())
1102 return llvm::ConstantStruct::getAnon(Values, STy->isPacked());
1108 llvm::Constant *constant) {
1109 llvm::Type *OrigTy = constant->getType();
1110 if (
const auto STy = dyn_cast<llvm::StructType>(OrigTy))
1112 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(OrigTy)) {
1114 uint64_t Size = ArrayTy->getNumElements();
1117 llvm::Type *ElemTy = ArrayTy->getElementType();
1118 bool ZeroInitializer = constant->isNullValue();
1119 llvm::Constant *OpValue, *PaddedOp;
1120 if (ZeroInitializer) {
1121 OpValue = llvm::Constant::getNullValue(ElemTy);
1124 for (
unsigned Op = 0; Op != Size; ++Op) {
1125 if (!ZeroInitializer) {
1126 OpValue = constant->getAggregateElement(Op);
1129 Values.push_back(PaddedOp);
1131 auto *NewElemTy = Values[0]->getType();
1132 if (NewElemTy == ElemTy)
1134 auto *NewArrayTy = llvm::ArrayType::get(NewElemTy, Size);
1135 return llvm::ConstantArray::get(NewArrayTy, Values);
1146 auto FunctionName = [&](
const DeclContext *DC) -> std::string {
1147 if (
const auto *FD = dyn_cast<FunctionDecl>(DC)) {
1148 if (
const auto *CC = dyn_cast<CXXConstructorDecl>(FD))
1149 return CC->getNameAsString();
1150 if (
const auto *CD = dyn_cast<CXXDestructorDecl>(FD))
1151 return CD->getNameAsString();
1153 }
else if (
const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) {
1154 return OM->getNameAsString();
1158 return "<captured>";
1160 llvm_unreachable(
"expected a function or method");
1166 llvm::GlobalVariable *&CacheEntry = InitializerConstants[&D];
1167 if (!CacheEntry || CacheEntry->getInitializer() !=
Constant) {
1169 bool isConstant =
true;
1170 llvm::GlobalVariable *InsertBefore =
nullptr;
1177 Name = (
"__const." + FunctionName(DC) +
"." + D.
getName()).str();
1179 llvm_unreachable(
"local variable has no parent function or method");
1180 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
1181 getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
1182 Constant, Name, InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
1184 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1186 }
else if (CacheEntry->getAlign().valueOrOne() < Align.
getAsAlign()) {
1187 CacheEntry->setAlignment(Align.
getAsAlign());
1190 return Address(CacheEntry, CacheEntry->getValueType(), Align);
1202void CodeGenFunction::emitStoresForConstant(
const VarDecl &D,
Address Loc,
1204 llvm::Constant *constant,
1206 auto *Ty = constant->getType();
1207 uint64_t ConstantSize =
CGM.getDataLayout().getTypeAllocSize(Ty);
1211 bool canDoSingleStore = Ty->isIntOrIntVectorTy() ||
1212 Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy();
1213 if (canDoSingleStore) {
1214 auto *I =
Builder.CreateStore(constant, Loc, isVolatile);
1217 I->addAnnotationMetadata(
"auto-init");
1221 auto *SizeVal = llvm::ConstantInt::get(
CGM.IntPtrTy, ConstantSize);
1226 auto *I =
Builder.CreateMemSet(Loc, llvm::ConstantInt::get(
CGM.Int8Ty, 0),
1227 SizeVal, isVolatile);
1231 I->addAnnotationMetadata(
"auto-init");
1233 bool valueAlreadyCorrect =
1235 if (!valueAlreadyCorrect) {
1237 emitStoresForInitAfterBZero(constant, Loc, isVolatile, IsAutoInit);
1243 llvm::Value *Pattern =
1249 assert(AP.getBitWidth() <= 8);
1250 Value = AP.getLimitedValue();
1252 auto *I =
Builder.CreateMemSet(
1253 Loc, llvm::ConstantInt::get(
CGM.Int8Ty,
Value), SizeVal, isVolatile);
1256 I->addAnnotationMetadata(
"auto-init");
1262 bool IsTrivialAutoVarInitPattern =
1263 CGM.getContext().getLangOpts().getTrivialAutoVarInit() ==
1266 if (
auto *STy = dyn_cast<llvm::StructType>(Ty)) {
1267 if (STy == Loc.
getElementType() || IsTrivialAutoVarInitPattern) {
1268 const llvm::StructLayout *Layout =
1269 CGM.getDataLayout().getStructLayout(STy);
1270 for (
unsigned i = 0; i != constant->getNumOperands(); i++) {
1275 emitStoresForConstant(D, EltPtr, isVolatile,
1276 constant->getAggregateElement(i), IsAutoInit);
1280 }
else if (
auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) {
1281 if (ATy == Loc.
getElementType() || IsTrivialAutoVarInitPattern) {
1282 for (
unsigned i = 0; i != ATy->getNumElements(); i++) {
1285 emitStoresForConstant(D, EltPtr, isVolatile,
1286 constant->getAggregateElement(i), IsAutoInit);
1298 SizeVal, isVolatile);
1302 I->addAnnotationMetadata(
"auto-init");
1305void CodeGenFunction::emitStoresForZeroInit(
const VarDecl &D,
Address Loc,
1308 llvm::Constant *constant =
1310 emitStoresForConstant(D, Loc, isVolatile, constant,
1314void CodeGenFunction::emitStoresForPatternInit(
const VarDecl &D,
Address Loc,
1320 emitStoresForConstant(D, Loc, isVolatile, constant,
1325 auto *Ty = constant->getType();
1328 if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())
1329 for (llvm::Use &Op : constant->operands())
1336 llvm::Constant *constant) {
1337 auto *Ty = constant->getType();
1340 if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
1345 for (
unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
1349 if (Ty->isStructTy())
1351 if (Ty->isArrayTy())
1353 assert(Ty->isVectorTy());
1354 return llvm::ConstantVector::get(Values);
1369 if (!ShouldEmitLifetimeMarkers)
1372 assert(
Addr->getType()->getPointerAddressSpace() ==
1373 CGM.getDataLayout().getAllocaAddrSpace() &&
1374 "Pointer should be in alloca address space");
1375 llvm::CallInst *
C =
Builder.CreateCall(
CGM.getLLVMLifetimeStartFn(), {Addr});
1376 C->setDoesNotThrow();
1381 if (!ShouldEmitLifetimeMarkers)
1384 assert(
Addr->getType()->getPointerAddressSpace() ==
1385 CGM.getDataLayout().getAllocaAddrSpace() &&
1386 "Pointer should be in alloca address space");
1387 llvm::CallInst *
C =
Builder.CreateCall(
CGM.getLLVMLifetimeEndFn(), {Addr});
1388 C->setDoesNotThrow();
1394 llvm::CallInst *
C =
Builder.CreateCall(
CGM.getLLVMFakeUseFn(), {V});
1395 C->setDoesNotThrow();
1396 C->setTailCallKind(llvm::CallInst::TCK_NoTail);
1408 while (
getContext().getAsVariableArrayType(Type1D)) {
1410 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1414 Twine Name = Twine(
"__vla_expr") + Twine(VLAExprCounter++);
1416 StringRef NameRef = Name.toStringRef(Buffer);
1418 VLAExprNames.push_back(&Ident);
1421 Builder.CreateStore(VlaSize.NumElts, SizeExprAddr);
1422 Dimensions.emplace_back(SizeExprAddr.getPointer(),
1425 Type1D = VlaSize.Type;
1434 unsigned NameIdx = 0;
1435 for (
auto &VlaSize : Dimensions) {
1437 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1438 MD = llvm::ConstantAsMetadata::get(
C);
1443 SizeTy->getScalarSizeInBits(),
false);
1448 ArtificialDecl->setImplicit();
1453 assert(MD &&
"No Size expression debug node created");
1461 return 4 *
C.getTypeSize(
C.UnsignedIntTy);
1486 if (FuncDecl->
hasAttr<NoDebugAttr>() || FuncDecl->
hasAttr<OptimizeNoneAttr>())
1503 emission.IsEscapingByRef = isEscapingByRef;
1512 bool EmitDebugInfo = DI &&
CGM.getCodeGenOpts().hasReducedDebugInfo();
1517 if (
CGM.getLangOpts().OpenMPIRBuilder)
1522 ?
CGM.getOpenMPRuntime().getAddressOfLocalVariable(*
this, &D)
1528 address = OpenMPLocalAddr;
1529 AllocaAddr = OpenMPLocalAddr;
1541 getContext().getBaseElementType(Ty)->isObjCObjectPointerType())))) {
1542 emission.ConstantAggregateInitializer =
1544 if (emission.ConstantAggregateInitializer) {
1554 (
CGM.getCodeGenOpts().MergeAllConstants && !NRVO &&
1561 assert(emission.wasEmittedAsGlobal());
1578 address = MaybeCastStackAddressSpace(AllocaAddr, Ty.
getAddressSpace());
1581 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1582 (CXXRD && !CXXRD->hasTrivialDestructor()) ||
1583 RD->isNonTrivialToPrimitiveDestroy()) {
1600 llvm::Type *allocaTy;
1601 if (isEscapingByRef) {
1603 allocaTy = byrefInfo.Type;
1604 allocaAlignment = byrefInfo.ByrefAlignment;
1607 allocaAlignment = alignment;
1615 nullptr, &AllocaAddr);
1620 bool IsMSCatchParam =
1641 emission.UseLifetimeMarkers =
1652 if (
Bypasses.IsBypassed(&D) && !emission.IsEscapingByRef &&
1654 getAutoVarInitKind(Ty, D) !=
1656 if (!
Bypasses.isAlwaysBypassed()) {
1664 const auto *Vars =
Bypasses.getBypassedVarsForSource(FG.Source);
1665 if (!Vars || !Vars->contains(&D))
1667 llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
1668 Builder.SetInsertPoint(FG.Block->getTerminator());
1669 emitZeroOrPatternForAutoVarInit(Ty, D, address);
1675 llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
1677 emitZeroOrPatternForAutoVarInit(Ty, D, address);
1681 if (D.
hasAttr<StackProtectorIgnoreAttr>()) {
1682 if (
auto *AI = dyn_cast<llvm::AllocaInst>(address.
getBasePointer())) {
1683 llvm::LLVMContext &Ctx =
Builder.getContext();
1684 auto *Operand = llvm::ConstantAsMetadata::get(
Builder.getInt32(0));
1685 AI->setMetadata(
"stack-protector", llvm::MDNode::get(Ctx, {Operand}));
1688 std::optional<llvm::Attribute::AttrKind>
Attr =
1689 CGM.StackProtectorAttribute(&D);
1690 if (
Attr && (*
Attr == llvm::Attribute::StackProtectReq)) {
1692 diag::warn_stack_protection_ignore_attribute);
1703 bool VarAllocated =
false;
1705 auto &RT =
CGM.getOpenMPRuntime();
1706 if (RT.isDelayedVariableLengthDecl(*
this, &D)) {
1708 std::pair<llvm::Value *, llvm::Value *> AddrSizePair =
1709 RT.getKmpcAllocShared(*
this, &D);
1713 CGM.getContext().getDeclAlign(&D),
1715 address =
Base.getAddress();
1723 VarAllocated =
true;
1727 if (!VarAllocated) {
1728 if (!DidCallStackSave) {
1733 llvm::Value *
V =
Builder.CreateStackSave();
1737 DidCallStackSave =
true;
1758 setAddrOfLocalVar(&D, address);
1759 emission.Addr = address;
1760 emission.AllocaAddr = AllocaAddr;
1769 if (UsePointerValue) {
1790 if (
CGM.getCodeGenOpts().getExtendVariableLiveness() ==
1805 if (
const Expr *E = dyn_cast<Expr>(S))
1820 if (
const BlockExpr *BE = dyn_cast<BlockExpr>(E)) {
1822 for (
const auto &I :
Block->captures()) {
1823 if (I.getVariable() == &Var)
1831 if (
const StmtExpr *SE = dyn_cast<StmtExpr>(E)) {
1833 for (
const auto *BI : CS->
body())
1834 if (
const auto *BIE = dyn_cast<Expr>(BI)) {
1838 else if (
const auto *DS = dyn_cast<DeclStmt>(BI)) {
1840 for (
const auto *I : DS->decls()) {
1841 if (
const auto *VD = dyn_cast<VarDecl>((I))) {
1872 !Construct->requiresZeroInitialization())
1880 auto hasNoTrivialAutoVarInitAttr = [](
const Decl *D) {
1881 return D && D->
hasAttr<NoTrivialAutoVarInitAttr>();
1897 const auto *Vars =
Bypasses.getBypassedVarsForSource(Source);
1900 for (
const VarDecl *VD : *Vars) {
1903 emitZeroOrPatternForAutoVarInit(VD->getType(), *VD, It->second);
1907void CodeGenFunction::emitZeroOrPatternForAutoVarInit(
QualType type,
1911 auto trivialAutoVarInitMaxSize =
1914 bool isVolatile =
type.isVolatileQualified();
1915 if (!Size.isZero()) {
1922 switch (trivialAutoVarInit) {
1924 llvm_unreachable(
"Uninitialized handled by caller");
1928 if (trivialAutoVarInitMaxSize > 0 &&
1929 allocSize > trivialAutoVarInitMaxSize)
1931 emitStoresForZeroInit(D, Loc, isVolatile);
1936 if (trivialAutoVarInitMaxSize > 0 &&
1937 allocSize > trivialAutoVarInitMaxSize)
1939 emitStoresForPatternInit(D, Loc, isVolatile);
1954 auto SizeVal = VlaSize.NumElts;
1956 switch (trivialAutoVarInit) {
1958 llvm_unreachable(
"Uninitialized handled by caller");
1963 if (!EltSize.
isOne())
1964 SizeVal = Builder.CreateNUWMul(SizeVal,
CGM.
getSize(EltSize));
1965 auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(
Int8Ty, 0),
1966 SizeVal, isVolatile);
1967 I->addAnnotationMetadata(
"auto-init");
1972 if (
CGM.stopAutoInit())
1981 llvm::Value *IsZeroSizedVLA =
Builder.CreateICmpEQ(
1982 SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0),
1984 Builder.CreateCondBr(IsZeroSizedVLA, ContBB, SetupBB);
1986 if (!EltSize.
isOne())
1987 SizeVal =
Builder.CreateNUWMul(SizeVal,
CGM.getSize(EltSize));
1988 llvm::Value *BaseSizeInChars =
1993 SizeVal,
"vla.end");
1994 llvm::BasicBlock *OriginBB =
Builder.GetInsertBlock();
1996 llvm::PHINode *Cur =
Builder.CreatePHI(Begin.
getType(), 2,
"vla.cur");
2003 BaseSizeInChars, isVolatile);
2004 I->addAnnotationMetadata(
"auto-init");
2006 Builder.CreateInBoundsGEP(
Int8Ty, Cur, BaseSizeInChars,
"vla.next");
2007 llvm::Value *Done =
Builder.CreateICmpEQ(
Next, End,
"vla-init.isdone");
2008 Builder.CreateCondBr(Done, ContBB, LoopBB);
2009 Cur->addIncoming(
Next, LoopBB);
2016 assert(emission.Variable &&
"emission was not valid!");
2019 if (emission.wasEmittedAsGlobal())
return;
2021 const VarDecl &D = *emission.Variable;
2033 PGO->markStmtMaybeUsed(
Init);
2040 if (emission.IsEscapingByRef)
2047 type.isNonTrivialToPrimitiveDefaultInitialize() ==
2050 if (emission.IsEscapingByRef)
2059 bool capturedByInit =
2062 bool locIsByrefHeader = !capturedByInit;
2068 getAutoVarInitKind(
type, D);
2070 auto initializeWhatIsTechnicallyUninitialized = [&](
Address Loc) {
2071 if (trivialAutoVarInit ==
2076 if (emission.IsEscapingByRef && !locIsByrefHeader)
2079 return emitZeroOrPatternForAutoVarInit(
type, D, Loc);
2083 return initializeWhatIsTechnicallyUninitialized(Loc);
2085 llvm::Constant *constant =
nullptr;
2086 if (emission.ConstantAggregateInitializer ||
2088 assert(!capturedByInit &&
"constant init contains a capturing block?");
2089 if (emission.ConstantAggregateInitializer)
2090 constant = emission.ConstantAggregateInitializer;
2093 if (constant && !constant->isNullValue() &&
2094 (trivialAutoVarInit !=
2110 if (constant &&
type->isBitIntType() &&
2111 CGM.getTypes().typeRequiresSplitIntoByteArray(
type)) {
2115 llvm::Type *LoadType =
2116 CGM.getTypes().convertTypeForLoadStore(
type, constant->getType());
2117 constant = llvm::ConstantFoldLoadFromConst(
2118 constant, LoadType, llvm::APInt::getZero(32),
CGM.getDataLayout());
2123 if (trivialAutoVarInit !=
2134 initializeWhatIsTechnicallyUninitialized(Loc);
2142 PGO->markStmtMaybeUsed(
Init);
2144 if (!emission.ConstantAggregateInitializer) {
2152 type.isVolatileQualified(), constant,
2157 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
2158 for (
auto *B : DD->flat_bindings())
2159 if (
auto *HD = B->getHoldingVar())
2175 LValue lvalue,
bool capturedByInit) {
2178 if (
type->isReferenceType()) {
2197 if (
type->isAtomicType()) {
2203 else if (
auto *FD = dyn_cast<FieldDecl>(D))
2213 llvm_unreachable(
"bad evaluation kind");
2226 const VarDecl *var = emission.Variable;
2234 llvm_unreachable(
"no cleanup for trivially-destructible variable");
2239 if (emission.NRVOFlag) {
2240 assert(!
type->isArrayType());
2242 EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr,
type, dtor,
2250 if (var->isARCPseudoStrong())
return;
2256 if (!var->hasAttr<ObjCPreciseLifetimeAttr>())
2265 if (emission.NRVOFlag) {
2266 assert(!
type->isArrayType());
2267 EHStack.pushCleanup<DestroyNRVOVariableC>(cleanupKind, addr,
2268 emission.NRVOFlag,
type);
2279 bool useEHCleanup = (cleanupKind &
EHCleanup);
2280 EHStack.pushCleanup<DestroyObject>(cleanupKind, addr,
type, destroyer,
2285 assert(emission.Variable &&
"emission was not valid!");
2288 if (emission.wasEmittedAsGlobal())
return;
2294 const VarDecl &D = *emission.Variable;
2301 diag::err_seh_object_unwinding);
2307 D.
hasAttr<ObjCPreciseLifetimeAttr>()) {
2312 if (
const CleanupAttr *CA = D.
getAttr<CleanupAttr>()) {
2315 llvm::Constant *F =
CGM.GetAddrOfFunction(FD);
2316 assert(F &&
"Could not find function!");
2326 if (emission.IsEscapingByRef &&
2350 llvm_unreachable(
"Unknown DestructionKind");
2357 assert(dtorKind &&
"cannot push destructor for trivial type");
2367 assert(dtorKind &&
"cannot push destructor for trivial type");
2383 bool useEHCleanupForArray) {
2385 useEHCleanupForArray);
2392 assert(dtorKind &&
"cannot push destructor for trivial type");
2401 bool useEHCleanupForArray) {
2402 llvm::Instruction *DominatingIP =
2404 pushDestroy(cleanupKind, addr,
type, destroyer, useEHCleanupForArray);
2406 {
EHStack.stable_begin(), DominatingIP});
2410 EHStack.pushCleanup<CallStackRestore>(
2415 CleanupKind Kind, std::pair<llvm::Value *, llvm::Value *> AddrSizePair) {
2416 EHStack.pushCleanup<KmpcAllocFree>(Kind, AddrSizePair);
2422 bool useEHCleanupForArray) {
2432 useEHCleanupForArray);
2438 useEHCleanupForArray);
2443 using ConditionalCleanupType =
2454 cleanupKind, SavedAddr,
type, destroyer, useEHCleanupForArray);
2458 cleanup.AddAuxAllocas(std::move(DeactivationAllocas).Take());
2467 cleanupKind, ActiveFlagForLifetimeExt, SavedAddr,
type, destroyer,
2468 useEHCleanupForArray);
2484 bool useEHCleanupForArray) {
2487 return destroyer(*
this, addr,
type);
2496 bool checkZeroLength =
true;
2499 if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(
length)) {
2501 if (constLength->isZero())
return;
2502 checkZeroLength =
false;
2509 checkZeroLength, useEHCleanupForArray);
2527 bool checkZeroLength,
2528 bool useEHCleanup) {
2536 if (checkZeroLength) {
2537 llvm::Value *isEmpty =
Builder.CreateICmpEQ(begin, end,
2538 "arraydestroy.isempty");
2539 Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
2543 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2545 llvm::PHINode *elementPast =
2546 Builder.CreatePHI(begin->getType(), 2,
"arraydestroy.elementPast");
2547 elementPast->addIncoming(end, entryBB);
2550 llvm::Value *negativeOne = llvm::ConstantInt::get(
SizeTy, -1,
true);
2552 llvm::Value *element =
Builder.CreateInBoundsGEP(
2553 llvmElementType, elementPast, negativeOne,
"arraydestroy.element");
2560 destroyer(*
this,
Address(element, llvmElementType, elementAlign),
2567 llvm::Value *done =
Builder.CreateICmpEQ(element, begin,
"arraydestroy.done");
2568 Builder.CreateCondBr(done, doneBB, bodyBB);
2569 elementPast->addIncoming(element,
Builder.GetInsertBlock());
2578 llvm::Value *begin, llvm::Value *end,
2584 unsigned arrayDepth = 0;
2593 llvm::Value *zero = llvm::ConstantInt::get(CGF.
SizeTy, 0);
2597 elemTy, begin, gepIndices,
"pad.arraybegin");
2599 elemTy, end, gepIndices,
"pad.arrayend");
2613 class RegularPartialArrayDestroy final :
public EHScopeStack::Cleanup {
2614 llvm::Value *ArrayBegin;
2615 llvm::Value *ArrayEnd;
2616 QualType ElementType;
2618 CharUnits ElementAlign;
2620 RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
2621 QualType elementType, CharUnits elementAlign,
2623 : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
2624 ElementType(elementType), Destroyer(destroyer),
2625 ElementAlign(elementAlign) {}
2627 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2629 ElementType, ElementAlign, Destroyer);
2636 class IrregularPartialArrayDestroy final :
public EHScopeStack::Cleanup {
2637 llvm::Value *ArrayBegin;
2639 QualType ElementType;
2641 CharUnits ElementAlign;
2643 IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
2644 Address arrayEndPointer,
2645 QualType elementType,
2646 CharUnits elementAlign,
2648 : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
2649 ElementType(elementType), Destroyer(destroyer),
2650 ElementAlign(elementAlign) {}
2652 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2655 ElementType, ElementAlign, Destroyer);
2673 elementAlign, destroyer);
2683 llvm::Value *arrayEnd,
2688 arrayBegin, arrayEnd,
2689 elementType, elementAlign,
2695 if (LifetimeStartFn)
2696 return LifetimeStartFn;
2697 LifetimeStartFn = llvm::Intrinsic::getOrInsertDeclaration(
2699 return LifetimeStartFn;
2705 return LifetimeEndFn;
2706 LifetimeEndFn = llvm::Intrinsic::getOrInsertDeclaration(
2708 return LifetimeEndFn;
2715 FakeUseFn = llvm::Intrinsic::getOrInsertDeclaration(
2716 &
getModule(), llvm::Intrinsic::fake_use);
2725 struct ConsumeARCParameter final : EHScopeStack::Cleanup {
2726 ConsumeARCParameter(llvm::Value *param,
2728 : Param(param), Precise(precise) {}
2743 bool NoDebugInfo =
false;
2746 "Invalid argument to EmitParmDecl");
2755 "parameter has non-default address space in non-OpenCL mode");
2758 if (
auto IPD = dyn_cast<ImplicitParamDecl>(&D)) {
2776 bool DoStore =
false;
2778 bool UseIndirectDebugAddress =
false;
2792 if (UseIndirectDebugAddress) {
2795 PtrTy,
getContext().getTypeAlignInChars(PtrTy),
2796 D.
getName() +
".indirect_addr");
2817 "unexpected destructor type");
2827 ?
CGM.getOpenMPRuntime().getAddressOfLocalVariable(*
this, &D)
2830 DeclPtr = OpenMPLocalAddr;
2831 AllocaPtr = DeclPtr;
2835 D.
getName() +
".addr", &AllocaPtr);
2840 llvm::Value *ArgVal = (DoStore ? Arg.
getDirectValue() :
nullptr);
2852 bool isConsumed = D.
hasAttr<NSConsumedAttr>();
2857 "pseudo-strong variable isn't strong?");
2858 assert(qs.
hasConst() &&
"pseudo-strong variable should be const!");
2864 ArgVal =
Builder.CreateLoad(DeclPtr);
2868 if (
CGM.getCodeGenOpts().OptimizationLevel == 0) {
2907 setAddrOfLocalVar(&D, DeclPtr);
2912 if (
CGM.getCodeGenOpts().getExtendVariableLiveness() ==
2914 (
CGM.getCodeGenOpts().getExtendVariableLiveness() ==
2916 &D == CXXABIThisDecl)) {
2918 if (
auto *FnDecl = dyn_cast_or_null<FunctionDecl>(
CurCodeDecl);
2919 &D == CXXABIThisDecl || !FnDecl || !FnDecl->
getBody() ||
2920 FnDecl->getBody()->
getStmtClass() != Stmt::CoroutineBodyStmtClass) {
2930 llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable(
2932 if (
const auto *Var = dyn_cast_or_null<ParmVarDecl>(&D))
2933 DI->getParamDbgMappings().insert({Var, DILocalVar});
2937 if (D.
hasAttr<AnnotateAttr>())
2943 if (requiresReturnValueNullabilityCheck()) {
2947 RetValNullabilityPrecondition =
2948 Builder.CreateAnd(RetValNullabilityPrecondition,
2956 if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->
isUsed()))
2963 if (!LangOpts.OpenMP || LangOpts.OpenMPSimd ||
2964 (!LangOpts.EmitAllDecls && !D->
isUsed()))
2989 if (!VD->hasGlobalStorage())
3008 if (Entry->getType()->getAddressSpace() == TargetAS)
3011 llvm::PointerType *PTy = llvm::PointerType::get(
getLLVMContext(), TargetAS);
3016 llvm::GlobalVariable *DummyGV =
new llvm::GlobalVariable(
3017 getModule(), Entry->getValueType(),
false,
3018 llvm::GlobalValue::CommonLinkage,
nullptr,
"dummy",
nullptr,
3019 llvm::GlobalVariable::NotThreadLocal, Entry->getAddressSpace());
3020 Entry->replaceAllUsesWith(DummyGV);
3022 Entry->mutateType(PTy);
3023 llvm::Constant *NewPtrForOldDecl =
3024 llvm::ConstantExpr::getAddrSpaceCast(Entry, DummyGV->getType());
3028 DummyGV->replaceAllUsesWith(NewPtrForOldDecl);
3029 DummyGV->eraseFromParent();
3033std::optional<CharUnits>
3035 if (
const auto *AA = VD->
getAttr<OMPAllocateDeclAttr>()) {
3036 if (
Expr *Alignment = AA->getAlignment()) {
3037 unsigned UserAlign =
3038 Alignment->EvaluateKnownConstInt(
getContext()).getExtValue();
3046 std::max<unsigned>(UserAlign, NaturalAlign.
getQuantity()));
3049 return std::nullopt;
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.
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 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 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 shouldExtendLifetime(const ASTContext &Context, const Decl *FuncDecl, const VarDecl &D, ImplicitParamDecl *CXXABIThisDecl)
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 uint64_t maxFakeUseAggregateSize(const ASTContext &C)
Return the maximum size of an aggregate for which we generate a fake use intrinsic when -fextend-vari...
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 drillIntoBlockVariable(CodeGenFunction &CGF, LValue &lvalue, const VarDecl *var)
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.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
static const NamedDecl * getDefinition(const Decl *D)
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
DiagnosticsEngine & getDiagnostics() const
unsigned getTargetAddressSpace(LangAS AS) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Attr - This represents one attribute.
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.
This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits 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
Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
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 * getBasePointer() const
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.
unsigned getAddressSpace() const
Return the address space that this address resides in.
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.
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.
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 * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
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)
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)
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.
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...
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
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)
llvm::SmallVector< BypassingForwardJump, 4 > BypassingForwardJumps
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.
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.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
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.
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 ...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
bool currentFunctionUsesSEHTry() const
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)
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)
void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind, Address addr, QualType type)
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.
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,...
void EmitLifetimeEnd(llvm::Value *Addr)
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
llvm::SmallDenseMap< const VarDecl *, Address, 4 > BypassedVarInits
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.
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)
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.
void emitBypassedVarInitsForSource(const Stmt *Source)
Re-emit trivial-auto-var-init stores for variables bypassed by the jump Source.
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)
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
llvm::Instruction * getPostAllocaInsertPoint()
Return PostAllocaInsertPt.
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.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
llvm::GlobalVariable * AddInitializerToStaticVarDecl(const VarDecl &D, llvm::GlobalVariable *GV)
AddInitializerToStaticVarDecl - Add the initializer for 'D' to the global variable that has already b...
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.
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.
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)
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
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...
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
llvm::Constant * performAddrSpaceCast(llvm::Constant *Src, llvm::Type *DestTy)
void setStaticLocalDeclAddress(const VarDecl *D, llvm::Constant *C)
llvm::Function * getLLVMLifetimeStartFn()
Lazily declare the @llvm.lifetime.start intrinsic.
Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant, CharUnits Align)
void EmitOpenACCDeclare(const OpenACCDeclareDecl *D, CodeGenFunction *CGF=nullptr)
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.
void EmitOMPAllocateDecl(const OMPAllocateDecl *D)
Emit a code for the allocate directive.
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)
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.
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...
void EmitOpenACCRoutine(const OpenACCRoutineDecl *D, CodeGenFunction *CGF=nullptr)
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()
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.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
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()
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
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.
A pointer to member type per C++ 8.3.3 - Pointers to members.
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.
StmtClass getStmtClass() const
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....
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
RecordDecl * castAsRecordDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
NullabilityKindOrNone 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.
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
@ 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