29#include "llvm/IR/Intrinsics.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/Support/SaveAndRestore.h"
32#include "llvm/Transforms/Utils/SanitizerStats.h"
36using namespace CodeGen;
52 return layout.getNonVirtualAlignment();
84 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
97 return std::min(actualBaseAlign, expectedTargetAlign);
100 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
120 if (actualBaseAlign >= expectedBaseAlign) {
121 return expectedTargetAlign;
127 return std::min(actualBaseAlign, expectedTargetAlign);
131 assert(
CurFuncDecl &&
"loading 'this' without a func declaration?");
135 if (CXXThisAlignment.
isZero()) {
142 llvm::Type *Ty =
ConvertType(MD->getFunctionObjectParameterType());
151 llvm::Value *memberPtr,
158 memberPtr, memberPtrType);
181 assert(!
Base->isVirtual() &&
"Should not see virtual bases here!");
186 const auto *BaseDecl =
202 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
212 return llvm::ConstantInt::get(
PtrDiffTy, Offset.getQuantity());
224 bool BaseIsVirtual) {
226 assert(This.getElementType() ==
ConvertType(Derived));
239 if (!Offset.isZero()) {
249 llvm::Value *virtualOffset,
253 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
256 llvm::Value *baseOffset;
257 if (!nonVirtualOffset.
isZero()) {
258 llvm::Type *OffsetType =
264 llvm::ConstantInt::get(OffsetType, nonVirtualOffset.
getQuantity());
266 baseOffset = CGF.
Builder.CreateAdd(virtualOffset, baseOffset);
269 baseOffset = virtualOffset;
274 ptr = CGF.
Builder.CreateInBoundsGEP(CGF.
Int8Ty, ptr, baseOffset,
"add.ptr");
280 assert(nearestVBase &&
"virtual offset without vbase?");
282 derivedClass, nearestVBase);
296 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
305 if ((*Start)->isVirtual()) {
306 VBase = cast<CXXRecordDecl>(
315 VBase ? VBase : Derived, Start, PathEnd);
320 if (VBase && Derived->hasAttr<FinalAttr>()) {
323 NonVirtualOffset += vBaseOffset;
328 llvm::Type *BaseValueTy =
ConvertType((PathEnd[-1])->getType());
329 llvm::Type *PtrTy = llvm::PointerType::get(
337 if (NonVirtualOffset.
isZero() && !VBase) {
340 SkippedChecks.
set(SanitizerKind::Null, !NullCheckValue);
342 DerivedTy, DerivedAlign, SkippedChecks);
344 return Value.withElementType(BaseValueTy);
347 llvm::BasicBlock *origBB =
nullptr;
348 llvm::BasicBlock *endBB =
nullptr;
352 if (NullCheckValue) {
353 origBB =
Builder.GetInsertBlock();
357 llvm::Value *isNull =
Builder.CreateIsNull(
Value.getPointer());
358 Builder.CreateCondBr(isNull, endBB, notNullBB);
364 SkippedChecks.
set(SanitizerKind::Null,
true);
366 Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks);
370 llvm::Value *VirtualOffset =
nullptr;
378 VirtualOffset, Derived, VBase);
384 if (NullCheckValue) {
385 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
389 llvm::PHINode *PHI =
Builder.CreatePHI(PtrTy, 2,
"cast.result");
390 PHI->addIncoming(
Value.getPointer(), notNullBB);
391 PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB);
403 bool NullCheckValue) {
404 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
408 llvm::Type *DerivedValueTy =
ConvertType(DerivedTy);
410 llvm::Value *NonVirtualOffset =
413 if (!NonVirtualOffset) {
418 llvm::BasicBlock *CastNull =
nullptr;
419 llvm::BasicBlock *CastNotNull =
nullptr;
420 llvm::BasicBlock *CastEnd =
nullptr;
422 if (NullCheckValue) {
438 if (NullCheckValue) {
445 PHI->addIncoming(
Value, CastNotNull);
446 PHI->addIncoming(llvm::Constant::getNullValue(
Value->
getType()), CastNull);
469 }
else if (RD ==
Base) {
473 "doing no-op VTT offset in base dtor/ctor?");
474 assert(!ForVirtualBase &&
"Can't have same class as virtual base!");
484 assert(SubVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
494 return Builder.CreateConstInBoundsGEP2_64(
495 VTT->getValueType(), VTT, 0, SubVTTIndex);
505 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
517 DerivedClass, BaseClass,
520 false, Addr, ThisTy);
538 void VisitCXXThisExpr(
const CXXThisExpr *E) { UsesThis =
true; }
543 DynamicThisUseChecker Checker(
C);
545 return Checker.UsesThis;
552 "Must have base initializer!");
557 const auto *BaseClassDecl =
585 !BaseClassDecl->hasTrivialDestructor())
591 auto *CD = dyn_cast<CXXConstructorDecl>(D);
592 if (!(CD && CD->isCopyOrMoveConstructor()) &&
614 for (
const auto *I : IndirectField->
chain())
628 "Must have member initializer!");
629 assert(MemberInit->
getInit() &&
"Must have initializer!");
633 QualType FieldType = Field->getType();
655 if (Array && Constructor->isDefaulted() &&
656 Constructor->isCopyOrMoveConstructor()) {
661 unsigned SrcArgIndex =
776 struct SizeAndOffset {
790 size_t NumFields = 0;
791 for (
const auto *Field : ClassDecl->
fields()) {
795 assert(NumFields < SSV.size());
799 assert(NumFields == SSV.size());
800 if (SSV.size() <= 1)
return;
805 llvm::FunctionType *FTy =
806 llvm::FunctionType::get(
CGM.
VoidTy, Args,
false);
808 FTy, Prologue ?
"__asan_poison_intra_object_redzone"
809 :
"__asan_unpoison_intra_object_redzone");
816 for (
size_t i = 0; i < SSV.size(); i++) {
818 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
819 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
820 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
821 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
822 (NextField % AsanAlignment) != 0)
825 F, {
Builder.CreateAdd(ThisPtr,
Builder.getIntN(PtrSize, EndOffset)),
826 Builder.getIntN(PtrSize, PoisonSize)});
838 "can only generate complete ctor for this ABI");
850 assert(
Definition == Ctor &&
"emitting wrong constructor body");
854 bool IsTryBody = (Body && isa<CXXTryStmt>(Body));
860 RunCleanupsScope RunCleanups(*
this);
871 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
879 RunCleanups.ForceCleanup();
890 class CopyingValueRepresentation {
893 : CGF(CGF), OldSanOpts(CGF.SanOpts) {
897 ~CopyingValueRepresentation() {
907 class FieldMemcpyizer {
911 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
912 RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
913 FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0),
914 LastFieldOffset(0), LastAddedFieldIndex(0) {}
916 bool isMemcpyableField(
FieldDecl *F)
const {
935 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
937 unsigned LastFieldSize =
938 LastField->isBitField()
939 ? LastField->getBitWidthValue(Ctx)
942 uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
956 if (FirstField->isBitField()) {
964 FirstByteOffset = FirstFieldOffset;
967 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
984 FirstField =
nullptr;
1001 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
1002 LastFieldOffset = FirstFieldOffset;
1012 "Cannot aggregate fields out of order.");
1019 if (FOffset < FirstFieldOffset) {
1021 FirstFieldOffset = FOffset;
1022 }
else if (FOffset >= LastFieldOffset) {
1024 LastFieldOffset = FOffset;
1032 uint64_t FirstFieldOffset, LastFieldOffset;
1033 unsigned LastAddedFieldIndex;
1036 class ConstructorMemcpyizer :
public FieldMemcpyizer {
1051 if (!MemcpyableCtor)
1054 assert(Field &&
"No field for member init.");
1065 if (!isMemcpyableField(Field))
1075 : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)),
1076 ConstructorDecl(CD),
1077 MemcpyableCtor(CD->isDefaulted() &&
1078 CD->isCopyOrMoveConstructor() &&
1083 if (isMemberInitMemcpyable(MemberInit)) {
1084 AggregatedInits.push_back(MemberInit);
1085 addMemcpyableField(MemberInit->
getMember());
1087 emitAggregatedInits();
1089 ConstructorDecl, Args);
1093 void emitAggregatedInits() {
1094 if (AggregatedInits.size() <= 1) {
1097 if (!AggregatedInits.empty()) {
1098 CopyingValueRepresentation CVR(CGF);
1100 AggregatedInits[0], ConstructorDecl, Args);
1101 AggregatedInits.clear();
1107 pushEHDestructors();
1109 AggregatedInits.clear();
1112 void pushEHDestructors() {
1117 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1130 emitAggregatedInits();
1135 bool MemcpyableCtor;
1140 class AssignmentMemcpyizer :
public FieldMemcpyizer {
1145 if (!AssignmentsMemcpyable)
1149 if (BO->getOpcode() != BO_Assign)
1151 MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
1155 if (!Field || !isMemcpyableField(Field))
1157 Stmt *RHS = BO->getRHS();
1159 RHS = EC->getSubExpr();
1162 if (
MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
1163 if (ME2->getMemberDecl() == Field)
1168 CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
1171 MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
1175 if (!Field || !isMemcpyableField(Field))
1177 MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
1178 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1181 }
else if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
1182 FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1183 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1187 DstPtr = DC->getSubExpr();
1189 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1195 if (!Field || !isMemcpyableField(Field))
1199 SrcPtr = SC->getSubExpr();
1201 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1204 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1212 bool AssignmentsMemcpyable;
1218 : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
1219 AssignmentsMemcpyable(CGF.getLangOpts().getGC() ==
LangOptions::NonGC) {
1220 assert(Args.size() == 2);
1223 void emitAssignment(
Stmt *S) {
1226 addMemcpyableField(F);
1227 AggregatedStmts.push_back(S);
1229 emitAggregatedStmts();
1234 void emitAggregatedStmts() {
1235 if (AggregatedStmts.size() <= 1) {
1236 if (!AggregatedStmts.empty()) {
1237 CopyingValueRepresentation CVR(CGF);
1244 AggregatedStmts.clear();
1248 emitAggregatedStmts();
1255 const auto *BaseClassDecl =
1257 return BaseClassDecl->isDynamicClass();
1280 bool ConstructVBases = CtorType !=
Ctor_Base &&
1287 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1288 if (ConstructVBases &&
1290 BaseCtorContinueBB =
1292 assert(BaseCtorContinueBB);
1295 for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
1296 if (!ConstructVBases)
1306 if (BaseCtorContinueBB) {
1308 Builder.CreateBr(BaseCtorContinueBB);
1313 for (; B != E && (*B)->isBaseInitializer(); B++) {
1314 assert(!(*B)->isBaseVirtual());
1327 ConstructorMemcpyizer CM(*
this, CD, Args);
1328 for (; B != E; B++) {
1330 assert(!
Member->isBaseInitializer());
1331 assert(
Member->isAnyMemberInitializer() &&
1332 "Delegating initializer on non-delegating constructor");
1333 CM.addMemberInitializer(
Member);
1354 for (
const auto *Field : BaseClassDecl->
fields())
1359 for (
const auto &I : BaseClassDecl->
bases()) {
1366 MostDerivedClassDecl))
1370 if (BaseClassDecl == MostDerivedClassDecl) {
1372 for (
const auto &I : BaseClassDecl->
vbases()) {
1376 MostDerivedClassDecl))
1420 for (
const auto *Field : ClassDecl->
fields())
1438 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
1439 TrapCall->setDoesNotReturn();
1440 TrapCall->setDoesNotThrow();
1442 Builder.ClearInsertionPoint();
1455 RunCleanupsScope DtorEpilogue(*
this);
1467 bool isTryBody = (Body && isa<CXXTryStmt>(Body));
1473 RunCleanupsScope DtorEpilogue(*
this);
1481 case Dtor_Comdat: llvm_unreachable(
"not expecting a COMDAT");
1482 case Dtor_Deleting: llvm_unreachable(
"already handled deleting case");
1485 assert((Body ||
getTarget().getCXXABI().isMicrosoft()) &&
1486 "can't emit a dtor without a body for non-Microsoft ABIs");
1518 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
1522 assert(Dtor->
isImplicit() &&
"bodyless dtor not implicit");
1528 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1534 DtorEpilogue.ForceCleanup();
1544 assert(isa<CompoundStmt>(RootS) &&
1545 "Body of an implicit assignment operator should be compound stmt.");
1546 const CompoundStmt *RootCS = cast<CompoundStmt>(RootS);
1551 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1552 for (
auto *I : RootCS->
body())
1553 AM.emitAssignment(I);
1573 LoadThisForDtorDelete(CGF, Dtor),
1579 llvm::Value *ShouldDeleteCondition,
1580 bool ReturnAfterDelete) {
1583 llvm::Value *ShouldCallDelete
1584 = CGF.
Builder.CreateIsNull(ShouldDeleteCondition);
1585 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1591 LoadThisForDtorDelete(CGF, Dtor),
1594 ReturnAfterDelete &&
1595 "unexpected value for ReturnAfterDelete");
1596 if (ReturnAfterDelete)
1599 CGF.
Builder.CreateBr(continueBB);
1605 llvm::Value *ShouldDeleteCondition;
1608 CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
1609 : ShouldDeleteCondition(ShouldDeleteCondition) {
1610 assert(ShouldDeleteCondition !=
nullptr);
1614 EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1621 CodeGenFunction::Destroyer *destroyer;
1622 bool useEHCleanupForArray;
1625 DestroyField(
const FieldDecl *field, CodeGenFunction::Destroyer *destroyer,
1626 bool useEHCleanupForArray)
1627 : field(field), destroyer(destroyer),
1628 useEHCleanupForArray(useEHCleanupForArray) {}
1639 flags.isForNormalCleanup() && useEHCleanupForArray);
1643 class DeclAsInlineDebugLocation {
1645 llvm::MDNode *InlinedAt;
1646 std::optional<ApplyDebugLocation> Location;
1650 : DI(CGF.getDebugInfo()) {
1658 ~DeclAsInlineDebugLocation() {
1666 static void EmitSanitizerDtorCallback(
1668 std::optional<CharUnits::QuantityType> PoisonSize = {}) {
1669 CodeGenFunction::SanitizerScope SanScope(&CGF);
1675 if (PoisonSize.has_value()) {
1676 Args.emplace_back(llvm::ConstantInt::get(CGF.
SizeTy, *PoisonSize));
1677 ArgTypes.emplace_back(CGF.
SizeTy);
1680 llvm::FunctionType *FnType =
1681 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1688 EmitSanitizerDtorFieldsCallback(
CodeGenFunction &CGF, llvm::Value *Ptr,
1690 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_fields", Ptr,
1699 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
1717 DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass);
1718 EmitSanitizerDtorFieldsCallback(CGF, Addr.
getPointer(),
1722 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1728 unsigned StartIndex;
1734 : Dtor(Dtor), StartIndex(StartIndex), EndIndex(EndIndex) {}
1748 llvm::ConstantInt *OffsetSizePtr =
1751 llvm::Value *OffsetPtr =
1761 CharUnits PoisonSize = PoisonEnd - PoisonStart;
1766 DeclAsInlineDebugLocation InlineHere(
1767 CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex));
1768 EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.
getQuantity());
1771 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1783 assert(Dtor->getParent()->isDynamicClass());
1790 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_vptr",
1795 class SanitizeDtorCleanupBuilder {
1799 std::optional<unsigned> StartIndex;
1804 : Context(Context), EHStack(EHStack), DD(DD), StartIndex(
std::nullopt) {}
1805 void PushCleanupForField(
const FieldDecl *Field) {
1806 if (
Field->isZeroSize(Context))
1808 unsigned FieldIndex =
Field->getFieldIndex();
1811 StartIndex = FieldIndex;
1812 }
else if (StartIndex) {
1814 *StartIndex, FieldIndex);
1815 StartIndex = std::nullopt;
1835 "Should not emit dtor epilogue for non-exported trivial dtor!");
1841 "operator delete missing - EnterDtorCleanups");
1842 if (CXXStructorImplicitParamValue) {
1846 EmitConditionalDtorDeleteCall(*
this, CXXStructorImplicitParamValue,
1849 EHStack.pushCleanup<CallDtorDeleteConditional>(
1855 LoadThisForDtorDelete(*
this, DD),
1882 for (
const auto &
Base : ClassDecl->
vbases()) {
1883 auto *BaseClassDecl =
1886 if (BaseClassDecl->hasTrivialDestructor()) {
1891 SanOpts.
has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty())
1913 for (
const auto &
Base : ClassDecl->
bases()) {
1915 if (
Base.isVirtual())
1939 for (
const auto *Field : ClassDecl->
fields()) {
1941 SanitizeBuilder.PushCleanupForField(Field);
1954 EHStack.pushCleanup<DestroyField>(
1959 SanitizeBuilder.End();
1973 bool zeroInitialize) {
1975 llvm::Value *numElements =
1979 NewPointerIsChecked, zeroInitialize);
1992 llvm::Value *numElements,
1995 bool NewPointerIsChecked,
1996 bool zeroInitialize) {
2002 llvm::BranchInst *zeroCheckBranch =
nullptr;
2005 llvm::ConstantInt *constantCount
2006 = dyn_cast<llvm::ConstantInt>(numElements);
2007 if (constantCount) {
2009 if (constantCount->isZero())
return;
2014 llvm::Value *iszero =
Builder.CreateIsNull(numElements,
"isempty");
2015 zeroCheckBranch =
Builder.CreateCondBr(iszero, loopBB, loopBB);
2021 llvm::Value *arrayBegin = arrayBase.
getPointer();
2022 llvm::Value *arrayEnd =
Builder.CreateInBoundsGEP(
2023 elementType, arrayBegin, numElements,
"arrayctor.end");
2026 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2029 llvm::PHINode *cur =
Builder.CreatePHI(arrayBegin->getType(), 2,
2031 cur->addIncoming(arrayBegin, entryBB);
2060 RunCleanupsScope
Scope(*
this);
2081 llvm::Value *next =
Builder.CreateInBoundsGEP(
2082 elementType, cur, llvm::ConstantInt::get(
SizeTy, 1),
"arrayctor.next");
2083 cur->addIncoming(next,
Builder.GetInsertBlock());
2086 llvm::Value *done =
Builder.CreateICmpEQ(next, arrayEnd,
"arrayctor.done");
2088 Builder.CreateCondBr(done, contBB, loopBB);
2091 if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
2109 bool ForVirtualBase,
2117 llvm::Value *ThisPtr =
This.getPointer();
2119 if (SlotAS != ThisAS) {
2121 llvm::Type *NewType =
2124 ThisAS, SlotAS, NewType);
2134 assert(E->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2183 bool ForVirtualBase,
2189 bool NewPointerIsChecked) {
2192 if (!NewPointerIsChecked)
2197 assert(Args.size() == 1 &&
"trivial default ctor with args");
2205 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2217 bool PassPrototypeArgs =
true;
2265 if (InheritedFromVBase &&
2271 Args.push_back(ThisArg);
2272 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2274 assert(CXXInheritedCtorInitExprArgs.size() >= D->
getNumParams() &&
2275 "wrong number of parameters for inherited constructor call");
2276 Args = CXXInheritedCtorInitExprArgs;
2280 Args.push_back(ThisArg);
2281 const auto *OuterCtor = cast<CXXConstructorDecl>(
CurCodeDecl);
2282 assert(OuterCtor->getNumParams() == D->
getNumParams());
2283 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2285 for (
const auto *Param : OuterCtor->parameters()) {
2287 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2292 if (Param->hasAttr<PassObjectSizeAttr>()) {
2293 auto *POSParam = SizeArguments[Param];
2294 assert(POSParam &&
"missing pass_object_size value for forwarding");
2309 InlinedInheritingConstructorScope
Scope(*
this, GD);
2311 RunCleanupsScope RunCleanups(*
this);
2314 CXXInheritedCtorInitExprArgs = Args;
2325 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2326 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
2327 if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) {
2328 const RValue &RV = Args[I].getRValue(*
this);
2329 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2332 : ParamValue::forIndirect(RV.getAggregateAddress());
2344 CXXThisValue = CXXABIThisValue;
2351 llvm::Value *VTableGlobal =
2357 CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset();
2359 if (!NonVirtualOffset.
isZero())
2362 Vptr.VTableClass, Vptr.NearestVBase);
2364 llvm::Value *VPtrValue =
2365 GetVTablePtr(This, VTableGlobal->getType(), Vptr.VTableClass);
2367 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2368 Builder.CreateAssumption(Cmp);
2412 FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
2413 assert(I != E &&
"no parameters to constructor");
2423 assert(I != E &&
"cannot skip vtt parameter, already done with args");
2424 assert((*I)->getType()->isPointerType() &&
2425 "skipping parameter not of vtt type");
2430 for (; I != E; ++I) {
2437 true, This, DelegateArgs,
2450 : Dtor(D), Addr(Addr),
Type(
Type) {}
2455 QualType ThisTy = Dtor->getFunctionObjectParameterType();
2457 true, Addr, ThisTy);
2494 bool ForVirtualBase,
2508 : Dtor(D), Addr(Addr), Ty(Ty) {}
2525 if (!ClassDecl)
return;
2529 assert(D && D->
isUsed() &&
"destructor not marked as used!");
2535 llvm::Value *VTableAddressPoint =
2537 *
this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase);
2539 if (!VTableAddressPoint)
2543 llvm::Value *VirtualOffset =
nullptr;
2552 NonVirtualOffset = Vptr.OffsetFromNearestVBase;
2555 NonVirtualOffset = Vptr.Base.getBaseOffset();
2560 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2562 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.VTableClass,
2588 false, VTableClass, VBases,
2596 bool BaseIsNonVirtualPrimaryBase,
2598 VisitedVirtualBasesSetTy &VBases,
2599 VPtrsVector &Vptrs) {
2602 if (!BaseIsNonVirtualPrimaryBase) {
2604 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2605 Vptrs.push_back(Vptr);
2611 for (
const auto &I : RD->
bases()) {
2616 if (!BaseDecl->isDynamicClass())
2621 bool BaseDeclIsNonVirtualPrimaryBase;
2623 if (I.isVirtual()) {
2625 if (!VBases.insert(BaseDecl).second)
2633 BaseDeclIsNonVirtualPrimaryBase =
false;
2638 BaseOffsetFromNearestVBase =
2640 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2645 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2646 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2665 llvm::Type *VTableTy,
2667 Address VTablePtrSrc =
This.withElementType(VTableTy);
2704 if (isa<CXXDestructorDecl>(MD) && MD->
isImplicit())
2715 llvm::Value *VTable,
2725 llvm::Value *TypeId =
2733 ? llvm::Intrinsic::type_test
2734 : llvm::Intrinsic::public_type_test;
2735 llvm::Value *TypeTest =
2742 llvm::Value *VTable,
2743 CFITypeCheckKind TCK,
2745 if (!
SanOpts.
has(SanitizerKind::CFICastStrict))
2753 CFITypeCheckKind TCK,
2762 const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl());
2767 if (!
SanOpts.
has(SanitizerKind::CFICastStrict))
2770 llvm::BasicBlock *ContBlock =
nullptr;
2773 llvm::Value *DerivedNotNull =
2779 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
2784 llvm::Value *VTable;
2785 std::tie(VTable, ClassDecl) =
2797 llvm::Value *VTable,
2798 CFITypeCheckKind TCK,
2805 llvm::SanitizerStatKind SSK;
2808 M = SanitizerKind::CFIVCall;
2809 SSK = llvm::SanStat_CFI_VCall;
2812 M = SanitizerKind::CFINVCall;
2813 SSK = llvm::SanStat_CFI_NVCall;
2816 M = SanitizerKind::CFIDerivedCast;
2817 SSK = llvm::SanStat_CFI_DerivedCast;
2820 M = SanitizerKind::CFIUnrelatedCast;
2821 SSK = llvm::SanStat_CFI_UnrelatedCast;
2826 llvm_unreachable(
"unexpected sanitizer kind");
2830 if (
getContext().getNoSanitizeList().containsType(M, TypeName))
2833 SanitizerScope SanScope(
this);
2836 llvm::Metadata *MD =
2838 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
2840 llvm::Value *TypeTest =
Builder.CreateCall(
2843 llvm::Constant *StaticData[] = {
2844 llvm::ConstantInt::get(
Int8Ty, TCK),
2860 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
2863 llvm::Value *ValidVtable =
Builder.CreateCall(
2865 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
2866 StaticData, {VTable, ValidVtable});
2887 const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
2888 uint64_t VTableByteOffset) {
2889 SanitizerScope SanScope(
this);
2893 llvm::Metadata *MD =
2897 llvm::Value *CheckedLoad =
Builder.CreateCall(
2899 {VTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), TypeId});
2900 llvm::Value *CheckResult =
Builder.CreateExtractValue(CheckedLoad, 1);
2904 !
getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
2906 EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall),
2907 SanitizerHandler::CFICheckFail, {}, {});
2910 return Builder.CreateBitCast(
Builder.CreateExtractValue(CheckedLoad, 0),
2931 if (!resultType->isVoidType() &&
2944 RValue RV =
EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
2947 if (!resultType->isVoidType() && returnSlot.
isNull()) {
2948 if (
getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
2951 EmitReturnOfRValue(RV, resultType);
2982 "generic lambda interconversion to block not implemented");
3022 void *InsertPos =
nullptr;
3025 assert(CorrespondingCallOpSpecialization);
3026 CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
3030 if (hasInAllocaArg(MD)) {
3032 llvm::Function *ImplFn =
nullptr;
3054 llvm::Value *ThisArg =
CurFn->getArg(0);
3062 llvm::Function **ImplFn) {
3065 llvm::Function *CallOpFn =
3072 ArgTypes.push_back(I->type);
3082 StringRef CallOpName = CallOpFn->getName();
3083 std::string ImplName;
3084 if (
size_t Pos = CallOpName.find_first_of(
"<lambda"))
3085 ImplName = (
"?__impl@" + CallOpName.drop_front(Pos)).str();
3087 ImplName = (
"__impl" + CallOpName).str();
3089 llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
3092 llvm::GlobalValue::InternalLinkage, ImplName,
3097 const auto *D = cast<FunctionDecl>(GD.
getDecl());
static Address ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, CharUnits nonVirtualOffset, llvm::Value *virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase)
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, const CXXConstructorDecl *Ctor, CXXCtorType Type, CallArgList &Args)
static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor)
CanSkipVTablePointerInitialization - Check whether we need to initialize any vtable pointers before c...
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit)
static const CXXRecordDecl * LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD)
static void EmitBaseInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *BaseInit)
static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D)
static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init)
static bool FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field)
static bool HasTrivialDestructorBody(ASTContext &Context, const CXXRecordDecl *BaseClassDecl, const CXXRecordDecl *MostDerivedClassDecl)
static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *MemberInit, const CXXConstructorDecl *Constructor, FunctionArgList &Args)
static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, CXXCtorInitializer *MemberInit, LValue &LHS)
Defines the C++ template declaration subclasses.
static const RecordType * getRecordType(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const NoSanitizeList & getNoSanitizeList() const
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
TypeInfoChars getTypeInfoInChars(const Type *T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a block literal declaration, which is like an unnamed FunctionDecl.
capture_const_iterator capture_begin() const
ArrayRef< ParmVarDecl * > parameters() const
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
Represents a call to a C++ constructor.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
init_iterator init_end()
Retrieve an iterator past the last initializer.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a C++ destructor within a class.
const FunctionDecl * getOperatorDelete() const
Expr * getOperatorDeleteThisArg() const
Represents a call to an inherited base class constructor from an inheriting constructor.
SourceLocation getLocation() const LLVM_READONLY
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
QualType getFunctionObjectParameterType() const
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
method_range methods() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
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...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::Value * getPointer() const
llvm::PointerType * getType() const
Return the type of the pointer value.
bool isSanitizerChecked() const
Address getAddress() 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)
Qualifiers getQualifiers() const
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
Overlap_t mayOverlap() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
A scoped helper to set the current debug location to an inlined location.
const BlockDecl * getBlockDecl() const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateLaunderInvariantGroup(Address Addr)
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateGEP(Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
virtual llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, const CXXRecordDecl *RD)
Emit the code to initialize hidden members required to handle virtual inheritance,...
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
virtual bool NeedsVTTParameter(GlobalDecl GD)
Return whether the given global decl needs a VTT parameter.
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT)
Calculate an l-value from an object and a data member pointer.
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD)
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0
Emit the destructor call.
AddedStructorArgCounts addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, CallArgList &Args)
Add any ABI-specific implicit arguments needed to call a constructor.
All available information about a concrete callee.
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...
llvm::MDNode * getInlinedAt() const
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
FunctionType::ExtInfo getExtInfo() const
ABIArgInfo & getReturnInfo()
const_arg_iterator arg_begin() const
CanQualType getReturnType() const
const_arg_iterator arg_end() const
RequiredArgs getRequiredArgs() const
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
static ParamValue forDirect(llvm::Value *value)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
void EmitDestructorBody(FunctionArgList &Args)
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
void EmitAsanPrologueOrEpilogue(bool Prologue)
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo, llvm::Function **ImplFn)
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, const FunctionArgList &Args, SourceLocation Loc)
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args)
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, CallArgList &CallArgs, const CGFunctionInfo *CallOpFnInfo=nullptr, llvm::Constant *CallOpFn=nullptr)
void EmitVTableAssumptionLoad(const VPtr &vptr, Address This)
Emit assumption that vptr load == global vtable.
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static bool hasScalarEvaluationKind(QualType T)
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)
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...
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool NewPointerIsChecked, bool ZeroInitialization=false)
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool IsVirtual)
Determine whether a base class initialization may overlap some other object.
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 EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
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)
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
const CodeGen::CGBlockInfo * BlockInfo
void EmitAggregateCopyCtor(LValue Dest, LValue Src, AggValueSlot::Overlap_t MayOverlap)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
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...
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E)
Emit a call to a constructor inherited from a base class, passing the current constructor's arguments...
@ TCK_ConstructorCall
Checking the 'this' pointer for a constructor call.
@ TCK_UpcastToVirtualBase
Checking the operand of a cast to a virtual base object.
@ TCK_Upcast
Checking the operand of a cast to a base object.
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,...
VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass)
llvm::Type * ConvertTypeForMem(QualType T)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
static Destroyer destroyCXXObject
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ Default
! No language constraints on evaluation order.
void EmitLambdaBlockInvokeBody()
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
llvm::SmallPtrSet< const CXXRecordDecl *, 4 > VisitedVirtualBasesSetTy
const TargetInfo & getTarget() const
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for RD using llvm....
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...
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, AggValueSlot ThisAVS, const CXXConstructExpr *E)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
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...
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetCodeGenInfo & getTargetHooks() const
void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase, bool Delegating, CallArgList &Args)
Emit a call to an inheriting constructor (that is, one that invokes a constructor inherited from a ba...
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor)
void EmitConstructorBody(FunctionArgList &Args)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This)
Emit assumption load for all bases.
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 Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
Address GetAddressOfBaseClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue, SourceLocation Loc)
GetAddressOfBaseClass - This function will add the necessary delta to the load of 'this' and returns ...
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
Address GetAddressOfDirectBaseInCompleteClass(Address Value, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, bool BaseIsVirtual)
GetAddressOfBaseOfCompleteClass - Convert the given pointer to a complete class to the given direct b...
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertType(QualType T)
Address GetAddrOfBlockDecl(const VarDecl *var)
CodeGenTypes & getTypes() const
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args)
Address LoadCXXThisAddress()
Address CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD, CallArgList &CallArgs)
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond, llvm::ConstantInt *TypeId, llvm::Value *Ptr, ArrayRef< llvm::Constant * > StaticArgs)
Emit a slow path cross-DSO CFI check which calls __cfi_slowpath if Cond if false.
void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type)
EnterDtorCleanups - Enter the cleanups necessary to complete the given phase of destruction for a des...
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs=std::nullopt)
EmitStmt - Emit the code for the statement.
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T)
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 incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::SmallVector< VPtr, 4 > VPtrsVector
void InitializeVTablePointers(const CXXRecordDecl *ClassDecl)
void InitializeVTablePointer(const VPtr &vptr)
Initialize the vtable pointer of the given subobject.
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo)
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
llvm::ConstantInt * CreateCrossDsoCfiTypeId(llvm::Metadata *MD)
Generate a cross-DSO type identifier for MD.
CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD)
Returns the minimum object size for an object of the given class type (or a class derived from it).
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.
void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, const CXXRecordDecl *RD)
Adds !invariant.barrier !tag to instruction.
llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
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()
const TargetInfo & getTarget() const
llvm::Metadata * CreateMetadataIdentifierForType(QualType T)
Create a metadata identifier for the given type.
llvm::Constant * GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd)
Returns the offset from a derived class to a class.
bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)
Returns whether the given record has hidden LTO visibility and therefore may participate in (single-m...
const llvm::DataLayout & getDataLayout() const
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType)
getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an access to a virtual table poi...
CGCXXABI & getCXXABI() const
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD)
Returns whether the given record has public LTO visibility (regardless of -lto-whole-program-visibili...
void DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo)
DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args)
"Arrange" the LLVM information for a call or type with the given signature.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base)
getSubVTTIndex - Return the index of the sub-VTT for the base class of the given record decl.
Information for lazily generating a cleanup.
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
Address getAddress(CodeGenFunction &CGF) const
Address getBitFieldAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
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.
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
bool isZeroSize(const ASTContext &Ctx) const
Determine if this field is a subobject of zero size, that is, either a zero-length bit-field or a fie...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool hasTrivialBody() const
Returns whether the function has a trivial body that does not require any specific codegen.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
bool isVariadic() const
Whether this function prototype is variadic.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
CXXDtorType getDtorType() const
const Decl * getDecl() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
bool isRelativeLayout() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
QualType getPointeeType() const
const Type * getClass() const
This represents a decl that may have a name.
std::string getQualifiedNameAsString() const
bool containsType(SanitizerMask Mask, StringRef MangledTypeName, StringRef Category=StringRef()) const
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
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.
bool hasObjCLifetime() const
LangAS getAddressSpace() const
field_range fields() const
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
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.
Encodes a location in the source.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee? This is a fundamental language change,...
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
const Type * getTypeForDecl() const
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a variable declaration or definition.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
bool This(InterpState &S, CodePtr OpPC)
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
CXXDtorType
C++ destructor types.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
Structure with information about how a bitfield should be accessed.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.