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:
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:
140 case Decl::ImplicitConceptSpecialization:
141 case Decl::LifetimeExtendedTemporary:
142 case Decl::RequiresExprBody:
146 case Decl::NamespaceAlias:
154 case Decl::UsingEnum:
158 case Decl::UsingPack:
160 EmitDecl(*Using, EvaluateConditionDecl);
162 case Decl::UsingDirective:
167 case Decl::Decomposition: {
170 "Should not see file-scope variables inside a function!");
172 if (EvaluateConditionDecl)
178 case Decl::OMPDeclareReduction:
181 case Decl::OMPDeclareMapper:
184 case Decl::OpenACCDeclare:
186 case Decl::OpenACCRoutine:
190 case Decl::TypeAlias: {
193 DI->EmitAndRetainType(Ty);
216 llvm::GlobalValue::LinkageTypes
Linkage =
217 CGM.getLLVMLinkageVarDefinition(&D);
227 return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*
this, D);
239 std::string ContextName;
241 if (
auto *CD = dyn_cast<CapturedDecl>(DC))
243 if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
245 else if (
const auto *BD = dyn_cast<BlockDecl>(DC))
247 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(DC))
248 ContextName = OMD->getSelector().getAsString();
250 llvm_unreachable(
"Unknown context for static var decl");
262 if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&D])
281 llvm::Constant *
Init =
nullptr;
283 D.
hasAttr<CUDASharedAttr>() || D.
hasAttr<LoaderUninitializedAttr>())
284 Init = llvm::UndefValue::get(LTy);
288 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
290 nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
291 GV->setAlignment(
getContext().getDeclAlign(&D).getAsAlign());
294 GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
304 llvm::Constant *
Addr = GV;
305 if (AS != ExpectedAS) {
309 getContext().getTargetAddressSpace(ExpectedAS)));
328 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
330 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
332 else if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
352llvm::GlobalVariable *
354 llvm::GlobalVariable *GV) {
362 CGM.ErrorUnsupported(D.
getInit(),
"constant l-value expression");
364 CGM.ErrorUnsupported(D.
getInit(),
"flexible array initializer");
368 GV->setConstant(
false);
375 PGO->markStmtMaybeUsed(D.
getInit());
381 CGM.getDataLayout().getTypeAllocSize(
Init->getType()));
382 assert(VarSize == CstSize &&
"Emitted constant has unexpected size");
390 GV->replaceInitializer(
Init);
405 llvm::GlobalValue::LinkageTypes
Linkage) {
409 llvm::Constant *addr =
CGM.getOrCreateStaticVarDecl(D,
Linkage);
415 setAddrOfLocalVar(&D,
Address(addr, elemTy, alignment));
424 llvm::Type *expectedType = addr->getType();
426 llvm::GlobalVariable *var =
436 if (D.
getInit() && !isCudaSharedVar) {
444 CGM.AddGlobalAnnotations(&D, var);
446 if (
auto *SA = D.
getAttr<PragmaClangBSSSectionAttr>())
447 var->addAttribute(
"bss-section", SA->getName());
448 if (
auto *SA = D.
getAttr<PragmaClangDataSectionAttr>())
449 var->addAttribute(
"data-section", SA->getName());
450 if (
auto *SA = D.
getAttr<PragmaClangRodataSectionAttr>())
451 var->addAttribute(
"rodata-section", SA->getName());
452 if (
auto *SA = D.
getAttr<PragmaClangRelroSectionAttr>())
453 var->addAttribute(
"relro-section", SA->getName());
455 if (
const SectionAttr *SA = D.
getAttr<SectionAttr>())
456 var->setSection(SA->getName());
459 CGM.addUsedGlobal(var);
460 else if (D.
hasAttr<UsedAttr>())
461 CGM.addUsedOrCompilerUsedGlobal(var);
463 if (
CGM.getCodeGenOpts().KeepPersistentStorageVariables)
464 CGM.addUsedOrCompilerUsedGlobal(var);
471 llvm::Constant *castedAddr =
472 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
473 LocalDeclMap.find(&D)->second =
Address(castedAddr, elemTy, alignment);
474 CGM.setStaticLocalDeclAddress(&D, castedAddr);
476 CGM.getSanitizerMetadata()->reportGlobal(var, D);
480 if (DI &&
CGM.getCodeGenOpts().hasReducedDebugInfo()) {
487 struct DestroyObject final : EHScopeStack::Cleanup {
490 bool useEHCleanupForArray)
491 : addr(addr),
type(
type), destroyer(destroyer),
492 useEHCleanupForArray(useEHCleanupForArray) {}
497 bool useEHCleanupForArray;
501 bool useEHCleanupForArray =
502 flags.isForNormalCleanup() && this->useEHCleanupForArray;
508 template <
class Derived>
509 struct DestroyNRVOVariable : EHScopeStack::Cleanup {
510 DestroyNRVOVariable(Address addr, QualType
type, llvm::Value *NRVOFlag)
511 : NRVOFlag(NRVOFlag), Loc(addr), Ty(
type) {}
513 llvm::Value *NRVOFlag;
517 void Emit(CodeGenFunction &CGF, Flags flags)
override {
519 bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
521 llvm::BasicBlock *SkipDtorBB =
nullptr;
526 llvm::Value *DidNRVO =
528 CGF.
Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
532 static_cast<Derived *
>(
this)->emitDestructorCall(CGF);
537 virtual ~DestroyNRVOVariable() =
default;
540 struct DestroyNRVOVariableCXX final
541 : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
542 DestroyNRVOVariableCXX(Address addr, QualType
type,
543 const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag)
544 : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr,
type, NRVOFlag),
547 const CXXDestructorDecl *Dtor;
549 void emitDestructorCall(CodeGenFunction &CGF) {
556 struct DestroyNRVOVariableC final
557 : DestroyNRVOVariable<DestroyNRVOVariableC> {
558 DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)
559 : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
561 void emitDestructorCall(CodeGenFunction &CGF) {
566 struct CallStackRestore final : EHScopeStack::Cleanup {
568 CallStackRestore(Address Stack) : Stack(Stack) {}
569 bool isRedundantBeforeReturn()
override {
return true; }
570 void Emit(CodeGenFunction &CGF, Flags flags)
override {
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 {
586 struct ExtendGCLifetime final : EHScopeStack::Cleanup {
588 ExtendGCLifetime(
const VarDecl *var) : Var(*
var) {}
590 void Emit(CodeGenFunction &CGF, Flags flags)
override {
593 DeclRefExpr DRE(CGF.
getContext(),
const_cast<VarDecl *
>(&Var),
false,
594 Var.getType(),
VK_LValue, SourceLocation());
601 struct CallCleanupFunction final : EHScopeStack::Cleanup {
602 llvm::Constant *CleanupFn;
603 const CGFunctionInfo &FnInfo;
605 const CleanupAttr *Attribute;
607 CallCleanupFunction(llvm::Constant *CleanupFn,
const CGFunctionInfo *Info,
608 const VarDecl *Var,
const CleanupAttr *Attr)
609 : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var), Attribute(Attr) {}
611 void Emit(CodeGenFunction &CGF, Flags flags)
override {
612 DeclRefExpr DRE(CGF.
getContext(),
const_cast<VarDecl *
>(&Var),
false,
631 GlobalDecl GD = GlobalDecl(Attribute->getFunctionDecl());
633 CGF.
EmitCall(FnInfo, Callee, ReturnValueSlot(), Args,
635 Attribute->getLoc());
647 llvm_unreachable(
"present but none");
655 (var.hasAttr<ObjCPreciseLifetimeAttr>()
660 CGF.
pushDestroy(cleanupKind, addr, var.getType(), destroyer,
679 if (
const Expr *e = dyn_cast<Expr>(
s)) {
682 s = e = e->IgnoreParenCasts();
684 if (
const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e))
685 return (ref->getDecl() == &var);
686 if (
const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
687 const BlockDecl *block = be->getBlockDecl();
688 for (
const auto &I : block->
captures()) {
689 if (I.getVariable() == &var)
695 for (
const Stmt *SubStmt :
s->children())
704 if (!
decl)
return false;
711 const LValue &destLV,
const Expr *init) {
712 bool needsCast =
false;
719 case CK_BlockPointerToObjCPointerCast:
725 case CK_LValueToRValue: {
734 auto srcAddr = srcLV.getAddress();
736 srcAddr = srcAddr.withElementType(destLV.getAddress().getElementType());
767 if (!
SanOpts.has(SanitizerKind::NullabilityAssign))
776 auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign;
777 auto CheckHandler = SanitizerHandler::TypeMismatch;
780 llvm::Constant *StaticData[] = {
782 llvm::ConstantInt::get(
Int8Ty, 0),
788 LValue lvalue,
bool capturedByInit) {
806 init = DIE->getExpr();
810 if (
auto *EWC = dyn_cast<ExprWithCleanups>(init)) {
812 return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit);
819 bool accessedByInit =
false;
821 accessedByInit = (capturedByInit ||
isAccessedBy(D, init));
822 if (accessedByInit) {
825 if (capturedByInit) {
834 llvm::Value *zero =
CGM.getNullPointer(ty, tempLV.
getType());
846 llvm::Value *value =
nullptr;
850 llvm_unreachable(
"present but none");
912 unsigned &NumStores) {
921 return Init->isNullValue() || NumStores--;
925 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
933 if (llvm::ConstantDataSequential *CDS =
934 dyn_cast<llvm::ConstantDataSequential>(
Init)) {
935 for (
unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
936 llvm::Constant *Elt = CDS->getElementAsConstant(i);
949void CodeGenFunction::emitStoresForInitAfterBZero(llvm::Constant *
Init,
953 "called emitStoresForInitAfterBZero for zero or undef value.");
958 auto *I =
Builder.CreateStore(
Init, Loc, isVolatile);
961 I->addAnnotationMetadata(
"auto-init");
965 if (llvm::ConstantDataSequential *CDS =
966 dyn_cast<llvm::ConstantDataSequential>(
Init)) {
967 for (
unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
968 llvm::Constant *Elt = CDS->getElementAsConstant(i);
972 emitStoresForInitAfterBZero(
973 Elt,
Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,
980 "Unknown value type!");
982 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
987 emitStoresForInitAfterBZero(Elt,
988 Builder.CreateConstInBoundsGEP2_32(Loc, 0, i),
989 isVolatile, IsAutoInit);
997 uint64_t GlobalSize) {
1005 unsigned StoreBudget = 6;
1006 uint64_t SizeLimit = 32;
1008 return GlobalSize > SizeLimit &&
1018 uint64_t GlobalSize,
1019 const llvm::DataLayout &DL) {
1020 uint64_t SizeLimit = 32;
1021 if (GlobalSize <= SizeLimit)
1023 return llvm::isBytewiseValue(
Init, DL);
1030 uint64_t GlobalByteSize) {
1032 uint64_t ByteSizeLimit = 64;
1035 if (GlobalByteSize <= ByteSizeLimit)
1048 return llvm::Constant::getNullValue(Ty);
1052 llvm::Constant *constant);
1057 llvm::StructType *STy,
1058 llvm::Constant *constant) {
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);
1072 llvm::Constant *CurOp;
1073 if (constant->isZeroValue())
1074 CurOp = llvm::Constant::getNullValue(STy->getElementType(i));
1079 NestedIntact =
false;
1080 Values.push_back(NewOp);
1081 SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType());
1083 unsigned TotalSize = Layout->getSizeInBytes();
1084 if (SizeSoFar < TotalSize) {
1085 auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar);
1088 if (NestedIntact && Values.size() == STy->getNumElements())
1090 return llvm::ConstantStruct::getAnon(Values, STy->isPacked());
1096 llvm::Constant *constant) {
1097 llvm::Type *OrigTy = constant->getType();
1098 if (
const auto STy = dyn_cast<llvm::StructType>(OrigTy))
1100 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(OrigTy)) {
1102 uint64_t Size = ArrayTy->getNumElements();
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);
1112 for (
unsigned Op = 0; Op != Size; ++Op) {
1113 if (!ZeroInitializer) {
1114 OpValue = constant->getAggregateElement(Op);
1117 Values.push_back(PaddedOp);
1119 auto *NewElemTy = Values[0]->getType();
1120 if (NewElemTy == ElemTy)
1122 auto *NewArrayTy = llvm::ArrayType::get(NewElemTy, Size);
1123 return llvm::ConstantArray::get(NewArrayTy, Values);
1132 llvm::Constant *Constant,
1134 auto FunctionName = [&](
const DeclContext *DC) -> std::string {
1135 if (
const auto *FD = dyn_cast<FunctionDecl>(DC)) {
1136 if (
const auto *CC = dyn_cast<CXXConstructorDecl>(FD))
1137 return CC->getNameAsString();
1138 if (
const auto *CD = dyn_cast<CXXDestructorDecl>(FD))
1139 return CD->getNameAsString();
1141 }
else if (
const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) {
1142 return OM->getNameAsString();
1146 return "<captured>";
1148 llvm_unreachable(
"expected a function or method");
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;
1165 Name = (
"__const." + FunctionName(DC) +
"." + D.
getName()).str();
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);
1172 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1174 }
else if (CacheEntry->getAlignment() < uint64_t(Align.
getQuantity())) {
1175 CacheEntry->setAlignment(Align.
getAsAlign());
1178 return Address(CacheEntry, CacheEntry->getValueType(), Align);
1184 llvm::Constant *Constant,
1190void CodeGenFunction::emitStoresForConstant(
const VarDecl &D,
Address Loc,
1192 llvm::Constant *constant,
1194 auto *Ty = constant->getType();
1195 uint64_t ConstantSize =
CGM.getDataLayout().getTypeAllocSize(Ty);
1199 bool canDoSingleStore = Ty->isIntOrIntVectorTy() ||
1200 Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy();
1201 if (canDoSingleStore) {
1202 auto *I =
Builder.CreateStore(constant, Loc, isVolatile);
1205 I->addAnnotationMetadata(
"auto-init");
1209 auto *SizeVal = llvm::ConstantInt::get(
CGM.IntPtrTy, ConstantSize);
1214 auto *I =
Builder.CreateMemSet(Loc, llvm::ConstantInt::get(
CGM.Int8Ty, 0),
1215 SizeVal, isVolatile);
1219 I->addAnnotationMetadata(
"auto-init");
1221 bool valueAlreadyCorrect =
1223 if (!valueAlreadyCorrect) {
1225 emitStoresForInitAfterBZero(constant, Loc, isVolatile, IsAutoInit);
1231 llvm::Value *Pattern =
1237 assert(AP.getBitWidth() <= 8);
1238 Value = AP.getLimitedValue();
1240 auto *I =
Builder.CreateMemSet(
1241 Loc, llvm::ConstantInt::get(
CGM.Int8Ty,
Value), SizeVal, isVolatile);
1244 I->addAnnotationMetadata(
"auto-init");
1250 bool IsTrivialAutoVarInitPattern =
1251 CGM.getContext().getLangOpts().getTrivialAutoVarInit() ==
1254 if (
auto *STy = dyn_cast<llvm::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++) {
1261 Address EltPtr =
Builder.CreateConstInBoundsByteGEP(
1263 emitStoresForConstant(D, EltPtr, isVolatile,
1264 constant->getAggregateElement(i), IsAutoInit);
1268 }
else if (
auto *ATy = dyn_cast<llvm::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);
1286 SizeVal, isVolatile);
1290 I->addAnnotationMetadata(
"auto-init");
1293void CodeGenFunction::emitStoresForZeroInit(
const VarDecl &D,
Address Loc,
1296 llvm::Constant *constant =
1298 emitStoresForConstant(D, Loc, isVolatile, constant,
1302void CodeGenFunction::emitStoresForPatternInit(
const VarDecl &D,
Address Loc,
1308 emitStoresForConstant(D, Loc, isVolatile, constant,
1313 auto *Ty = constant->getType();
1316 if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())
1317 for (llvm::Use &Op : constant->operands())
1324 llvm::Constant *constant) {
1325 auto *Ty = constant->getType();
1328 if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
1333 for (
unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
1337 if (Ty->isStructTy())
1339 if (Ty->isArrayTy())
1341 assert(Ty->isVectorTy());
1342 return llvm::ConstantVector::get(Values);
1357 if (!ShouldEmitLifetimeMarkers)
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();
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.getLLVMLifetimeEndFn(), {Addr});
1376 C->setDoesNotThrow();
1382 llvm::CallInst *
C =
Builder.CreateCall(
CGM.getLLVMFakeUseFn(), {V});
1383 C->setDoesNotThrow();
1384 C->setTailCallKind(llvm::CallInst::TCK_NoTail);
1396 while (
getContext().getAsVariableArrayType(Type1D)) {
1398 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1402 Twine Name = Twine(
"__vla_expr") + Twine(VLAExprCounter++);
1404 StringRef NameRef = Name.toStringRef(Buffer);
1406 VLAExprNames.push_back(&Ident);
1409 Builder.CreateStore(VlaSize.NumElts, SizeExprAddr);
1410 Dimensions.emplace_back(SizeExprAddr.getPointer(),
1413 Type1D = VlaSize.Type;
1422 unsigned NameIdx = 0;
1423 for (
auto &VlaSize : Dimensions) {
1425 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1426 MD = llvm::ConstantAsMetadata::get(
C);
1431 SizeTy->getScalarSizeInBits(),
false);
1436 ArtificialDecl->setImplicit();
1441 assert(MD &&
"No Size expression debug node created");
1449 return 4 *
C.getTypeSize(
C.UnsignedIntTy);
1474 if (FuncDecl->
hasAttr<NoDebugAttr>() || FuncDecl->
hasAttr<OptimizeNoneAttr>())
1491 emission.IsEscapingByRef = isEscapingByRef;
1500 bool EmitDebugInfo = DI &&
CGM.getCodeGenOpts().hasReducedDebugInfo();
1505 if (
CGM.getLangOpts().OpenMPIRBuilder)
1510 ?
CGM.getOpenMPRuntime().getAddressOfLocalVariable(*
this, &D)
1516 address = OpenMPLocalAddr;
1517 AllocaAddr = OpenMPLocalAddr;
1530 getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) &&
1542 (
CGM.getCodeGenOpts().MergeAllConstants && !NRVO &&
1549 assert(emission.wasEmittedAsGlobal());
1554 emission.IsConstantAggregate =
true;
1568 address = MaybeCastStackAddressSpace(AllocaAddr, Ty.
getAddressSpace());
1571 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1572 (CXXRD && !CXXRD->hasTrivialDestructor()) ||
1573 RD->isNonTrivialToPrimitiveDestroy()) {
1590 llvm::Type *allocaTy;
1591 if (isEscapingByRef) {
1593 allocaTy = byrefInfo.Type;
1594 allocaAlignment = byrefInfo.ByrefAlignment;
1597 allocaAlignment = alignment;
1605 nullptr, &AllocaAddr);
1610 bool IsMSCatchParam =
1631 emission.UseLifetimeMarkers =
1646 bool VarAllocated =
false;
1648 auto &RT =
CGM.getOpenMPRuntime();
1649 if (RT.isDelayedVariableLengthDecl(*
this, &D)) {
1651 std::pair<llvm::Value *, llvm::Value *> AddrSizePair =
1652 RT.getKmpcAllocShared(*
this, &D);
1656 CGM.getContext().getDeclAlign(&D),
1658 address =
Base.getAddress();
1666 VarAllocated =
true;
1670 if (!VarAllocated) {
1671 if (!DidCallStackSave) {
1676 llvm::Value *
V =
Builder.CreateStackSave();
1680 DidCallStackSave =
true;
1701 setAddrOfLocalVar(&D, address);
1702 emission.Addr = address;
1703 emission.AllocaAddr = AllocaAddr;
1712 if (UsePointerValue) {
1733 if (
CGM.getCodeGenOpts().getExtendVariableLiveness() ==
1748 if (
const Expr *E = dyn_cast<Expr>(S))
1763 if (
const BlockExpr *BE = dyn_cast<BlockExpr>(E)) {
1765 for (
const auto &I :
Block->captures()) {
1766 if (I.getVariable() == &Var)
1774 if (
const StmtExpr *SE = dyn_cast<StmtExpr>(E)) {
1776 for (
const auto *BI : CS->
body())
1777 if (
const auto *BIE = dyn_cast<Expr>(BI)) {
1781 else if (
const auto *DS = dyn_cast<DeclStmt>(BI)) {
1783 for (
const auto *I : DS->decls()) {
1784 if (
const auto *VD = dyn_cast<VarDecl>((I))) {
1815 !Construct->requiresZeroInitialization())
1821void CodeGenFunction::emitZeroOrPatternForAutoVarInit(
QualType type,
1825 auto trivialAutoVarInitMaxSize =
1828 bool isVolatile =
type.isVolatileQualified();
1829 if (!Size.isZero()) {
1836 switch (trivialAutoVarInit) {
1838 llvm_unreachable(
"Uninitialized handled by caller");
1842 if (trivialAutoVarInitMaxSize > 0 &&
1843 allocSize > trivialAutoVarInitMaxSize)
1845 emitStoresForZeroInit(D, Loc, isVolatile);
1850 if (trivialAutoVarInitMaxSize > 0 &&
1851 allocSize > trivialAutoVarInitMaxSize)
1853 emitStoresForPatternInit(D, Loc, isVolatile);
1868 auto SizeVal = VlaSize.NumElts;
1870 switch (trivialAutoVarInit) {
1872 llvm_unreachable(
"Uninitialized handled by caller");
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");
1886 if (
CGM.stopAutoInit())
1895 llvm::Value *IsZeroSizedVLA =
Builder.CreateICmpEQ(
1896 SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0),
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");
1917 BaseSizeInChars, isVolatile);
1918 I->addAnnotationMetadata(
"auto-init");
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);
1930 assert(emission.Variable &&
"emission was not valid!");
1933 if (emission.wasEmittedAsGlobal())
return;
1935 const VarDecl &D = *emission.Variable;
1947 PGO->markStmtMaybeUsed(
Init);
1954 if (emission.IsEscapingByRef)
1961 type.isNonTrivialToPrimitiveDefaultInitialize() ==
1964 if (emission.IsEscapingByRef)
1973 bool capturedByInit =
1976 bool locIsByrefHeader = !capturedByInit;
1980 auto hasNoTrivialAutoVarInitAttr = [&](
const Decl *D) {
1981 return D && D->
hasAttr<NoTrivialAutoVarInitAttr>();
1986 hasNoTrivialAutoVarInitAttr(
type->getAsTagDecl()) ||
1991 auto initializeWhatIsTechnicallyUninitialized = [&](
Address Loc) {
1992 if (trivialAutoVarInit ==
1997 if (emission.IsEscapingByRef && !locIsByrefHeader)
2000 return emitZeroOrPatternForAutoVarInit(
type, D, Loc);
2004 return initializeWhatIsTechnicallyUninitialized(Loc);
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 !=
2028 if (constant &&
type->isBitIntType() &&
2029 CGM.getTypes().typeRequiresSplitIntoByteArray(
type)) {
2033 llvm::Type *LoadType =
2034 CGM.getTypes().convertTypeForLoadStore(
type, constant->getType());
2035 constant = llvm::ConstantFoldLoadFromConst(
2036 constant, LoadType, llvm::APInt::getZero(32),
CGM.getDataLayout());
2041 if (trivialAutoVarInit !=
2052 initializeWhatIsTechnicallyUninitialized(Loc);
2060 PGO->markStmtMaybeUsed(
Init);
2062 if (!emission.IsConstantAggregate) {
2070 type.isVolatileQualified(), constant,
2075 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
2076 for (
auto *B : DD->flat_bindings())
2077 if (
auto *HD = B->getHoldingVar())
2093 LValue lvalue,
bool capturedByInit) {
2096 if (
type->isReferenceType()) {
2115 if (
type->isAtomicType()) {
2121 else if (
auto *FD = dyn_cast<FieldDecl>(D))
2131 llvm_unreachable(
"bad evaluation kind");
2144 const VarDecl *var = emission.Variable;
2152 llvm_unreachable(
"no cleanup for trivially-destructible variable");
2157 if (emission.NRVOFlag) {
2158 assert(!
type->isArrayType());
2160 EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr,
type, dtor,
2168 if (var->isARCPseudoStrong())
return;
2174 if (!var->hasAttr<ObjCPreciseLifetimeAttr>())
2183 if (emission.NRVOFlag) {
2184 assert(!
type->isArrayType());
2185 EHStack.pushCleanup<DestroyNRVOVariableC>(cleanupKind, addr,
2186 emission.NRVOFlag,
type);
2197 bool useEHCleanup = (cleanupKind &
EHCleanup);
2198 EHStack.pushCleanup<DestroyObject>(cleanupKind, addr,
type, destroyer,
2203 assert(emission.Variable &&
"emission was not valid!");
2206 if (emission.wasEmittedAsGlobal())
return;
2212 const VarDecl &D = *emission.Variable;
2220 D.
hasAttr<ObjCPreciseLifetimeAttr>()) {
2225 if (
const CleanupAttr *CA = D.
getAttr<CleanupAttr>()) {
2228 llvm::Constant *F =
CGM.GetAddrOfFunction(FD);
2229 assert(F &&
"Could not find function!");
2239 if (emission.IsEscapingByRef &&
2263 llvm_unreachable(
"Unknown DestructionKind");
2270 assert(dtorKind &&
"cannot push destructor for trivial type");
2280 assert(dtorKind &&
"cannot push destructor for trivial type");
2296 bool useEHCleanupForArray) {
2298 useEHCleanupForArray);
2305 assert(dtorKind &&
"cannot push destructor for trivial type");
2314 bool useEHCleanupForArray) {
2315 llvm::Instruction *DominatingIP =
2317 pushDestroy(cleanupKind, addr,
type, destroyer, useEHCleanupForArray);
2319 {
EHStack.stable_begin(), DominatingIP});
2323 EHStack.pushCleanup<CallStackRestore>(Kind, SPMem);
2327 CleanupKind Kind, std::pair<llvm::Value *, llvm::Value *> AddrSizePair) {
2328 EHStack.pushCleanup<KmpcAllocFree>(Kind, AddrSizePair);
2334 bool useEHCleanupForArray) {
2344 useEHCleanupForArray);
2350 useEHCleanupForArray);
2355 using ConditionalCleanupType =
2366 cleanupKind, SavedAddr,
type, destroyer, useEHCleanupForArray);
2370 cleanup.AddAuxAllocas(std::move(DeactivationAllocas).Take());
2379 cleanupKind, ActiveFlagForLifetimeExt, SavedAddr,
type, destroyer,
2380 useEHCleanupForArray);
2396 bool useEHCleanupForArray) {
2399 return destroyer(*
this, addr,
type);
2408 bool checkZeroLength =
true;
2411 if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(
length)) {
2413 if (constLength->isZero())
return;
2414 checkZeroLength =
false;
2421 checkZeroLength, useEHCleanupForArray);
2439 bool checkZeroLength,
2440 bool useEHCleanup) {
2448 if (checkZeroLength) {
2449 llvm::Value *isEmpty =
Builder.CreateICmpEQ(begin, end,
2450 "arraydestroy.isempty");
2451 Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
2455 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2457 llvm::PHINode *elementPast =
2458 Builder.CreatePHI(begin->getType(), 2,
"arraydestroy.elementPast");
2459 elementPast->addIncoming(end, entryBB);
2462 llvm::Value *negativeOne = llvm::ConstantInt::get(
SizeTy, -1,
true);
2464 llvm::Value *element =
Builder.CreateInBoundsGEP(
2465 llvmElementType, elementPast, negativeOne,
"arraydestroy.element");
2472 destroyer(*
this,
Address(element, llvmElementType, elementAlign),
2479 llvm::Value *done =
Builder.CreateICmpEQ(element, begin,
"arraydestroy.done");
2480 Builder.CreateCondBr(done, doneBB, bodyBB);
2481 elementPast->addIncoming(element,
Builder.GetInsertBlock());
2490 llvm::Value *begin, llvm::Value *end,
2496 unsigned arrayDepth = 0;
2505 llvm::Value *zero = llvm::ConstantInt::get(CGF.
SizeTy, 0);
2509 elemTy, begin, gepIndices,
"pad.arraybegin");
2511 elemTy, end, gepIndices,
"pad.arrayend");
2525 class RegularPartialArrayDestroy final :
public EHScopeStack::Cleanup {
2526 llvm::Value *ArrayBegin;
2527 llvm::Value *ArrayEnd;
2528 QualType ElementType;
2530 CharUnits ElementAlign;
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) {}
2539 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2541 ElementType, ElementAlign, Destroyer);
2548 class IrregularPartialArrayDestroy final :
public EHScopeStack::Cleanup {
2549 llvm::Value *ArrayBegin;
2550 Address ArrayEndPointer;
2551 QualType ElementType;
2553 CharUnits ElementAlign;
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) {}
2564 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2567 ElementType, ElementAlign, Destroyer);
2585 elementAlign, destroyer);
2595 llvm::Value *arrayEnd,
2600 arrayBegin, arrayEnd,
2601 elementType, elementAlign,
2607 if (LifetimeStartFn)
2608 return LifetimeStartFn;
2609 LifetimeStartFn = llvm::Intrinsic::getOrInsertDeclaration(
2611 return LifetimeStartFn;
2617 return LifetimeEndFn;
2618 LifetimeEndFn = llvm::Intrinsic::getOrInsertDeclaration(
2620 return LifetimeEndFn;
2627 FakeUseFn = llvm::Intrinsic::getOrInsertDeclaration(
2628 &
getModule(), llvm::Intrinsic::fake_use);
2637 struct ConsumeARCParameter final : EHScopeStack::Cleanup {
2638 ConsumeARCParameter(llvm::Value *param,
2640 : Param(param), Precise(precise) {}
2655 bool NoDebugInfo =
false;
2658 "Invalid argument to EmitParmDecl");
2668 if (
auto IPD = dyn_cast<ImplicitParamDecl>(&D)) {
2686 bool DoStore =
false;
2688 bool UseIndirectDebugAddress =
false;
2696 auto AllocaAS =
CGM.getASTAllocaAddressSpace();
2705 if (UseIndirectDebugAddress) {
2708 D.
getName() +
".indirect_addr");
2715 if (SrcLangAS != DestLangAS) {
2716 assert(
getContext().getTargetAddressSpace(SrcLangAS) ==
2717 CGM.getDataLayout().getAllocaAddrSpace());
2734 "unexpected destructor type");
2744 ?
CGM.getOpenMPRuntime().getAddressOfLocalVariable(*
this, &D)
2747 DeclPtr = OpenMPLocalAddr;
2748 AllocaPtr = DeclPtr;
2752 D.
getName() +
".addr", &AllocaPtr);
2757 llvm::Value *ArgVal = (DoStore ? Arg.
getDirectValue() :
nullptr);
2767 bool isConsumed = D.
hasAttr<NSConsumedAttr>();
2772 "pseudo-strong variable isn't strong?");
2773 assert(qs.
hasConst() &&
"pseudo-strong variable should be const!");
2779 ArgVal =
Builder.CreateLoad(DeclPtr);
2783 if (
CGM.getCodeGenOpts().OptimizationLevel == 0) {
2787 llvm::Value *Null =
CGM.EmitNullConstant(D.
getType());
2822 setAddrOfLocalVar(&D, DeclPtr);
2827 if (
CGM.getCodeGenOpts().getExtendVariableLiveness() ==
2829 (
CGM.getCodeGenOpts().getExtendVariableLiveness() ==
2831 &D == CXXABIThisDecl)) {
2840 llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable(
2842 if (
const auto *Var = dyn_cast_or_null<ParmVarDecl>(&D))
2843 DI->getParamDbgMappings().insert({Var, DILocalVar});
2847 if (D.
hasAttr<AnnotateAttr>())
2853 if (requiresReturnValueNullabilityCheck()) {
2857 RetValNullabilityPrecondition =
2858 Builder.CreateAnd(RetValNullabilityPrecondition,
2866 if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->
isUsed()))
2873 if (!LangOpts.OpenMP || LangOpts.OpenMPSimd ||
2874 (!LangOpts.EmitAllDecls && !D->
isUsed()))
2899 if (!VD->hasGlobalStorage())
2918 if (Entry->getType()->getAddressSpace() == TargetAS)
2921 llvm::PointerType *PTy = llvm::PointerType::get(
getLLVMContext(), TargetAS);
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);
2932 Entry->mutateType(PTy);
2933 llvm::Constant *NewPtrForOldDecl =
2934 llvm::ConstantExpr::getAddrSpaceCast(Entry, DummyGV->getType());
2938 DummyGV->replaceAllUsesWith(NewPtrForOldDecl);
2939 DummyGV->eraseFromParent();
2943std::optional<CharUnits>
2945 if (
const auto *AA = VD->
getAttr<OMPAllocateDeclAttr>()) {
2946 if (
Expr *Alignment = AA->getAlignment()) {
2947 unsigned UserAlign =
2948 Alignment->EvaluateKnownConstInt(
getContext()).getExtValue();
2956 std::max<unsigned>(UserAlign, NaturalAlign.
getQuantity()));
2959 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.
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.
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 * 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< 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.
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,...
const TargetCodeGenInfo & getTargetHooks() const
void EmitLifetimeEnd(llvm::Value *Addr)
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 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.
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...
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
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()
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