35#include "llvm/Analysis/ValueTracking.h"
36#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/GlobalVariable.h"
38#include "llvm/IR/Intrinsics.h"
39#include "llvm/IR/Type.h"
43using namespace CodeGen;
46 "Clang max alignment greater than what LLVM supports?");
48void CodeGenFunction::EmitDecl(
const Decl &D) {
50 case Decl::BuiltinTemplate:
51 case Decl::TranslationUnit:
52 case Decl::ExternCContext:
54 case Decl::UnresolvedUsingTypename:
55 case Decl::ClassTemplateSpecialization:
56 case Decl::ClassTemplatePartialSpecialization:
57 case Decl::VarTemplateSpecialization:
58 case Decl::VarTemplatePartialSpecialization:
59 case Decl::TemplateTypeParm:
60 case Decl::UnresolvedUsingValue:
61 case Decl::NonTypeTemplateParm:
62 case Decl::CXXDeductionGuide:
64 case Decl::CXXConstructor:
65 case Decl::CXXDestructor:
66 case Decl::CXXConversion:
68 case Decl::MSProperty:
69 case Decl::IndirectField:
71 case Decl::ObjCAtDefsField:
73 case Decl::ImplicitParam:
74 case Decl::ClassTemplate:
75 case Decl::VarTemplate:
76 case Decl::FunctionTemplate:
77 case Decl::TypeAliasTemplate:
78 case Decl::TemplateTemplateParm:
79 case Decl::ObjCMethod:
80 case Decl::ObjCCategory:
81 case Decl::ObjCProtocol:
82 case Decl::ObjCInterface:
83 case Decl::ObjCCategoryImpl:
84 case Decl::ObjCImplementation:
85 case Decl::ObjCProperty:
86 case Decl::ObjCCompatibleAlias:
87 case Decl::PragmaComment:
88 case Decl::PragmaDetectMismatch:
89 case Decl::AccessSpec:
90 case Decl::LinkageSpec:
92 case Decl::ObjCPropertyImpl:
93 case Decl::FileScopeAsm:
94 case Decl::TopLevelStmt:
96 case Decl::FriendTemplate:
99 case Decl::UsingShadow:
100 case Decl::ConstructorUsingShadow:
101 case Decl::ObjCTypeParam:
103 case Decl::UnresolvedUsingIfExists:
104 case Decl::HLSLBuffer:
105 llvm_unreachable(
"Declaration should not be in declstmts!");
107 case Decl::CXXRecord:
115 DI->EmitAndRetainType(
getContext().getEnumType(cast<EnumDecl>(&D)));
118 case Decl::EnumConstant:
119 case Decl::StaticAssert:
123 case Decl::UnnamedGlobalConstant:
124 case Decl::TemplateParamObject:
125 case Decl::OMPThreadPrivate:
126 case Decl::OMPAllocate:
127 case Decl::OMPCapturedExpr:
128 case Decl::OMPRequires:
131 case Decl::ImplicitConceptSpecialization:
132 case Decl::LifetimeExtendedTemporary:
133 case Decl::RequiresExprBody:
137 case Decl::NamespaceAlias:
139 DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(D));
143 DI->EmitUsingDecl(cast<UsingDecl>(D));
145 case Decl::UsingEnum:
147 DI->EmitUsingEnumDecl(cast<UsingEnumDecl>(D));
149 case Decl::UsingPack:
150 for (
auto *Using : cast<UsingPackDecl>(D).expansions())
153 case Decl::UsingDirective:
155 DI->EmitUsingDirective(cast<UsingDirectiveDecl>(D));
158 case Decl::Decomposition: {
159 const VarDecl &VD = cast<VarDecl>(D);
161 "Should not see file-scope variables inside a function!");
163 if (
auto *DD = dyn_cast<DecompositionDecl>(&VD))
164 for (
auto *B : DD->bindings())
165 if (
auto *HD = B->getHoldingVar())
170 case Decl::OMPDeclareReduction:
173 case Decl::OMPDeclareMapper:
177 case Decl::TypeAlias: {
178 QualType Ty = cast<TypedefNameDecl>(D).getUnderlyingType();
180 DI->EmitAndRetainType(Ty);
203 llvm::GlobalValue::LinkageTypes
Linkage =
226 std::string ContextName;
228 if (
auto *CD = dyn_cast<CapturedDecl>(DC))
229 DC = cast<DeclContext>(CD->getNonClosureContext());
230 if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
232 else if (
const auto *BD = dyn_cast<BlockDecl>(DC))
234 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(DC))
235 ContextName = OMD->getSelector().getAsString();
237 llvm_unreachable(
"Unknown context for static var decl");
249 if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&D])
268 llvm::Constant *
Init =
nullptr;
270 D.
hasAttr<CUDASharedAttr>() || D.
hasAttr<LoaderUninitializedAttr>())
271 Init = llvm::UndefValue::get(LTy);
275 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
277 nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
278 GV->setAlignment(
getContext().getDeclAlign(&D).getAsAlign());
281 GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
291 llvm::Constant *Addr = GV;
292 if (AS != ExpectedAS) {
294 *
this, GV, AS, ExpectedAS,
296 getContext().getTargetAddressSpace(ExpectedAS)));
307 if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC)) {
315 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
317 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
319 else if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
324 assert(isa<ObjCMethodDecl>(DC) &&
"unexpected parent code decl");
339llvm::GlobalVariable *
341 llvm::GlobalVariable *GV) {
343 llvm::Constant *
Init = emitter.tryEmitForInitializer(D);
355 GV->setConstant(
false);
367 assert(VarSize == CstSize &&
"Emitted constant has unexpected size");
374 if (GV->getValueType() !=
Init->getType()) {
375 llvm::GlobalVariable *OldGV = GV;
377 GV =
new llvm::GlobalVariable(
379 OldGV->getLinkage(),
Init,
"",
380 OldGV, OldGV->getThreadLocalMode(),
381 OldGV->getType()->getPointerAddressSpace());
382 GV->setVisibility(OldGV->getVisibility());
383 GV->setDSOLocal(OldGV->isDSOLocal());
384 GV->setComdat(OldGV->getComdat());
390 OldGV->replaceAllUsesWith(GV);
393 OldGV->eraseFromParent();
401 GV->setInitializer(
Init);
403 emitter.finalize(GV);
416 llvm::GlobalValue::LinkageTypes
Linkage) {
426 setAddrOfLocalVar(&D,
Address(addr, elemTy, alignment));
435 llvm::Type *expectedType = addr->getType();
437 llvm::GlobalVariable *var =
438 cast<llvm::GlobalVariable>(addr->stripPointerCasts());
447 if (D.
getInit() && !isCudaSharedVar)
455 if (
auto *SA = D.
getAttr<PragmaClangBSSSectionAttr>())
456 var->addAttribute(
"bss-section", SA->getName());
457 if (
auto *SA = D.
getAttr<PragmaClangDataSectionAttr>())
458 var->addAttribute(
"data-section", SA->getName());
459 if (
auto *SA = D.
getAttr<PragmaClangRodataSectionAttr>())
460 var->addAttribute(
"rodata-section", SA->getName());
461 if (
auto *SA = D.
getAttr<PragmaClangRelroSectionAttr>())
462 var->addAttribute(
"relro-section", SA->getName());
464 if (
const SectionAttr *SA = D.
getAttr<SectionAttr>())
465 var->setSection(SA->getName());
469 else if (D.
hasAttr<UsedAttr>())
480 llvm::Constant *castedAddr =
481 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
482 LocalDeclMap.find(&D)->second =
Address(castedAddr, elemTy, alignment);
498 CodeGenFunction::Destroyer *destroyer,
499 bool useEHCleanupForArray)
500 : addr(addr),
type(
type), destroyer(destroyer),
501 useEHCleanupForArray(useEHCleanupForArray) {}
505 CodeGenFunction::Destroyer *destroyer;
506 bool useEHCleanupForArray;
510 bool useEHCleanupForArray =
511 flags.isForNormalCleanup() && this->useEHCleanupForArray;
517 template <
class Derived>
520 : NRVOFlag(NRVOFlag), Loc(addr), Ty(
type) {}
522 llvm::Value *NRVOFlag;
528 bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
530 llvm::BasicBlock *SkipDtorBB =
nullptr;
535 llvm::Value *DidNRVO =
537 CGF.
Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
541 static_cast<Derived *
>(
this)->emitDestructorCall(CGF);
546 virtual ~DestroyNRVOVariable() =
default;
549 struct DestroyNRVOVariableCXX final
550 : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
553 : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr,
type, NRVOFlag),
565 struct DestroyNRVOVariableC final
566 : DestroyNRVOVariable<DestroyNRVOVariableC> {
568 : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
577 CallStackRestore(
Address Stack) : Stack(Stack) {}
578 bool isRedundantBeforeReturn()
override {
return true; }
586 std::pair<llvm::Value *, llvm::Value *> AddrSizePair;
587 KmpcAllocFree(
const std::pair<llvm::Value *, llvm::Value *> &AddrSizePair)
588 : AddrSizePair(AddrSizePair) {}
597 ExtendGCLifetime(
const VarDecl *var) : Var(*var) {}
611 llvm::Constant *CleanupFn;
615 CallCleanupFunction(llvm::Constant *CleanupFn,
const CGFunctionInfo *Info,
617 : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
652 llvm_unreachable(
"present but none");
660 (var.
hasAttr<ObjCPreciseLifetimeAttr>()
684 if (
const Expr *e = dyn_cast<Expr>(
s)) {
687 s = e = e->IgnoreParenCasts();
689 if (
const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e))
690 return (ref->getDecl() == &var);
691 if (
const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
692 const BlockDecl *block = be->getBlockDecl();
693 for (
const auto &I : block->
captures()) {
694 if (I.getVariable() == &var)
700 for (
const Stmt *SubStmt :
s->children())
709 if (!
decl)
return false;
710 if (!isa<VarDecl>(
decl))
return false;
717 bool needsCast =
false;
724 case CK_BlockPointerToObjCPointerCast:
730 case CK_LValueToRValue: {
773 if (!
SanOpts.
has(SanitizerKind::NullabilityAssign))
782 SanitizerScope SanScope(
this);
784 llvm::Constant *StaticData[] = {
786 llvm::ConstantInt::get(
Int8Ty, 0),
789 SanitizerHandler::TypeMismatch, StaticData, RHS);
793 LValue lvalue,
bool capturedByInit) {
805 init = DIE->getExpr();
809 if (
auto *EWC = dyn_cast<ExprWithCleanups>(init)) {
810 CodeGenFunction::RunCleanupsScope
Scope(*
this);
811 return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit);
818 bool accessedByInit =
false;
820 accessedByInit = (capturedByInit ||
isAccessedBy(D, init));
821 if (accessedByInit) {
824 if (capturedByInit) {
846 llvm::Value *value =
nullptr;
850 llvm_unreachable(
"present but none");
853 if (!D || !isa<VarDecl>(D) || !cast<VarDecl>(D)->isARCPseudoStrong()) {
912 unsigned &NumStores) {
914 if (isa<llvm::ConstantAggregateZero>(
Init) ||
915 isa<llvm::ConstantPointerNull>(
Init) ||
916 isa<llvm::UndefValue>(
Init))
918 if (isa<llvm::ConstantInt>(
Init) || isa<llvm::ConstantFP>(
Init) ||
919 isa<llvm::ConstantVector>(
Init) || isa<llvm::BlockAddress>(
Init) ||
920 isa<llvm::ConstantExpr>(
Init))
921 return Init->isNullValue() || NumStores--;
924 if (isa<llvm::ConstantArray>(
Init) || isa<llvm::ConstantStruct>(
Init)) {
925 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
926 llvm::Constant *Elt = cast<llvm::Constant>(
Init->getOperand(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);
953 assert(!
Init->isNullValue() && !isa<llvm::UndefValue>(
Init) &&
954 "called emitStoresForInitAfterBZero for zero or undef value.");
956 if (isa<llvm::ConstantInt>(
Init) || isa<llvm::ConstantFP>(
Init) ||
957 isa<llvm::ConstantVector>(
Init) || isa<llvm::BlockAddress>(
Init) ||
958 isa<llvm::ConstantExpr>(
Init)) {
959 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);
971 if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
973 CGM, Elt, Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,
974 Builder, IsAutoInit);
979 assert((isa<llvm::ConstantStruct>(
Init) || isa<llvm::ConstantArray>(
Init)) &&
980 "Unknown value type!");
982 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
983 llvm::Constant *Elt = cast<llvm::Constant>(
Init->getOperand(i));
986 if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
988 Builder.CreateConstInBoundsGEP2_32(Loc, 0, i),
989 isVolatile, Builder, IsAutoInit);
997 uint64_t GlobalSize) {
999 if (isa<llvm::ConstantAggregateZero>(
Init))
return true;
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)
1045 if (isPattern == IsPattern::Yes)
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));
1076 CurOp = cast<llvm::Constant>(constant->getAggregateElement(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();
1143 }
else if (isa<BlockDecl>(DC)) {
1145 }
else if (isa<CapturedDecl>(DC)) {
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,
1193 llvm::Constant *constant,
bool IsAutoInit) {
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);
1204 I->addAnnotationMetadata(
"auto-init");
1208 auto *SizeVal = llvm::ConstantInt::get(CGM.
IntPtrTy, ConstantSize);
1213 auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(CGM.
Int8Ty, 0),
1214 SizeVal, isVolatile);
1216 I->addAnnotationMetadata(
"auto-init");
1218 bool valueAlreadyCorrect =
1219 constant->isNullValue() || isa<llvm::UndefValue>(constant);
1220 if (!valueAlreadyCorrect) {
1229 llvm::Value *Pattern =
1232 uint64_t
Value = 0x00;
1233 if (!isa<llvm::UndefValue>(Pattern)) {
1234 const llvm::APInt &AP = cast<llvm::ConstantInt>(Pattern)->getValue();
1235 assert(AP.getBitWidth() <= 8);
1236 Value = AP.getLimitedValue();
1238 auto *I = Builder.CreateMemSet(
1239 Loc, llvm::ConstantInt::get(CGM.
Int8Ty,
Value), SizeVal, isVolatile);
1241 I->addAnnotationMetadata(
"auto-init");
1247 bool IsTrivialAutoVarInitPattern =
1251 if (
auto *STy = dyn_cast<llvm::StructType>(Ty)) {
1254 const llvm::StructLayout *Layout =
1256 for (
unsigned i = 0; i != constant->getNumOperands(); i++) {
1259 Address EltPtr = Builder.CreateConstInBoundsByteGEP(
1262 constant->getAggregateElement(i), IsAutoInit);
1266 }
else if (
auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) {
1269 for (
unsigned i = 0; i != ATy->getNumElements(); i++) {
1270 Address EltPtr = Builder.CreateConstGEP(
1273 constant->getAggregateElement(i), IsAutoInit);
1282 Builder.CreateMemCpy(Loc,
1285 SizeVal, isVolatile);
1287 I->addAnnotationMetadata(
"auto-init");
1294 llvm::Constant *constant =
1306 assert(!isa<llvm::UndefValue>(constant));
1312 auto *Ty = constant->getType();
1313 if (isa<llvm::UndefValue>(constant))
1315 if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())
1316 for (llvm::Use &Op : constant->operands())
1323 llvm::Constant *constant) {
1324 auto *Ty = constant->getType();
1325 if (isa<llvm::UndefValue>(constant))
1327 if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
1332 for (
unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
1333 auto *OpValue = cast<llvm::Constant>(constant->getOperand(Op));
1336 if (Ty->isStructTy())
1337 return llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Values);
1338 if (Ty->isArrayTy())
1339 return llvm::ConstantArray::get(cast<llvm::ArrayType>(Ty), Values);
1340 assert(Ty->isVectorTy());
1341 return llvm::ConstantVector::get(Values);
1357 llvm::Value *Addr) {
1358 if (!ShouldEmitLifetimeMarkers)
1361 assert(Addr->getType()->getPointerAddressSpace() ==
1363 "Pointer should be in alloca address space");
1364 llvm::Value *SizeV = llvm::ConstantInt::get(
1368 C->setDoesNotThrow();
1373 assert(Addr->getType()->getPointerAddressSpace() ==
1375 "Pointer should be in alloca address space");
1378 C->setDoesNotThrow();
1390 while (
getContext().getAsVariableArrayType(Type1D)) {
1392 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1396 Twine Name = Twine(
"__vla_expr") + Twine(VLAExprCounter++);
1398 StringRef NameRef = Name.toStringRef(Buffer);
1400 VLAExprNames.push_back(&Ident);
1404 Dimensions.emplace_back(SizeExprAddr.getPointer(),
1407 Type1D = VlaSize.Type;
1416 unsigned NameIdx = 0;
1417 for (
auto &VlaSize : Dimensions) {
1419 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1420 MD = llvm::ConstantAsMetadata::get(
C);
1425 SizeTy->getScalarSizeInBits(),
false);
1430 ArtificialDecl->setImplicit();
1435 assert(MD &&
"No Size expression debug node created");
1442CodeGenFunction::AutoVarEmission
1449 AutoVarEmission emission(D);
1452 emission.IsEscapingByRef = isEscapingByRef;
1477 address = OpenMPLocalAddr;
1478 AllocaAddr = OpenMPLocalAddr;
1491 getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) &&
1510 assert(emission.wasEmittedAsGlobal());
1515 emission.IsConstantAggregate =
true;
1530 const auto *RD = RecordTy->getDecl();
1531 const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1532 if ((CXXRD && !CXXRD->hasTrivialDestructor()) ||
1533 RD->isNonTrivialToPrimitiveDestroy()) {
1550 llvm::Type *allocaTy;
1551 if (isEscapingByRef) {
1553 allocaTy = byrefInfo.Type;
1554 allocaAlignment = byrefInfo.ByrefAlignment;
1557 allocaAlignment = alignment;
1564 nullptr, &AllocaAddr);
1569 bool IsMSCatchParam =
1591 emission.SizeForLifetimeMarkers =
1595 assert(!emission.useLifetimeMarkers());
1606 bool VarAllocated =
false;
1609 if (RT.isDelayedVariableLengthDecl(*
this, &D)) {
1611 std::pair<llvm::Value *, llvm::Value *> AddrSizePair =
1618 address =
Base.getAddress(*
this);
1626 VarAllocated =
true;
1630 if (!VarAllocated) {
1631 if (!DidCallStackSave) {
1636 llvm::Value *
V =
Builder.CreateStackSave();
1640 DidCallStackSave =
true;
1661 setAddrOfLocalVar(&D, address);
1662 emission.Addr = address;
1663 emission.AllocaAddr = AllocaAddr;
1672 if (UsePointerValue) {
1684 if (emission.useLifetimeMarkers())
1686 emission.getOriginalAllocatedAddress(),
1687 emission.getSizeForLifetimeMarkers());
1697 if (
const Expr *E = dyn_cast<Expr>(S))
1699 for (
const Stmt *SubStmt : S->children())
1712 if (
const BlockExpr *BE = dyn_cast<BlockExpr>(E)) {
1714 for (
const auto &I :
Block->captures()) {
1715 if (I.getVariable() == &Var)
1723 if (
const StmtExpr *SE = dyn_cast<StmtExpr>(E)) {
1725 for (
const auto *BI : CS->
body())
1726 if (
const auto *BIE = dyn_cast<Expr>(BI)) {
1730 else if (
const auto *DS = dyn_cast<DeclStmt>(BI)) {
1732 for (
const auto *I : DS->decls()) {
1733 if (
const auto *VD = dyn_cast<VarDecl>((I))) {
1764 !Construct->requiresZeroInitialization())
1770void CodeGenFunction::emitZeroOrPatternForAutoVarInit(
QualType type,
1774 auto trivialAutoVarInitMaxSize =
1777 bool isVolatile =
type.isVolatileQualified();
1778 if (!
Size.isZero()) {
1785 switch (trivialAutoVarInit) {
1787 llvm_unreachable(
"Uninitialized handled by caller");
1791 if (trivialAutoVarInitMaxSize > 0 &&
1792 allocSize > trivialAutoVarInitMaxSize)
1799 if (trivialAutoVarInitMaxSize > 0 &&
1800 allocSize > trivialAutoVarInitMaxSize)
1817 auto SizeVal = VlaSize.NumElts;
1819 switch (trivialAutoVarInit) {
1821 llvm_unreachable(
"Uninitialized handled by caller");
1826 if (!EltSize.
isOne())
1829 SizeVal, isVolatile);
1830 I->addAnnotationMetadata(
"auto-init");
1844 llvm::Value *IsZeroSizedVLA =
Builder.CreateICmpEQ(
1845 SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0),
1847 Builder.CreateCondBr(IsZeroSizedVLA, ContBB, SetupBB);
1849 if (!EltSize.
isOne())
1851 llvm::Value *BaseSizeInChars =
1854 llvm::Value *End =
Builder.CreateInBoundsGEP(
1855 Begin.getElementType(),
Begin.getPointer(), SizeVal,
"vla.end");
1856 llvm::BasicBlock *OriginBB =
Builder.GetInsertBlock();
1858 llvm::PHINode *Cur =
Builder.CreatePHI(
Begin.getType(), 2,
"vla.cur");
1859 Cur->addIncoming(
Begin.getPointer(), OriginBB);
1865 BaseSizeInChars, isVolatile);
1866 I->addAnnotationMetadata(
"auto-init");
1868 Builder.CreateInBoundsGEP(
Int8Ty, Cur, BaseSizeInChars,
"vla.next");
1869 llvm::Value *Done =
Builder.CreateICmpEQ(Next, End,
"vla-init.isdone");
1870 Builder.CreateCondBr(Done, ContBB, LoopBB);
1871 Cur->addIncoming(Next, LoopBB);
1878 assert(emission.Variable &&
"emission was not valid!");
1881 if (emission.wasEmittedAsGlobal())
return;
1883 const VarDecl &D = *emission.Variable;
1898 if (emission.IsEscapingByRef)
1905 type.isNonTrivialToPrimitiveDefaultInitialize() ==
1908 if (emission.IsEscapingByRef)
1917 bool capturedByInit =
1920 bool locIsByrefHeader = !capturedByInit;
1922 locIsByrefHeader ? emission.getObjectAddress(*
this) : emission.Addr;
1928 : (D.
getAttr<UninitializedAttr>()
1932 auto initializeWhatIsTechnicallyUninitialized = [&](
Address Loc) {
1933 if (trivialAutoVarInit ==
1938 if (emission.IsEscapingByRef && !locIsByrefHeader)
1941 return emitZeroOrPatternForAutoVarInit(
type, D, Loc);
1945 return initializeWhatIsTechnicallyUninitialized(Loc);
1947 llvm::Constant *constant =
nullptr;
1948 if (emission.IsConstantAggregate ||
1950 assert(!capturedByInit &&
"constant init contains a capturing block?");
1952 if (constant && !constant->isZeroValue() &&
1953 (trivialAutoVarInit !=
1971 initializeWhatIsTechnicallyUninitialized(Loc);
1977 if (!emission.IsConstantAggregate) {
2000 LValue lvalue,
bool capturedByInit) {
2003 if (
type->isReferenceType()) {
2022 if (
type->isAtomicType()) {
2026 if (isa<VarDecl>(D))
2028 else if (
auto *FD = dyn_cast<FieldDecl>(D))
2038 llvm_unreachable(
"bad evaluation kind");
2043 const CodeGenFunction::AutoVarEmission &emission,
2049 Address addr = emission.getObjectAddress(*
this);
2051 const VarDecl *var = emission.Variable;
2059 llvm_unreachable(
"no cleanup for trivially-destructible variable");
2064 if (emission.NRVOFlag) {
2065 assert(!
type->isArrayType());
2067 EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr,
type, dtor,
2081 if (!var->
hasAttr<ObjCPreciseLifetimeAttr>())
2090 if (emission.NRVOFlag) {
2091 assert(!
type->isArrayType());
2092 EHStack.pushCleanup<DestroyNRVOVariableC>(cleanupKind, addr,
2093 emission.NRVOFlag,
type);
2104 bool useEHCleanup = (cleanupKind &
EHCleanup);
2105 EHStack.pushCleanup<DestroyObject>(cleanupKind, addr,
type, destroyer,
2110 assert(emission.Variable &&
"emission was not valid!");
2113 if (emission.wasEmittedAsGlobal())
return;
2119 const VarDecl &D = *emission.Variable;
2127 D.
hasAttr<ObjCPreciseLifetimeAttr>()) {
2132 if (
const CleanupAttr *CA = D.
getAttr<CleanupAttr>()) {
2136 assert(F &&
"Could not find function!");
2145 if (emission.IsEscapingByRef &&
2148 if (emission.Variable->getType().isObjCGCWeak())
2169 llvm_unreachable(
"Unknown DestructionKind");
2176 assert(dtorKind &&
"cannot push destructor for trivial type");
2186 assert(dtorKind &&
"cannot push destructor for trivial type");
2195 bool useEHCleanupForArray) {
2196 pushFullExprCleanup<DestroyObject>(cleanupKind, addr,
type,
2197 destroyer, useEHCleanupForArray);
2201 EHStack.pushCleanup<CallStackRestore>(
Kind, SPMem);
2205 CleanupKind Kind, std::pair<llvm::Value *, llvm::Value *> AddrSizePair) {
2206 EHStack.pushCleanup<KmpcAllocFree>(
Kind, AddrSizePair);
2211 Destroyer *destroyer,
2212 bool useEHCleanupForArray) {
2220 EHStack.pushCleanup<DestroyObject>(
2222 destroyer, useEHCleanupForArray);
2224 return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>(
2233 using ConditionalCleanupType =
2241 EHStack.pushCleanup<ConditionalCleanupType>(
2242 static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), SavedAddr,
type,
2243 destroyer, useEHCleanupForArray);
2247 pushCleanupAfterFullExprWithActiveFlag<ConditionalCleanupType>(
2248 cleanupKind, ActiveFlag, SavedAddr,
type, destroyer,
2249 useEHCleanupForArray);
2264 Destroyer *destroyer,
2265 bool useEHCleanupForArray) {
2268 return destroyer(*
this, addr,
type);
2277 bool checkZeroLength =
true;
2280 if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(
length)) {
2282 if (constLength->isZero())
return;
2283 checkZeroLength =
false;
2290 checkZeroLength, useEHCleanupForArray);
2307 Destroyer *destroyer,
2308 bool checkZeroLength,
2309 bool useEHCleanup) {
2317 if (checkZeroLength) {
2318 llvm::Value *isEmpty =
Builder.CreateICmpEQ(begin, end,
2319 "arraydestroy.isempty");
2320 Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
2324 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2326 llvm::PHINode *elementPast =
2327 Builder.CreatePHI(begin->getType(), 2,
"arraydestroy.elementPast");
2328 elementPast->addIncoming(end, entryBB);
2331 llvm::Value *negativeOne = llvm::ConstantInt::get(
SizeTy, -1,
true);
2333 llvm::Value *element =
Builder.CreateInBoundsGEP(
2334 llvmElementType, elementPast, negativeOne,
"arraydestroy.element");
2341 destroyer(*
this,
Address(element, llvmElementType, elementAlign),
2348 llvm::Value *done =
Builder.CreateICmpEQ(element, begin,
"arraydestroy.done");
2349 Builder.CreateCondBr(done, doneBB, bodyBB);
2350 elementPast->addIncoming(element,
Builder.GetInsertBlock());
2359 llvm::Value *begin, llvm::Value *end,
2365 unsigned arrayDepth = 0;
2374 llvm::Value *zero = llvm::ConstantInt::get(CGF.
SizeTy, 0);
2377 begin = CGF.
Builder.CreateInBoundsGEP(
2378 elemTy, begin, gepIndices,
"pad.arraybegin");
2379 end = CGF.
Builder.CreateInBoundsGEP(
2380 elemTy, end, gepIndices,
"pad.arrayend");
2395 llvm::Value *ArrayBegin;
2396 llvm::Value *ArrayEnd;
2398 CodeGenFunction::Destroyer *Destroyer;
2401 RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
2403 CodeGenFunction::Destroyer *destroyer)
2404 : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
2405 ElementType(elementType), Destroyer(destroyer),
2406 ElementAlign(elementAlign) {}
2410 ElementType, ElementAlign, Destroyer);
2418 llvm::Value *ArrayBegin;
2421 CodeGenFunction::Destroyer *Destroyer;
2424 IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
2428 CodeGenFunction::Destroyer *destroyer)
2429 : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
2430 ElementType(elementType), Destroyer(destroyer),
2431 ElementAlign(elementAlign) {}
2436 ElementType, ElementAlign, Destroyer);
2451 Destroyer *destroyer) {
2452 pushFullExprCleanup<IrregularPartialArrayDestroy>(
EHCleanup,
2453 arrayBegin, arrayEndPointer,
2454 elementType, elementAlign,
2465 llvm::Value *arrayEnd,
2468 Destroyer *destroyer) {
2469 pushFullExprCleanup<RegularPartialArrayDestroy>(
EHCleanup,
2470 arrayBegin, arrayEnd,
2471 elementType, elementAlign,
2477 if (LifetimeStartFn)
2478 return LifetimeStartFn;
2479 LifetimeStartFn = llvm::Intrinsic::getDeclaration(&
getModule(),
2481 return LifetimeStartFn;
2487 return LifetimeEndFn;
2488 LifetimeEndFn = llvm::Intrinsic::getDeclaration(&
getModule(),
2490 return LifetimeEndFn;
2499 ConsumeARCParameter(llvm::Value *param,
2501 : Param(param), Precise(precise) {}
2516 bool NoDebugInfo =
false;
2518 assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
2519 "Invalid argument to EmitParmDecl");
2523 if (!isa<llvm::GlobalValue>(Arg.getAnyValue()))
2524 Arg.getAnyValue()->setName(D.
getName());
2529 if (
auto IPD = dyn_cast<ImplicitParamDecl>(&D)) {
2533 llvm::Value *
V = Arg.isIndirect()
2535 : Arg.getDirectValue();
2547 bool DoStore =
false;
2549 bool UseIndirectDebugAddress =
false;
2552 if (Arg.isIndirect()) {
2553 DeclPtr = Arg.getIndirectAddress();
2559 AllocaPtr = DeclPtr;
2566 if (UseIndirectDebugAddress) {
2569 D.
getName() +
".indirect_addr");
2576 if (SrcLangAS != DestLangAS) {
2577 assert(
getContext().getTargetAddressSpace(SrcLangAS) ==
2583 *
this,
V, SrcLangAS, DestLangAS, T,
true),
2596 "unexpected destructor type");
2598 CalleeDestructedParamCleanups[cast<ParmVarDecl>(&D)] =
2609 DeclPtr = OpenMPLocalAddr;
2610 AllocaPtr = DeclPtr;
2614 D.
getName() +
".addr", &AllocaPtr);
2619 llvm::Value *ArgVal = (DoStore ? Arg.getDirectValue() :
nullptr);
2629 bool isConsumed = D.
hasAttr<NSConsumedAttr>();
2634 "pseudo-strong variable isn't strong?");
2635 assert(qs.
hasConst() &&
"pseudo-strong variable should be const!");
2640 if (Arg.isIndirect() && !ArgVal)
2684 setAddrOfLocalVar(&D, DeclPtr);
2692 if (
const auto *Var = dyn_cast_or_null<ParmVarDecl>(&D))
2697 if (D.
hasAttr<AnnotateAttr>())
2703 if (requiresReturnValueNullabilityCheck()) {
2706 SanitizerScope SanScope(
this);
2707 RetValNullabilityPrecondition =
2708 Builder.CreateAnd(RetValNullabilityPrecondition,
2709 Builder.CreateIsNotNull(Arg.getAnyValue()));
2716 if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->
isUsed()))
2723 if (!LangOpts.OpenMP || LangOpts.OpenMPSimd ||
2724 (!LangOpts.EmitAllDecls && !D->
isUsed()))
2735 const auto *DE = cast<DeclRefExpr>(E);
2736 const auto *VD = cast<VarDecl>(DE->getDecl());
2759 if (Entry->getType()->getAddressSpace() == TargetAS)
2764 llvm::PointerType *PTy = llvm::PointerType::get(Ty, TargetAS);
2769 llvm::GlobalVariable *DummyGV =
new llvm::GlobalVariable(
2770 getModule(), Entry->getValueType(),
false,
2771 llvm::GlobalValue::CommonLinkage,
nullptr,
"dummy",
nullptr,
2772 llvm::GlobalVariable::NotThreadLocal, Entry->getAddressSpace());
2773 Entry->replaceAllUsesWith(DummyGV);
2775 Entry->mutateType(PTy);
2776 llvm::Constant *NewPtrForOldDecl =
2777 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
2778 Entry, DummyGV->getType());
2782 DummyGV->replaceAllUsesWith(NewPtrForOldDecl);
2783 DummyGV->eraseFromParent();
2787std::optional<CharUnits>
2789 if (
const auto *AA = VD->
getAttr<OMPAllocateDeclAttr>()) {
2790 if (
Expr *Alignment = AA->getAlignment()) {
2791 unsigned UserAlign =
2792 Alignment->EvaluateKnownConstInt(
getContext()).getExtValue();
2800 std::max<unsigned>(UserAlign, NaturalAlign.
getQuantity()));
2803 return std::nullopt;
Defines the clang::ASTContext interface.
static void emitStoresForInitAfterBZero(CodeGenModule &CGM, llvm::Constant *Init, Address Loc, bool isVolatile, CGBuilderTy &Builder, bool IsAutoInit)
For inits that canEmitInitWithFewStoresAfterBZero returned true for, emit the scalar stores that woul...
static bool isCapturedBy(const VarDecl &, const Expr *)
Determines whether the given __block variable is potentially captured by the given expression.
static void emitPartialArrayDestroy(CodeGenFunction &CGF, llvm::Value *begin, llvm::Value *end, QualType type, CharUnits elementAlign, CodeGenFunction::Destroyer *destroyer)
Perform partial array destruction as if in an EH cleanup.
static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D, Address Loc, bool isVolatile, CGBuilderTy &Builder)
static bool canEmitInitWithFewStoresAfterBZero(llvm::Constant *Init, unsigned &NumStores)
Decide whether we can emit the non-zero parts of the specified initializer with equal or fewer than N...
static llvm::Constant * patternOrZeroFor(CodeGenModule &CGM, IsPattern isPattern, llvm::Type *Ty)
Generate a constant filled with either a pattern or zeroes.
static llvm::Constant * constWithPadding(CodeGenModule &CGM, IsPattern isPattern, llvm::Constant *constant)
Replace all padding bytes in a given constant with either a pattern byte or 0x00.
static llvm::Value * shouldUseMemSetToInitialize(llvm::Constant *Init, uint64_t GlobalSize, const llvm::DataLayout &DL)
Decide whether we should use memset to initialize a local variable instead of using a memcpy from a c...
static std::string getStaticDeclName(CodeGenModule &CGM, const VarDecl &D)
static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, Address Loc, bool isVolatile, CGBuilderTy &Builder, llvm::Constant *constant, bool IsAutoInit)
static bool shouldSplitConstantStore(CodeGenModule &CGM, uint64_t GlobalByteSize)
Decide whether we want to split a constant structure or array store into a sequence of its fields' st...
static llvm::Constant * replaceUndef(CodeGenModule &CGM, IsPattern isPattern, llvm::Constant *constant)
static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF, const LValue &destLV, const Expr *init)
static bool shouldUseBZeroPlusStoresToInitialize(llvm::Constant *Init, uint64_t GlobalSize)
Decide whether we should use bzero plus some stores to initialize a local variable instead of using a...
static llvm::Constant * constStructWithPadding(CodeGenModule &CGM, IsPattern isPattern, llvm::StructType *STy, llvm::Constant *constant)
Helper function for constWithPadding() to deal with padding in structures.
static bool containsUndef(llvm::Constant *constant)
static bool isAccessedBy(const VarDecl &var, const Stmt *s)
static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var, Address addr, Qualifiers::ObjCLifetime lifetime)
EmitAutoVarWithLifetime - Does the setup required for an automatic variable with lifetime.
static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM, const VarDecl &D, CGBuilderTy &Builder, llvm::Constant *Constant, CharUnits Align)
static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D, Address Loc, bool isVolatile, CGBuilderTy &Builder)
static void drillIntoBlockVariable(CodeGenFunction &CGF, LValue &lvalue, const VarDecl *var)
CodeGenFunction::ComplexPairTy ComplexPairTy
This file defines OpenMP nodes for declarative directives.
static const RecordType * getRecordType(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
static const NamedDecl * getDefinition(const Decl *D)
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
unsigned getTargetAddressSpace(LangAS AS) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
ArrayRef< Capture > captures() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
A use of a default initializer in a constructor or in aggregate initialization.
Represents a C++ destructor within a class.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
bool getIndirectByVal() const
CharUnits getAlignment() const
Return the alignment of this pointer.
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::Value * getPointer() const
static AggValueSlot forLValue(const LValue &LV, CodeGenFunction &CGF, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about a global variable.
Param2DILocTy & getParamDbgMappings()
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void setLocation(SourceLocation Loc)
Update the current source location.
void registerVLASizeExpression(QualType Ty, llvm::Metadata *SizeExpr)
Register VLA size expression debug node with the qualified type.
CGFunctionInfo - Class to encapsulate the information about a function definition.
const_arg_iterator arg_begin() const
MutableArrayRef< ArgInfo > arguments()
virtual void EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF, const VarDecl &D)
Emit the IR required for a work-group-local variable declaration, and add an entry to CGF's LocalDecl...
Allows to disable automatic handling of functions used in target regions as those marked as omp decla...
virtual void getKmpcFreeShared(CodeGenFunction &CGF, const std::pair< llvm::Value *, llvm::Value * > &AddrSizePair)
Get call to __kmpc_free_shared.
void emitUserDefinedMapper(const OMPDeclareMapperDecl *D, CodeGenFunction *CGF=nullptr)
Emit the function for the user defined mapper construct.
virtual void processRequiresDirective(const OMPRequiresDecl *D)
Perform check on requires decl to ensure that target architecture supports unified addressing.
virtual std::pair< llvm::Value *, llvm::Value * > getKmpcAllocShared(CodeGenFunction &CGF, const VarDecl *VD)
Get call to __kmpc_alloc_shared.
virtual void emitUserDefinedReduction(CodeGenFunction *CGF, const OMPDeclareReductionDecl *D)
Emit code for the specified user defined reduction construct.
virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void emitAutoVarTypeCleanup(const AutoVarEmission &emission, QualType::DestructionKind dtorKind)
void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, bool LoadBlockVarAddr, bool CanThrow)
Enter a cleanup to destroy a __block variable.
llvm::Value * EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr)
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
static Destroyer destroyNonTrivialCStruct
static bool cxxDestructorCanThrow(QualType T)
Check if T is a C++ class that has a destructor that can throw.
SanitizerSet SanOpts
Sanitizers enabled for this function.
llvm::DenseMap< const VarDecl *, llvm::Value * > NRVOFlags
A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...
void EmitARCMoveWeak(Address dst, Address src)
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
static bool hasScalarEvaluationKind(QualType T)
const BlockByrefInfo & getBlockByrefInfo(const VarDecl *var)
void EmitDecl(const Decl &D)
EmitDecl - Emit a declaration.
void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
CleanupKind getARCCleanupKind()
Retrieves the default cleanup kind for an ARC cleanup.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitExtendGCLifetime(llvm::Value *object)
EmitExtendGCLifetime - Given a pointer to an Objective-C object, make sure it survives garbage collec...
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
const CodeGen::CGBlockInfo * BlockInfo
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
void emitByrefStructureInit(const AutoVarEmission &emission)
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
@ TCK_NonnullAssign
Checking the value assigned to a _Nonnull pointer. Must not be null.
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitARCUnsafeUnretainedScalarExpr(const Expr *expr)
void EmitAutoVarInit(const AutoVarEmission &emission)
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
DominatingValue< T >::saved_type saveValueInCond(T value)
void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
static Destroyer destroyCXXObject
void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)
Emit local annotations for the local variable V, declared by D.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitAtomicInit(Expr *E, LValue lvalue)
const TargetInfo & getTarget() const
bool isInConditionalBranch() const
isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)
Emit code in this function to perform a guarded variable initialization.
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void EmitARCCopyWeak(Address dst, Address src)
void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)
void defaultInitNonTrivialCStructVar(LValue Dst)
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
CGDebugInfo * getDebugInfo()
Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, bool followForward=true)
BuildBlockByrefAddress - Computes the location of the data in a variable which is declared as __block...
LValue EmitDeclRefLValue(const DeclRefExpr *E)
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
Address createCleanupActiveFlag()
Address CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
llvm::Value * EmitARCRetainAutoreleaseScalarExpr(const Expr *expr)
const TargetCodeGenInfo & getTargetHooks() const
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
Address ReturnValuePointer
ReturnValuePointer - The temporary alloca to hold a pointer to sret.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
llvm::GlobalVariable * AddInitializerToStaticVarDecl(const VarDecl &D, llvm::GlobalVariable *GV)
AddInitializerToStaticVarDecl - Add the initializer for 'D' to the global variable that has already b...
static Destroyer destroyARCWeak
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertType(QualType T)
void EmitARCInitWeak(Address addr, llvm::Value *value)
static Destroyer destroyARCStrongPrecise
void initFullExprCleanupWithFlag(Address ActiveFlag)
VarBypassDetector Bypasses
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
void pushStackRestore(CleanupKind kind, Address SPMem)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const CGFunctionInfo * CurFnInfo
void pushKmpcAllocFree(CleanupKind Kind, std::pair< llvm::Value *, llvm::Value * > AddrSizePair)
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
static Destroyer destroyARCStrongImprecise
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo)
Emits the alloca and debug information for the size expressions for each dimension of an array.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
bool hasLabelBeenSeenInCurrentScope() const
Return true if a label was seen in the current scope.
This class organizes the cross-function state that is used while generating LLVM code.
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::Module & getModule() const
void setStaticLocalDeclAddress(const VarDecl *D, llvm::Constant *C)
llvm::Function * getLLVMLifetimeStartFn()
Lazily declare the @llvm.lifetime.start intrinsic.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant, CharUnits Align)
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
void EmitOMPAllocateDecl(const OMPAllocateDecl *D)
Emit a code for the allocate directive.
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)
Returns LLVM linkage for a declarator.
const llvm::DataLayout & getDataLayout() const
void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
SanitizerMetadata * getSanitizerMetadata()
llvm::Constant * getOrCreateStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV)
Add global annotations that are set on D, for the global GV.
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const
Set the TLS mode for the given LLVM GlobalValue for the thread-local variable declaration D.
ASTContext & getContext() const
void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, CodeGenFunction *CGF=nullptr)
Emit a code for declare mapper construct.
llvm::Function * getLLVMLifetimeEndFn()
Lazily declare the @llvm.lifetime.end intrinsic.
bool supportsCOMDAT() const
void EmitOMPRequiresDecl(const OMPRequiresDecl *D)
Emit a code for requires directive.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
std::optional< CharUnits > getOMPAllocateAlignment(const VarDecl *VD)
Return the alignment specified in an allocate directive, if present.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, CodeGenFunction *CGF=nullptr)
Emit a code for declare reduction construct.
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
const CGFunctionInfo & arrangeFunctionDeclaration(const FunctionDecl *FD)
Free functions are functions that are compatible with an ordinary C function pointer type.
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
Information for lazily generating a cleanup.
ConditionalCleanup stores the saved form of its parameters, then restores them and performs the clean...
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
LValue - This represents an lvalue references.
Address getAddress(CodeGenFunction &CGF) const
llvm::Value * getPointer(CodeGenFunction &CGF) 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)
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
bool IsBypassed(const VarDecl *D) const
Returns true if the variable declaration was by bypassed by any goto or switch statement.
CompoundStmt - This represents a group of statements like { stmt stmt }.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks,...
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
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.
A (possibly-)qualified type.
@ DK_objc_strong_lifetime
@ PDIK_Struct
The type is a struct containing a field whose type is not PCK_Trivial.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
bool isParamDestroyedInCallee() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
static const uint64_t MaximumAlignment
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
const T * castAs() const
Member-template castAs<specific type>.
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
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
Matches all kinds of arrays.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
bool Zero(InterpState &S, CodePtr OpPC)
bool Null(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Ctor_Base
Base object ctor.
@ NonNull
Values of this type can never be null.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ SD_Automatic
Automatic storage duration (most local variables).
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
@ ThreadPrivateVar
Parameter for Thread private variable.
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
static Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable /p VD.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * IntPtrTy
llvm::PointerType * AllocaInt8PtrTy
LangAS getASTAllocaAddressSpace() const
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.