35#include "llvm/Analysis/ConstantFolding.h"
36#include "llvm/Analysis/ValueTracking.h"
37#include "llvm/IR/DataLayout.h"
38#include "llvm/IR/GlobalVariable.h"
39#include "llvm/IR/Instructions.h"
40#include "llvm/IR/Intrinsics.h"
41#include "llvm/IR/Type.h"
45using namespace CodeGen;
48 "Clang max alignment greater than what LLVM supports?");
50void CodeGenFunction::EmitDecl(
const Decl &
D) {
52 case Decl::BuiltinTemplate:
53 case Decl::TranslationUnit:
54 case Decl::ExternCContext:
56 case Decl::UnresolvedUsingTypename:
57 case Decl::ClassTemplateSpecialization:
58 case Decl::ClassTemplatePartialSpecialization:
59 case Decl::VarTemplateSpecialization:
60 case Decl::VarTemplatePartialSpecialization:
61 case Decl::TemplateTypeParm:
62 case Decl::UnresolvedUsingValue:
63 case Decl::NonTypeTemplateParm:
64 case Decl::CXXDeductionGuide:
66 case Decl::CXXConstructor:
67 case Decl::CXXDestructor:
68 case Decl::CXXConversion:
70 case Decl::MSProperty:
71 case Decl::IndirectField:
73 case Decl::ObjCAtDefsField:
75 case Decl::ImplicitParam:
76 case Decl::ClassTemplate:
77 case Decl::VarTemplate:
78 case Decl::FunctionTemplate:
79 case Decl::TypeAliasTemplate:
80 case Decl::TemplateTemplateParm:
81 case Decl::ObjCMethod:
82 case Decl::ObjCCategory:
83 case Decl::ObjCProtocol:
84 case Decl::ObjCInterface:
85 case Decl::ObjCCategoryImpl:
86 case Decl::ObjCImplementation:
87 case Decl::ObjCProperty:
88 case Decl::ObjCCompatibleAlias:
89 case Decl::PragmaComment:
90 case Decl::PragmaDetectMismatch:
91 case Decl::AccessSpec:
92 case Decl::LinkageSpec:
94 case Decl::ObjCPropertyImpl:
95 case Decl::FileScopeAsm:
96 case Decl::TopLevelStmt:
98 case Decl::FriendTemplate:
101 case Decl::UsingShadow:
102 case Decl::ConstructorUsingShadow:
103 case Decl::ObjCTypeParam:
105 case Decl::UnresolvedUsingIfExists:
106 case Decl::HLSLBuffer:
107 llvm_unreachable(
"Declaration should not be in declstmts!");
109 case Decl::CXXRecord:
117 DI->EmitAndRetainType(
getContext().getEnumType(cast<EnumDecl>(&
D)));
120 case Decl::EnumConstant:
121 case Decl::StaticAssert:
125 case Decl::UnnamedGlobalConstant:
126 case Decl::TemplateParamObject:
127 case Decl::OMPThreadPrivate:
128 case Decl::OMPAllocate:
129 case Decl::OMPCapturedExpr:
130 case Decl::OMPRequires:
133 case Decl::ImplicitConceptSpecialization:
134 case Decl::LifetimeExtendedTemporary:
135 case Decl::RequiresExprBody:
139 case Decl::NamespaceAlias:
141 DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(
D));
145 DI->EmitUsingDecl(cast<UsingDecl>(
D));
147 case Decl::UsingEnum:
149 DI->EmitUsingEnumDecl(cast<UsingEnumDecl>(
D));
151 case Decl::UsingPack:
152 for (
auto *Using : cast<UsingPackDecl>(
D).expansions())
155 case Decl::UsingDirective:
157 DI->EmitUsingDirective(cast<UsingDirectiveDecl>(
D));
160 case Decl::Decomposition: {
161 const VarDecl &VD = cast<VarDecl>(
D);
163 "Should not see file-scope variables inside a function!");
165 if (
auto *DD = dyn_cast<DecompositionDecl>(&VD))
166 for (
auto *B : DD->bindings())
167 if (
auto *HD = B->getHoldingVar())
172 case Decl::OMPDeclareReduction:
175 case Decl::OMPDeclareMapper:
179 case Decl::TypeAlias: {
180 QualType Ty = cast<TypedefNameDecl>(
D).getUnderlyingType();
182 DI->EmitAndRetainType(Ty);
193 if (
D.hasExternalStorage())
202 if (
D.getType()->isSamplerT())
205 llvm::GlobalValue::LinkageTypes
Linkage =
218 assert(
D.hasLocalStorage());
227 assert(!
D.isExternallyVisible() &&
"name shouldn't matter");
228 std::string ContextName;
230 if (
auto *CD = dyn_cast<CapturedDecl>(DC))
231 DC = cast<DeclContext>(CD->getNonClosureContext());
232 if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
234 else if (
const auto *BD = dyn_cast<BlockDecl>(DC))
236 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(DC))
237 ContextName = OMD->getSelector().getAsString();
239 llvm_unreachable(
"Unknown context for static var decl");
241 ContextName +=
"." +
D.getNameAsString();
251 if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&
D])
270 llvm::Constant *
Init =
nullptr;
273 Init = llvm::UndefValue::get(LTy);
277 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
279 nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
280 GV->setAlignment(
getContext().getDeclAlign(&
D).getAsAlign());
283 GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
293 llvm::Constant *Addr = GV;
294 if (AS != ExpectedAS) {
296 *
this, GV, AS, ExpectedAS,
298 getContext().getTargetAddressSpace(ExpectedAS)));
309 if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC)) {
317 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
319 else if (
const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
321 else if (
const auto *FD = dyn_cast<FunctionDecl>(DC))
326 assert(isa<ObjCMethodDecl>(DC) &&
"unexpected parent code decl");
341llvm::GlobalVariable *
343 llvm::GlobalVariable *GV) {
345 llvm::Constant *
Init = emitter.tryEmitForInitializer(
D);
357 GV->setConstant(
false);
371 assert(VarSize == CstSize &&
"Emitted constant has unexpected size");
378 D.getType().isConstantStorage(
getContext(),
true, !NeedsDtor));
379 GV->replaceInitializer(
Init);
381 emitter.finalize(GV);
394 llvm::GlobalValue::LinkageTypes
Linkage) {
404 setAddrOfLocalVar(&
D,
Address(addr, elemTy, alignment));
409 if (
D.getType()->isVariablyModifiedType())
413 llvm::Type *expectedType = addr->getType();
415 llvm::GlobalVariable *
var =
416 cast<llvm::GlobalVariable>(addr->stripPointerCasts());
425 if (
D.getInit() && !isCudaSharedVar)
433 if (
auto *SA =
D.
getAttr<PragmaClangBSSSectionAttr>())
434 var->addAttribute(
"bss-section", SA->getName());
435 if (
auto *SA =
D.
getAttr<PragmaClangDataSectionAttr>())
436 var->addAttribute(
"data-section", SA->getName());
437 if (
auto *SA =
D.
getAttr<PragmaClangRodataSectionAttr>())
438 var->addAttribute(
"rodata-section", SA->getName());
439 if (
auto *SA =
D.
getAttr<PragmaClangRelroSectionAttr>())
440 var->addAttribute(
"relro-section", SA->getName());
442 if (
const SectionAttr *SA =
D.
getAttr<SectionAttr>())
443 var->setSection(SA->getName());
458 llvm::Constant *castedAddr =
459 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
460 LocalDeclMap.find(&
D)->second =
Address(castedAddr, elemTy, alignment);
476 CodeGenFunction::Destroyer *destroyer,
477 bool useEHCleanupForArray)
478 : addr(addr),
type(
type), destroyer(destroyer),
479 useEHCleanupForArray(useEHCleanupForArray) {}
483 CodeGenFunction::Destroyer *destroyer;
484 bool useEHCleanupForArray;
488 bool useEHCleanupForArray =
489 flags.isForNormalCleanup() && this->useEHCleanupForArray;
495 template <
class Derived>
498 : NRVOFlag(NRVOFlag),
Loc(addr), Ty(
type) {}
500 llvm::Value *NRVOFlag;
506 bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
508 llvm::BasicBlock *SkipDtorBB =
nullptr;
513 llvm::Value *DidNRVO =
515 CGF.
Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
519 static_cast<Derived *
>(
this)->emitDestructorCall(CGF);
524 virtual ~DestroyNRVOVariable() =
default;
527 struct DestroyNRVOVariableCXX final
528 : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
531 : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr,
type, NRVOFlag),
543 struct DestroyNRVOVariableC final
544 : DestroyNRVOVariable<DestroyNRVOVariableC> {
546 : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
555 CallStackRestore(
Address Stack) : Stack(Stack) {}
556 bool isRedundantBeforeReturn()
override {
return true; }
564 std::pair<llvm::Value *, llvm::Value *> AddrSizePair;
565 KmpcAllocFree(
const std::pair<llvm::Value *, llvm::Value *> &AddrSizePair)
566 : AddrSizePair(AddrSizePair) {}
575 ExtendGCLifetime(
const VarDecl *var) : Var(*
var) {}
589 llvm::Constant *CleanupFn;
593 CallCleanupFunction(llvm::Constant *CleanupFn,
const CGFunctionInfo *Info,
595 : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
630 llvm_unreachable(
"present but none");
638 (var.hasAttr<ObjCPreciseLifetimeAttr>()
643 CGF.
pushDestroy(cleanupKind, addr, var.getType(), destroyer,
662 if (
const Expr *e = dyn_cast<Expr>(
s)) {
665 s = e = e->IgnoreParenCasts();
667 if (
const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e))
668 return (ref->getDecl() == &var);
669 if (
const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
670 const BlockDecl *block = be->getBlockDecl();
671 for (
const auto &I : block->
captures()) {
672 if (I.getVariable() == &var)
678 for (
const Stmt *SubStmt :
s->children())
687 if (!
decl)
return false;
688 if (!isa<VarDecl>(
decl))
return false;
695 bool needsCast =
false;
702 case CK_BlockPointerToObjCPointerCast:
708 case CK_LValueToRValue: {
750 if (!
SanOpts.
has(SanitizerKind::NullabilityAssign))
759 SanitizerScope SanScope(
this);
761 llvm::Constant *StaticData[] = {
763 llvm::ConstantInt::get(
Int8Ty, 0),
766 SanitizerHandler::TypeMismatch, StaticData, RHS);
770 LValue lvalue,
bool capturedByInit) {
782 init = DIE->getExpr();
786 if (
auto *EWC = dyn_cast<ExprWithCleanups>(init)) {
787 CodeGenFunction::RunCleanupsScope
Scope(*
this);
795 bool accessedByInit =
false;
798 if (accessedByInit) {
801 if (capturedByInit) {
822 llvm::Value *value =
nullptr;
826 llvm_unreachable(
"present but none");
829 if (!
D || !isa<VarDecl>(
D) || !cast<VarDecl>(
D)->isARCPseudoStrong()) {
888 unsigned &NumStores) {
890 if (isa<llvm::ConstantAggregateZero>(
Init) ||
891 isa<llvm::ConstantPointerNull>(
Init) ||
892 isa<llvm::UndefValue>(
Init))
894 if (isa<llvm::ConstantInt>(
Init) || isa<llvm::ConstantFP>(
Init) ||
895 isa<llvm::ConstantVector>(
Init) || isa<llvm::BlockAddress>(
Init) ||
896 isa<llvm::ConstantExpr>(
Init))
897 return Init->isNullValue() || NumStores--;
900 if (isa<llvm::ConstantArray>(
Init) || isa<llvm::ConstantStruct>(
Init)) {
901 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
902 llvm::Constant *Elt = cast<llvm::Constant>(
Init->getOperand(i));
909 if (llvm::ConstantDataSequential *CDS =
910 dyn_cast<llvm::ConstantDataSequential>(
Init)) {
911 for (
unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
912 llvm::Constant *Elt = CDS->getElementAsConstant(i);
929 assert(!
Init->isNullValue() && !isa<llvm::UndefValue>(
Init) &&
930 "called emitStoresForInitAfterBZero for zero or undef value.");
932 if (isa<llvm::ConstantInt>(
Init) || isa<llvm::ConstantFP>(
Init) ||
933 isa<llvm::ConstantVector>(
Init) || isa<llvm::BlockAddress>(
Init) ||
934 isa<llvm::ConstantExpr>(
Init)) {
935 auto *I = Builder.CreateStore(
Init,
Loc, isVolatile);
937 I->addAnnotationMetadata(
"auto-init");
941 if (llvm::ConstantDataSequential *CDS =
942 dyn_cast<llvm::ConstantDataSequential>(
Init)) {
943 for (
unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
944 llvm::Constant *Elt = CDS->getElementAsConstant(i);
947 if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
949 CGM, Elt, Builder.CreateConstInBoundsGEP2_32(
Loc, 0, i), isVolatile,
950 Builder, IsAutoInit);
955 assert((isa<llvm::ConstantStruct>(
Init) || isa<llvm::ConstantArray>(
Init)) &&
956 "Unknown value type!");
958 for (
unsigned i = 0, e =
Init->getNumOperands(); i != e; ++i) {
959 llvm::Constant *Elt = cast<llvm::Constant>(
Init->getOperand(i));
962 if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
964 Builder.CreateConstInBoundsGEP2_32(
Loc, 0, i),
965 isVolatile, Builder, IsAutoInit);
973 uint64_t GlobalSize) {
975 if (isa<llvm::ConstantAggregateZero>(
Init))
return true;
981 unsigned StoreBudget = 6;
982 uint64_t SizeLimit = 32;
984 return GlobalSize > SizeLimit &&
995 const llvm::DataLayout &DL) {
996 uint64_t SizeLimit = 32;
997 if (GlobalSize <= SizeLimit)
999 return llvm::isBytewiseValue(
Init, DL);
1006 uint64_t GlobalByteSize) {
1008 uint64_t ByteSizeLimit = 64;
1011 if (GlobalByteSize <= ByteSizeLimit)
1021 if (isPattern == IsPattern::Yes)
1024 return llvm::Constant::getNullValue(Ty);
1028 llvm::Constant *constant);
1033 llvm::StructType *STy,
1034 llvm::Constant *constant) {
1036 const llvm::StructLayout *Layout = DL.getStructLayout(STy);
1037 llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.
getLLVMContext());
1038 unsigned SizeSoFar = 0;
1040 bool NestedIntact =
true;
1041 for (
unsigned i = 0, e = STy->getNumElements(); i != e; i++) {
1042 unsigned CurOff = Layout->getElementOffset(i);
1043 if (SizeSoFar < CurOff) {
1044 assert(!STy->isPacked());
1045 auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar);
1048 llvm::Constant *CurOp;
1049 if (constant->isZeroValue())
1050 CurOp = llvm::Constant::getNullValue(STy->getElementType(i));
1052 CurOp = cast<llvm::Constant>(constant->getAggregateElement(i));
1055 NestedIntact =
false;
1056 Values.push_back(NewOp);
1057 SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType());
1059 unsigned TotalSize = Layout->getSizeInBytes();
1060 if (SizeSoFar < TotalSize) {
1061 auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar);
1064 if (NestedIntact && Values.size() == STy->getNumElements())
1066 return llvm::ConstantStruct::getAnon(Values, STy->isPacked());
1072 llvm::Constant *constant) {
1073 llvm::Type *OrigTy = constant->getType();
1074 if (
const auto STy = dyn_cast<llvm::StructType>(OrigTy))
1076 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(OrigTy)) {
1078 uint64_t Size = ArrayTy->getNumElements();
1081 llvm::Type *ElemTy = ArrayTy->getElementType();
1082 bool ZeroInitializer = constant->isNullValue();
1083 llvm::Constant *OpValue, *PaddedOp;
1084 if (ZeroInitializer) {
1085 OpValue = llvm::Constant::getNullValue(ElemTy);
1088 for (
unsigned Op = 0; Op != Size; ++Op) {
1089 if (!ZeroInitializer) {
1090 OpValue = constant->getAggregateElement(Op);
1093 Values.push_back(PaddedOp);
1095 auto *NewElemTy = Values[0]->getType();
1096 if (NewElemTy == ElemTy)
1098 auto *NewArrayTy = llvm::ArrayType::get(NewElemTy, Size);
1099 return llvm::ConstantArray::get(NewArrayTy, Values);
1108 llvm::Constant *Constant,
1110 auto FunctionName = [&](
const DeclContext *DC) -> std::string {
1111 if (
const auto *FD = dyn_cast<FunctionDecl>(DC)) {
1112 if (
const auto *CC = dyn_cast<CXXConstructorDecl>(FD))
1113 return CC->getNameAsString();
1114 if (
const auto *CD = dyn_cast<CXXDestructorDecl>(FD))
1115 return CD->getNameAsString();
1117 }
else if (
const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) {
1118 return OM->getNameAsString();
1119 }
else if (isa<BlockDecl>(DC)) {
1121 }
else if (isa<CapturedDecl>(DC)) {
1122 return "<captured>";
1124 llvm_unreachable(
"expected a function or method");
1130 llvm::GlobalVariable *&CacheEntry = InitializerConstants[&
D];
1131 if (!CacheEntry || CacheEntry->getInitializer() != Constant) {
1132 auto *Ty = Constant->getType();
1133 bool isConstant =
true;
1134 llvm::GlobalVariable *InsertBefore =
nullptr;
1138 if (
D.hasGlobalStorage())
1141 Name = (
"__const." + FunctionName(DC) +
"." +
D.getName()).str();
1143 llvm_unreachable(
"local variable has no parent function or method");
1144 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
1145 getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
1146 Constant, Name, InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
1148 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1150 }
else if (CacheEntry->getAlignment() < uint64_t(Align.
getQuantity())) {
1151 CacheEntry->setAlignment(Align.
getAsAlign());
1154 return Address(CacheEntry, CacheEntry->getValueType(), Align);
1160 llvm::Constant *Constant,
1169 llvm::Constant *constant,
bool IsAutoInit) {
1170 auto *Ty = constant->getType();
1171 uint64_t ConstantSize = CGM.
getDataLayout().getTypeAllocSize(Ty);
1175 bool canDoSingleStore = Ty->isIntOrIntVectorTy() ||
1176 Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy();
1177 if (canDoSingleStore) {
1178 auto *I = Builder.CreateStore(constant,
Loc, isVolatile);
1180 I->addAnnotationMetadata(
"auto-init");
1184 auto *SizeVal = llvm::ConstantInt::get(CGM.
IntPtrTy, ConstantSize);
1189 auto *I = Builder.CreateMemSet(
Loc, llvm::ConstantInt::get(CGM.
Int8Ty, 0),
1190 SizeVal, isVolatile);
1192 I->addAnnotationMetadata(
"auto-init");
1194 bool valueAlreadyCorrect =
1195 constant->isNullValue() || isa<llvm::UndefValue>(constant);
1196 if (!valueAlreadyCorrect) {
1197 Loc =
Loc.withElementType(Ty);
1205 llvm::Value *Pattern =
1208 uint64_t
Value = 0x00;
1209 if (!isa<llvm::UndefValue>(Pattern)) {
1210 const llvm::APInt &AP = cast<llvm::ConstantInt>(Pattern)->getValue();
1211 assert(AP.getBitWidth() <= 8);
1212 Value = AP.getLimitedValue();
1214 auto *I = Builder.CreateMemSet(
1215 Loc, llvm::ConstantInt::get(CGM.
Int8Ty,
Value), SizeVal, isVolatile);
1217 I->addAnnotationMetadata(
"auto-init");
1223 bool IsTrivialAutoVarInitPattern =
1227 if (
auto *STy = dyn_cast<llvm::StructType>(Ty)) {
1228 if (STy ==
Loc.getElementType() ||
1229 (STy !=
Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
1230 const llvm::StructLayout *Layout =
1232 for (
unsigned i = 0; i != constant->getNumOperands(); i++) {
1235 Address EltPtr = Builder.CreateConstInBoundsByteGEP(
1236 Loc.withElementType(CGM.
Int8Ty), CurOff);
1238 constant->getAggregateElement(i), IsAutoInit);
1242 }
else if (
auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) {
1243 if (ATy ==
Loc.getElementType() ||
1244 (ATy !=
Loc.getElementType() && IsTrivialAutoVarInitPattern)) {
1245 for (
unsigned i = 0; i != ATy->getNumElements(); i++) {
1246 Address EltPtr = Builder.CreateConstGEP(
1247 Loc.withElementType(ATy->getElementType()), i);
1249 constant->getAggregateElement(i), IsAutoInit);
1258 Builder.CreateMemCpy(
Loc,
1260 CGM,
D, Builder, constant,
Loc.getAlignment()),
1261 SizeVal, isVolatile);
1263 I->addAnnotationMetadata(
"auto-init");
1269 llvm::Type *ElTy =
Loc.getElementType();
1270 llvm::Constant *constant =
1279 llvm::Type *ElTy =
Loc.getElementType();
1282 assert(!isa<llvm::UndefValue>(constant));
1288 auto *Ty = constant->getType();
1289 if (isa<llvm::UndefValue>(constant))
1291 if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())
1292 for (llvm::Use &Op : constant->operands())
1299 llvm::Constant *constant) {
1300 auto *Ty = constant->getType();
1301 if (isa<llvm::UndefValue>(constant))
1303 if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
1308 for (
unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
1309 auto *OpValue = cast<llvm::Constant>(constant->getOperand(Op));
1312 if (Ty->isStructTy())
1313 return llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Values);
1314 if (Ty->isArrayTy())
1315 return llvm::ConstantArray::get(cast<llvm::ArrayType>(Ty), Values);
1316 assert(Ty->isVectorTy());
1317 return llvm::ConstantVector::get(Values);
1333 llvm::Value *Addr) {
1334 if (!ShouldEmitLifetimeMarkers)
1337 assert(Addr->getType()->getPointerAddressSpace() ==
1339 "Pointer should be in alloca address space");
1340 llvm::Value *SizeV = llvm::ConstantInt::get(
1344 C->setDoesNotThrow();
1349 assert(Addr->getType()->getPointerAddressSpace() ==
1351 "Pointer should be in alloca address space");
1354 C->setDoesNotThrow();
1366 while (
getContext().getAsVariableArrayType(Type1D)) {
1368 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1372 Twine Name = Twine(
"__vla_expr") + Twine(VLAExprCounter++);
1374 StringRef NameRef = Name.toStringRef(Buffer);
1376 VLAExprNames.push_back(&Ident);
1380 Dimensions.emplace_back(SizeExprAddr.getPointer(),
1383 Type1D = VlaSize.Type;
1392 unsigned NameIdx = 0;
1393 for (
auto &VlaSize : Dimensions) {
1395 if (
auto *
C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1396 MD = llvm::ConstantAsMetadata::get(
C);
1401 SizeTy->getScalarSizeInBits(),
false);
1406 ArtificialDecl->setImplicit();
1411 assert(MD &&
"No Size expression debug node created");
1418CodeGenFunction::AutoVarEmission
1425 AutoVarEmission emission(
D);
1427 bool isEscapingByRef =
D.isEscapingByref();
1428 emission.IsEscapingByRef = isEscapingByRef;
1450 bool NRVO =
getLangOpts().ElideConstructors &&
D.isNRVOVariable();
1453 address = OpenMPLocalAddr;
1454 AllocaAddr = OpenMPLocalAddr;
1467 getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) &&
1468 D.getInit()->isConstantInitializer(
getContext(),
false)))) {
1486 assert(emission.wasEmittedAsGlobal());
1491 emission.IsConstantAggregate =
true;
1509 const auto *RD = RecordTy->getDecl();
1510 const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1511 if ((CXXRD && !CXXRD->hasTrivialDestructor()) ||
1512 RD->isNonTrivialToPrimitiveDestroy()) {
1529 llvm::Type *allocaTy;
1530 if (isEscapingByRef) {
1532 allocaTy = byrefInfo.Type;
1533 allocaAlignment = byrefInfo.ByrefAlignment;
1536 allocaAlignment = alignment;
1543 nullptr, &AllocaAddr);
1548 bool IsMSCatchParam =
1570 emission.SizeForLifetimeMarkers =
1574 assert(!emission.useLifetimeMarkers());
1585 bool VarAllocated =
false;
1588 if (RT.isDelayedVariableLengthDecl(*
this, &
D)) {
1590 std::pair<llvm::Value *, llvm::Value *> AddrSizePair =
1597 address =
Base.getAddress();
1605 VarAllocated =
true;
1609 if (!VarAllocated) {
1610 if (!DidCallStackSave) {
1615 llvm::Value *
V =
Builder.CreateStackSave();
1619 DidCallStackSave =
true;
1640 setAddrOfLocalVar(&
D, address);
1641 emission.Addr = address;
1642 emission.AllocaAddr = AllocaAddr;
1651 if (UsePointerValue) {
1663 if (emission.useLifetimeMarkers())
1665 emission.getOriginalAllocatedAddress(),
1666 emission.getSizeForLifetimeMarkers());
1676 if (
const Expr *
E = dyn_cast<Expr>(S))
1678 for (
const Stmt *SubStmt : S->children())
1691 if (
const BlockExpr *BE = dyn_cast<BlockExpr>(
E)) {
1693 for (
const auto &I :
Block->captures()) {
1694 if (I.getVariable() == &Var)
1702 if (
const StmtExpr *SE = dyn_cast<StmtExpr>(
E)) {
1704 for (
const auto *BI : CS->
body())
1705 if (
const auto *BIE = dyn_cast<Expr>(BI)) {
1709 else if (
const auto *DS = dyn_cast<DeclStmt>(BI)) {
1711 for (
const auto *I : DS->decls()) {
1712 if (
const auto *VD = dyn_cast<VarDecl>((I))) {
1743 !Construct->requiresZeroInitialization())
1749void CodeGenFunction::emitZeroOrPatternForAutoVarInit(
QualType type,
1753 auto trivialAutoVarInitMaxSize =
1756 bool isVolatile =
type.isVolatileQualified();
1757 if (!
Size.isZero()) {
1764 switch (trivialAutoVarInit) {
1766 llvm_unreachable(
"Uninitialized handled by caller");
1770 if (trivialAutoVarInitMaxSize > 0 &&
1771 allocSize > trivialAutoVarInitMaxSize)
1778 if (trivialAutoVarInitMaxSize > 0 &&
1779 allocSize > trivialAutoVarInitMaxSize)
1796 auto SizeVal = VlaSize.NumElts;
1798 switch (trivialAutoVarInit) {
1800 llvm_unreachable(
"Uninitialized handled by caller");
1805 if (!EltSize.
isOne())
1808 SizeVal, isVolatile);
1809 I->addAnnotationMetadata(
"auto-init");
1816 llvm::Type *ElTy =
Loc.getElementType();
1823 llvm::Value *IsZeroSizedVLA =
Builder.CreateICmpEQ(
1824 SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0),
1826 Builder.CreateCondBr(IsZeroSizedVLA, ContBB, SetupBB);
1828 if (!EltSize.
isOne())
1830 llvm::Value *BaseSizeInChars =
1834 Begin.emitRawPointer(*
this),
1835 SizeVal,
"vla.end");
1836 llvm::BasicBlock *OriginBB =
Builder.GetInsertBlock();
1838 llvm::PHINode *Cur =
Builder.CreatePHI(
Begin.getType(), 2,
"vla.cur");
1839 Cur->addIncoming(
Begin.emitRawPointer(*
this), OriginBB);
1840 CharUnits CurAlign =
Loc.getAlignment().alignmentOfArrayElement(EltSize);
1845 BaseSizeInChars, isVolatile);
1846 I->addAnnotationMetadata(
"auto-init");
1849 llvm::Value *Done =
Builder.CreateICmpEQ(Next, End,
"vla-init.isdone");
1850 Builder.CreateCondBr(Done, ContBB, LoopBB);
1851 Cur->addIncoming(Next, LoopBB);
1858 assert(emission.Variable &&
"emission was not valid!");
1861 if (emission.wasEmittedAsGlobal())
return;
1863 const VarDecl &
D = *emission.Variable;
1881 if (emission.IsEscapingByRef)
1888 type.isNonTrivialToPrimitiveDefaultInitialize() ==
1891 if (emission.IsEscapingByRef)
1900 bool capturedByInit =
1903 bool locIsByrefHeader = !capturedByInit;
1905 locIsByrefHeader ? emission.getObjectAddress(*
this) : emission.Addr;
1907 auto hasNoTrivialAutoVarInitAttr = [&](
const Decl *
D) {
1908 return D &&
D->
hasAttr<NoTrivialAutoVarInitAttr>();
1912 ((
D.isConstexpr() ||
D.
getAttr<UninitializedAttr>() ||
1913 hasNoTrivialAutoVarInitAttr(
type->getAsTagDecl()) ||
1918 auto initializeWhatIsTechnicallyUninitialized = [&](
Address Loc) {
1919 if (trivialAutoVarInit ==
1924 if (emission.IsEscapingByRef && !locIsByrefHeader)
1927 return emitZeroOrPatternForAutoVarInit(
type,
D,
Loc);
1931 return initializeWhatIsTechnicallyUninitialized(
Loc);
1933 llvm::Constant *constant =
nullptr;
1934 if (emission.IsConstantAggregate ||
1935 D.mightBeUsableInConstantExpressions(
getContext())) {
1936 assert(!capturedByInit &&
"constant init contains a capturing block?");
1938 if (constant && !constant->isZeroValue() &&
1939 (trivialAutoVarInit !=
1955 if (constant &&
type->isBitIntType() &&
1960 llvm::Type *LoadType =
1962 constant = llvm::ConstantFoldLoadFromConst(
1968 if (trivialAutoVarInit !=
1979 initializeWhatIsTechnicallyUninitialized(
Loc);
1989 if (!emission.IsConstantAggregate) {
2012 LValue lvalue,
bool capturedByInit) {
2015 if (
type->isReferenceType()) {
2034 if (
type->isAtomicType()) {
2038 if (isa<VarDecl>(
D))
2040 else if (
auto *FD = dyn_cast<FieldDecl>(
D))
2050 llvm_unreachable(
"bad evaluation kind");
2055 const CodeGenFunction::AutoVarEmission &emission,
2061 Address addr = emission.getObjectAddress(*
this);
2071 llvm_unreachable(
"no cleanup for trivially-destructible variable");
2076 if (emission.NRVOFlag) {
2077 assert(!
type->isArrayType());
2079 EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr,
type, dtor,
2087 if (
var->isARCPseudoStrong())
return;
2093 if (!
var->hasAttr<ObjCPreciseLifetimeAttr>())
2102 if (emission.NRVOFlag) {
2103 assert(!
type->isArrayType());
2104 EHStack.pushCleanup<DestroyNRVOVariableC>(cleanupKind, addr,
2105 emission.NRVOFlag,
type);
2116 bool useEHCleanup = (cleanupKind &
EHCleanup);
2117 EHStack.pushCleanup<DestroyObject>(cleanupKind, addr,
type, destroyer,
2122 assert(emission.Variable &&
"emission was not valid!");
2125 if (emission.wasEmittedAsGlobal())
return;
2131 const VarDecl &
D = *emission.Variable;
2139 D.
hasAttr<ObjCPreciseLifetimeAttr>()) {
2144 if (
const CleanupAttr *CA =
D.
getAttr<CleanupAttr>()) {
2148 assert(F &&
"Could not find function!");
2157 if (emission.IsEscapingByRef &&
2160 if (emission.Variable->getType().isObjCGCWeak())
2181 llvm_unreachable(
"Unknown DestructionKind");
2188 assert(dtorKind &&
"cannot push destructor for trivial type");
2198 assert(dtorKind &&
"cannot push destructor for trivial type");
2207 bool useEHCleanupForArray) {
2208 pushFullExprCleanup<DestroyObject>(cleanupKind, addr,
type,
2209 destroyer, useEHCleanupForArray);
2216 assert(dtorKind &&
"cannot push destructor for trivial type");
2225 bool useEHCleanupForArray) {
2226 llvm::Instruction *DominatingIP =
2228 pushDestroy(cleanupKind, addr,
type, destroyer, useEHCleanupForArray);
2234 EHStack.pushCleanup<CallStackRestore>(
Kind, SPMem);
2238 CleanupKind Kind, std::pair<llvm::Value *, llvm::Value *> AddrSizePair) {
2239 EHStack.pushCleanup<KmpcAllocFree>(
Kind, AddrSizePair);
2244 Destroyer *destroyer,
2245 bool useEHCleanupForArray) {
2255 useEHCleanupForArray);
2259 return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>(
2261 useEHCleanupForArray);
2266 using ConditionalCleanupType =
2273 AllocaTrackerRAII DeactivationAllocas(*
this);
2276 pushCleanupAndDeferDeactivation<ConditionalCleanupType>(
2277 cleanupKind, SavedAddr,
type, destroyer, useEHCleanupForArray);
2281 cleanup.AddAuxAllocas(std::move(DeactivationAllocas).Take());
2289 pushCleanupAfterFullExprWithActiveFlag<ConditionalCleanupType>(
2290 cleanupKind, ActiveFlagForLifetimeExt, SavedAddr,
type, destroyer,
2291 useEHCleanupForArray);
2306 Destroyer *destroyer,
2307 bool useEHCleanupForArray) {
2310 return destroyer(*
this, addr,
type);
2319 bool checkZeroLength =
true;
2322 if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(
length)) {
2324 if (constLength->isZero())
return;
2325 checkZeroLength =
false;
2332 checkZeroLength, useEHCleanupForArray);
2349 Destroyer *destroyer,
2350 bool checkZeroLength,
2351 bool useEHCleanup) {
2359 if (checkZeroLength) {
2360 llvm::Value *isEmpty =
Builder.CreateICmpEQ(begin, end,
2361 "arraydestroy.isempty");
2362 Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
2366 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2368 llvm::PHINode *elementPast =
2369 Builder.CreatePHI(begin->getType(), 2,
"arraydestroy.elementPast");
2370 elementPast->addIncoming(end, entryBB);
2373 llvm::Value *negativeOne = llvm::ConstantInt::get(
SizeTy, -1,
true);
2376 llvmElementType, elementPast, negativeOne,
"arraydestroy.element");
2383 destroyer(*
this,
Address(element, llvmElementType, elementAlign),
2390 llvm::Value *done =
Builder.CreateICmpEQ(element, begin,
"arraydestroy.done");
2391 Builder.CreateCondBr(done, doneBB, bodyBB);
2392 elementPast->addIncoming(element,
Builder.GetInsertBlock());
2401 llvm::Value *begin, llvm::Value *end,
2407 unsigned arrayDepth = 0;
2416 llvm::Value *zero = llvm::ConstantInt::get(CGF.
SizeTy, 0);
2420 elemTy, begin, gepIndices,
"pad.arraybegin");
2422 elemTy, end, gepIndices,
"pad.arrayend");
2437 llvm::Value *ArrayBegin;
2438 llvm::Value *ArrayEnd;
2440 CodeGenFunction::Destroyer *Destroyer;
2443 RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
2445 CodeGenFunction::Destroyer *destroyer)
2446 : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
2447 ElementType(elementType), Destroyer(destroyer),
2448 ElementAlign(elementAlign) {}
2452 ElementType, ElementAlign, Destroyer);
2460 llvm::Value *ArrayBegin;
2463 CodeGenFunction::Destroyer *Destroyer;
2466 IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
2470 CodeGenFunction::Destroyer *destroyer)
2471 : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
2472 ElementType(elementType), Destroyer(destroyer),
2473 ElementAlign(elementAlign) {}
2478 ElementType, ElementAlign, Destroyer);
2493 Destroyer *destroyer) {
2494 pushFullExprCleanup<IrregularPartialArrayDestroy>(
2496 elementAlign, destroyer);
2506 llvm::Value *arrayEnd,
2509 Destroyer *destroyer) {
2510 pushFullExprCleanup<RegularPartialArrayDestroy>(
EHCleanup,
2511 arrayBegin, arrayEnd,
2512 elementType, elementAlign,
2518 if (LifetimeStartFn)
2519 return LifetimeStartFn;
2520 LifetimeStartFn = llvm::Intrinsic::getOrInsertDeclaration(
2522 return LifetimeStartFn;
2528 return LifetimeEndFn;
2529 LifetimeEndFn = llvm::Intrinsic::getOrInsertDeclaration(
2531 return LifetimeEndFn;
2540 ConsumeARCParameter(llvm::Value *param,
2542 : Param(param), Precise(precise) {}
2557 bool NoDebugInfo =
false;
2559 assert((isa<ParmVarDecl>(
D) || isa<ImplicitParamDecl>(
D)) &&
2560 "Invalid argument to EmitParmDecl");
2564 if (!isa<llvm::GlobalValue>(Arg.getAnyValue()))
2565 Arg.getAnyValue()->setName(
D.getName());
2570 if (
auto IPD = dyn_cast<ImplicitParamDecl>(&
D)) {
2574 llvm::Value *
V = Arg.isIndirect()
2576 : Arg.getDirectValue();
2588 bool DoStore =
false;
2590 bool UseIndirectDebugAddress =
false;
2593 if (Arg.isIndirect()) {
2594 DeclPtr = Arg.getIndirectAddress();
2607 if (UseIndirectDebugAddress) {
2610 D.getName() +
".indirect_addr");
2617 if (SrcLangAS != DestLangAS) {
2618 assert(
getContext().getTargetAddressSpace(SrcLangAS) ==
2624 *
this,
V, SrcLangAS, DestLangAS,
T,
true),
2637 "unexpected destructor type");
2639 CalleeDestructedParamCleanups[cast<ParmVarDecl>(&
D)] =
2650 DeclPtr = OpenMPLocalAddr;
2651 AllocaPtr = DeclPtr;
2655 D.getName() +
".addr", &AllocaPtr);
2660 llvm::Value *ArgVal = (DoStore ? Arg.getDirectValue() :
nullptr);
2670 bool isConsumed =
D.
hasAttr<NSConsumedAttr>();
2673 if (
D.isARCPseudoStrong()) {
2675 "pseudo-strong variable isn't strong?");
2676 assert(qs.
hasConst() &&
"pseudo-strong variable should be const!");
2681 if (Arg.isIndirect() && !ArgVal)
2725 setAddrOfLocalVar(&
D, DeclPtr);
2733 if (
const auto *Var = dyn_cast_or_null<ParmVarDecl>(&
D))
2744 if (requiresReturnValueNullabilityCheck()) {
2747 SanitizerScope SanScope(
this);
2748 RetValNullabilityPrecondition =
2749 Builder.CreateAnd(RetValNullabilityPrecondition,
2750 Builder.CreateIsNotNull(Arg.getAnyValue()));
2757 if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !
D->
isUsed()))
2764 if (!LangOpts.OpenMP || LangOpts.OpenMPSimd ||
2765 (!LangOpts.EmitAllDecls && !
D->
isUsed()))
2775 for (
const Expr *
E :
D->varlist()) {
2776 const auto *DE = cast<DeclRefExpr>(
E);
2777 const auto *VD = cast<VarDecl>(DE->getDecl());
2800 if (Entry->getType()->getAddressSpace() == TargetAS)
2805 llvm::PointerType *PTy = llvm::PointerType::get(Ty, TargetAS);
2810 llvm::GlobalVariable *DummyGV =
new llvm::GlobalVariable(
2811 getModule(), Entry->getValueType(),
false,
2812 llvm::GlobalValue::CommonLinkage,
nullptr,
"dummy",
nullptr,
2813 llvm::GlobalVariable::NotThreadLocal, Entry->getAddressSpace());
2814 Entry->replaceAllUsesWith(DummyGV);
2816 Entry->mutateType(PTy);
2817 llvm::Constant *NewPtrForOldDecl =
2818 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
2819 Entry, DummyGV->getType());
2823 DummyGV->replaceAllUsesWith(NewPtrForOldDecl);
2824 DummyGV->eraseFromParent();
2828std::optional<CharUnits>
2830 if (
const auto *AA = VD->
getAttr<OMPAllocateDeclAttr>()) {
2831 if (
Expr *Alignment = AA->getAlignment()) {
2832 unsigned UserAlign =
2833 Alignment->EvaluateKnownConstInt(
getContext()).getExtValue();
2841 std::max<unsigned>(UserAlign, NaturalAlign.
getQuantity()));
2844 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)
__device__ __2f16 float __ockl_bool s
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
unsigned getTargetAddressSpace(LangAS AS) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
ArrayRef< Capture > captures() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
A use of a default initializer in a constructor or in aggregate initialization.
Represents a C++ destructor within a class.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
bool getIndirectByVal() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
KnownNonNull_t isKnownNonNull() const
Whether the pointer is known not to be null.
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl)
Emit information about a global variable.
Param2DILocTy & getParamDbgMappings()
llvm::DILocalVariable * EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder, bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an argument variable declaration.
llvm::DILocalVariable * EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI, CGBuilderTy &Builder, const bool UsePointerValue=false)
Emit call to llvm.dbg.declare for an automatic variable declaration.
void setLocation(SourceLocation Loc)
Update the current source location.
void registerVLASizeExpression(QualType Ty, llvm::Metadata *SizeExpr)
Register VLA size expression debug node with the qualified type.
CGFunctionInfo - Class to encapsulate the information about a function definition.
const_arg_iterator arg_begin() const
MutableArrayRef< ArgInfo > arguments()
virtual void EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF, const VarDecl &D)
Emit the IR required for a work-group-local variable declaration, and add an entry to CGF's LocalDecl...
Allows to disable automatic handling of functions used in target regions as those marked as omp decla...
virtual void getKmpcFreeShared(CodeGenFunction &CGF, const std::pair< llvm::Value *, llvm::Value * > &AddrSizePair)
Get call to __kmpc_free_shared.
void emitUserDefinedMapper(const OMPDeclareMapperDecl *D, CodeGenFunction *CGF=nullptr)
Emit the function for the user defined mapper construct.
virtual void processRequiresDirective(const OMPRequiresDecl *D)
Perform check on requires decl to ensure that target architecture supports unified addressing.
virtual std::pair< llvm::Value *, llvm::Value * > getKmpcAllocShared(CodeGenFunction &CGF, const VarDecl *VD)
Get call to __kmpc_alloc_shared.
virtual void emitUserDefinedReduction(CodeGenFunction *CGF, const OMPDeclareReductionDecl *D)
Emit code for the specified user defined reduction construct.
virtual Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void emitAutoVarTypeCleanup(const AutoVarEmission &emission, QualType::DestructionKind dtorKind)
void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, bool LoadBlockVarAddr, bool CanThrow)
Enter a cleanup to destroy a __block variable.
llvm::Value * EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr)
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
static Destroyer destroyNonTrivialCStruct
static bool cxxDestructorCanThrow(QualType T)
Check if T is a C++ class that has a destructor that can throw.
SanitizerSet SanOpts
Sanitizers enabled for this function.
RawAddress createCleanupActiveFlag()
llvm::DenseMap< const VarDecl *, llvm::Value * > NRVOFlags
A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...
void EmitARCMoveWeak(Address dst, Address src)
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
static bool hasScalarEvaluationKind(QualType T)
const BlockByrefInfo & getBlockByrefInfo(const VarDecl *var)
void EmitDecl(const Decl &D)
EmitDecl - Emit a declaration.
void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
CleanupKind getARCCleanupKind()
Retrieves the default cleanup kind for an ARC cleanup.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitExtendGCLifetime(llvm::Value *object)
EmitExtendGCLifetime - Given a pointer to an Objective-C object, make sure it survives garbage collec...
llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind, Address addr, QualType type)
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
const CodeGen::CGBlockInfo * BlockInfo
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
void emitByrefStructureInit(const AutoVarEmission &emission)
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
@ TCK_NonnullAssign
Checking the value assigned to a _Nonnull pointer. Must not be null.
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitARCUnsafeUnretainedScalarExpr(const Expr *expr)
void EmitAutoVarInit(const AutoVarEmission &emission)
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
DominatingValue< T >::saved_type saveValueInCond(T value)
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
static Destroyer destroyCXXObject
void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)
Emit local annotations for the local variable V, declared by D.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitAtomicInit(Expr *E, LValue lvalue)
const TargetInfo & getTarget() const
bool isInConditionalBranch() const
isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)
Emit code in this function to perform a guarded variable initialization.
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
void initFullExprCleanupWithFlag(RawAddress ActiveFlag)
void EmitARCCopyWeak(Address dst, Address src)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr)
void defaultInitNonTrivialCStructVar(LValue Dst)
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
bool isTrivialInitializer(const Expr *Init)
Determine whether the given initializer is trivial in the sense that it requires no code to be genera...
CGDebugInfo * getDebugInfo()
Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, bool followForward=true)
BuildBlockByrefAddress - Computes the location of the data in a variable which is declared as __block...
LValue EmitDeclRefLValue(const DeclRefExpr *E)
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
llvm::Value * EmitARCRetainAutoreleaseScalarExpr(const Expr *expr)
const TargetCodeGenInfo & getTargetHooks() const
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
Address ReturnValuePointer
ReturnValuePointer - The temporary alloca to hold a pointer to sret.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
llvm::GlobalVariable * AddInitializerToStaticVarDecl(const VarDecl &D, llvm::GlobalVariable *GV)
AddInitializerToStaticVarDecl - Add the initializer for 'D' to the global variable that has already b...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
static Destroyer destroyARCWeak
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertType(QualType T)
void EmitARCInitWeak(Address addr, llvm::Value *value)
static Destroyer destroyARCStrongPrecise
VarBypassDetector Bypasses
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
void pushStackRestore(CleanupKind kind, Address SPMem)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const CGFunctionInfo * CurFnInfo
void pushKmpcAllocFree(CleanupKind Kind, std::pair< llvm::Value *, llvm::Value * > AddrSizePair)
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
static Destroyer destroyARCStrongImprecise
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo)
Emits the alloca and debug information for the size expressions for each dimension of an array.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
bool hasLabelBeenSeenInCurrentScope() const
Return true if a label was seen in the current scope.
This class organizes the cross-function state that is used while generating LLVM code.
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD)
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::Module & getModule() const
void setStaticLocalDeclAddress(const VarDecl *D, llvm::Constant *C)
llvm::Function * getLLVMLifetimeStartFn()
Lazily declare the @llvm.lifetime.start intrinsic.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant, CharUnits Align)
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
CGOpenCLRuntime & getOpenCLRuntime()
Return a reference to the configured OpenCL runtime.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
void EmitOMPAllocateDecl(const OMPAllocateDecl *D)
Emit a code for the allocate directive.
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)
Returns LLVM linkage for a declarator.
const llvm::DataLayout & getDataLayout() const
void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
SanitizerMetadata * getSanitizerMetadata()
llvm::Constant * getOrCreateStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV)
Add global annotations that are set on D, for the global GV.
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const
Set the TLS mode for the given LLVM GlobalValue for the thread-local variable declaration D.
ASTContext & getContext() const
void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, CodeGenFunction *CGF=nullptr)
Emit a code for declare mapper construct.
llvm::Function * getLLVMLifetimeEndFn()
Lazily declare the @llvm.lifetime.end intrinsic.
bool supportsCOMDAT() const
void EmitOMPRequiresDecl(const OMPRequiresDecl *D)
Emit a code for requires directive.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
std::optional< CharUnits > getOMPAllocateAlignment(const VarDecl *VD)
Return the alignment specified in an allocate directive, if present.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, CodeGenFunction *CGF=nullptr)
Emit a code for declare reduction construct.
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
void markStmtMaybeUsed(const Stmt *S)
llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)
Given that T is a scalar type, return the IR type that should be used for load and store operations.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool typeRequiresSplitIntoByteArray(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
Check whether the given type needs to be laid out in memory using an opaque byte-array type because i...
const CGFunctionInfo & arrangeFunctionDeclaration(const FunctionDecl *FD)
Free functions are functions that are compatible with an ordinary C function pointer type.
llvm::Constant * tryEmitAbstractForInitializer(const VarDecl &D)
Try to emit the initializer of the given declaration as an abstract constant.
A cleanup scope which generates the cleanup blocks lazily.
Information for lazily generating a cleanup.
ConditionalCleanup stores the saved form of its parameters, then restores them and performs the clean...
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
LValue - This represents an lvalue references.
llvm::Value * getPointer(CodeGenFunction &CGF) const
Address getAddress() const
void setNonGC(bool Value)
void setAddress(Address address)
Qualifiers::ObjCLifetime getObjCLifetime() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
An abstract representation of an aligned address.
llvm::Value * getPointer() const
static RawAddress invalid()
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
bool IsBypassed(const VarDecl *D) const
Returns true if the variable declaration was by bypassed by any goto or switch statement.
CompoundStmt - This represents a group of statements like { stmt stmt }.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks,...
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & getOwn(StringRef Name)
Gets an IdentifierInfo for the given name without consulting external sources.
This represents '#pragma omp allocate ...' directive.
This represents '#pragma omp declare mapper ...' directive.
This represents '#pragma omp declare reduction ...' directive.
This represents '#pragma omp requires...' directive.
A (possibly-)qualified type.
@ DK_objc_strong_lifetime
@ PDIK_Struct
The type is a struct containing a field whose type is not PCK_Trivial.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
bool isParamDestroyedInCallee() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
static const uint64_t MaximumAlignment
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
const T * castAs() const
Member-template castAs<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 hasGlobalStorage() const
Returns true for all variables that do not have local storage.
const Expr * getInit() const
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Defines the clang::TargetInfo interface.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Constant * initializationPatternFor(CodeGenModule &, llvm::Type *)
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
ARCPreciseLifetime_t
Does an ARC strong l-value have precise lifetime?
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
constexpr Variable var(Literal L)
Returns the variable of L.
bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Descriptor *Desc)
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Ctor_Base
Base object ctor.
@ NonNull
Values of this type can never be null.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ SD_Automatic
Automatic storage duration (most local variables).
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
@ ThreadPrivateVar
Parameter for Thread private variable.
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
static Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)
Gets the OpenMP-specific address of the local variable /p VD.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
llvm::PointerType * AllocaInt8PtrTy
LangAS getASTAllocaAddressSpace() const
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.