18 #include "llvm/Support/ScopedPrinter.h" 21 using namespace clang;
22 using namespace CodeGen;
33 enum { DstIdx = 0, SrcIdx = 1 };
34 const char *ValNameStr[2] = {
"dst",
"src"};
36 template <
class Derived>
struct StructVisitor {
39 template <
class... Ts>
47 asDerived().visit(FT, FD, CurStructOffset, Args...);
50 asDerived().flushTrivialFields(Args...);
53 template <
class... Ts>
void visitTrivial(Ts... Args) {}
55 template <
class... Ts>
void visitCXXDestructor(Ts... Args) {
56 llvm_unreachable(
"field of a C++ struct type is not expected");
59 template <
class... Ts>
void flushTrivialFields(Ts... Args) {}
61 uint64_t getFieldOffsetInBits(
const FieldDecl *FD) {
71 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
77 template <
class Derived,
bool IsMove>
78 struct CopyStructVisitor : StructVisitor<Derived>,
80 using StructVisitor<Derived>::asDerived;
83 CopyStructVisitor(
ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
85 template <
class... Ts>
90 asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
93 template <
class... Ts>
97 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
99 CurStructOffsset, std::forward<Ts>(Args)...);
103 Super::visitWithKind(PCK, FT, FD, CurStructOffsset,
104 std::forward<Ts>(Args)...);
107 template <
class... Ts>
118 uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
119 uint64_t FEndInBits = FStartInBits + FieldSize;
120 uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
124 Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
125 End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
151 template <
class Derived>
struct GenFuncNameBase {
165 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
172 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
178 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
179 asDerived().visitStructFields(QT, FieldOffset);
182 template <
class FieldKind>
183 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
188 return asDerived().visitTrivial(
QualType(AT, 0), FD, CurStructOffset);
190 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
196 appendStr(
"_AB" + llvm::to_string(FieldOffset.
getQuantity()) +
"s" +
198 llvm::to_string(NumElts));
200 asDerived().visitWithKind(FK, EltTy,
nullptr, FieldOffset);
204 void appendStr(StringRef Str) { Name += Str; }
212 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
217 template <
class Derived>
218 struct GenUnaryFuncName : StructVisitor<Derived>, GenFuncNameBase<Derived> {
220 : StructVisitor<Derived>(Ctx) {
221 this->appendStr(Prefix);
222 this->appendStr(llvm::to_string(DstAlignment.
getQuantity()));
229 return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty));
232 template <
bool IsMove>
233 struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>,
234 GenFuncNameBase<GenBinaryFuncName<IsMove>> {
236 GenBinaryFuncName(StringRef Prefix,
CharUnits DstAlignment,
238 : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>(Ctx) {
239 this->appendStr(Prefix);
240 this->appendStr(llvm::to_string(DstAlignment.
getQuantity()));
241 this->appendStr(
"_" + llvm::to_string(SrcAlignment.
getQuantity()));
244 void flushTrivialFields() {
245 if (this->Start == this->
End)
248 this->appendStr(
"_t" + llvm::to_string(this->Start.getQuantity()) +
"w" +
249 llvm::to_string((this->
End - this->Start).getQuantity()));
258 uint64_t OffsetInBits =
259 this->Ctx.
toBits(CurStackOffset) + this->getFieldOffsetInBits(FD);
260 this->appendStr(
"_tv" + llvm::to_string(OffsetInBits) +
"w" +
265 struct GenDefaultInitializeFuncName
266 : GenUnaryFuncName<GenDefaultInitializeFuncName>,
270 : GenUnaryFuncName<GenDefaultInitializeFuncName>(
"__default_constructor_",
271 DstAlignment, Ctx) {}
274 if (
const auto *AT = getContext().getAsArrayType(FT)) {
279 Super::visitWithKind(PDIK, FT, FD, CurStructOffset);
283 struct GenDestructorFuncName : GenUnaryFuncName<GenDestructorFuncName>,
287 : GenUnaryFuncName<GenDestructorFuncName>(
"__destructor_", DstAlignment,
291 if (
const auto *AT = getContext().getAsArrayType(FT)) {
296 Super::visitWithKind(DK, FT, FD, CurStructOffset);
308 for (
unsigned I = 0; I < N; ++I)
313 for (
auto &
P : Params)
321 template <
class Derived>
struct GenFuncBase {
324 std::array<Address, N> Addrs) {
325 this->asDerived().callSpecialFunction(
329 template <
class FieldKind,
size_t N>
330 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
332 std::array<Address, N> Addrs) {
335 return asDerived().visitTrivial(
QualType(AT, 0), FD, CurStackOffset,
343 std::array<Address, N> StartAddrs = Addrs;
344 for (
unsigned I = 0; I < N; ++I)
345 StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStackOffset, FD);
346 Address DstAddr = StartAddrs[DstIdx];
350 llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
352 CGF.
Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
358 llvm::BasicBlock *PreheaderBB = CGF.
Builder.GetInsertBlock();
363 llvm::PHINode *PHIs[N];
365 for (
unsigned I = 0; I < N; ++I) {
367 PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
377 CGF.
Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd,
"done");
378 CGF.
Builder.CreateCondBr(Done, ExitBB, LoopBB);
384 std::array<Address, N> NewAddrs = Addrs;
386 for (
unsigned I = 0; I < N; ++I)
388 PHIs[I], StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
394 LoopBB = CGF.
Builder.GetInsertBlock();
396 for (
unsigned I = 0; I < N; ++I) {
399 NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
400 PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB);
404 CGF.
Builder.CreateBr(HeaderBB);
410 assert(Addr.
isValid() &&
"invalid address");
413 Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
414 Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.
getQuantity(),
416 return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
421 return getAddrWithOffset(Addr, StructFieldOffset +
427 getFunction(StringRef FuncName,
QualType QT, std::array<Address, N> Addrs,
430 if (llvm::Function *F = CGM.
getModule().getFunction(FuncName)) {
431 bool WrongType =
false;
432 if (!F->getReturnType()->isVoidTy())
435 for (
const llvm::Argument &Arg : F->args())
441 std::string FuncName = F->getName();
443 CGM.
Error(Loc,
"special function " + FuncName +
444 " for non-trivial C struct has incorrect type");
453 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
456 FuncName, &CGM.getModule());
458 CGM.SetLLVMFunctionAttributes(
nullptr, FI, F);
459 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
466 CGF->StartFunction(FD, Ctx.
VoidTy, F, FI, Args);
468 for (
unsigned I = 0; I < N; ++I) {
469 llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
470 Addrs[I] =
Address(V, Alignments[I]);
474 CGF->FinishFunction();
479 void callFunc(StringRef FuncName,
QualType QT, std::array<Address, N> Addrs,
481 std::array<CharUnits, N> Alignments;
484 for (
unsigned I = 0; I < N; ++I) {
485 Alignments[I] = Addrs[I].getAlignment();
491 if (llvm::Function *F =
492 getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.
CGM))
496 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
503 template <
class Derived,
bool IsMove>
504 struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
505 GenFuncBase<Derived> {
506 GenBinaryFunc(
ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
508 void flushTrivialFields(std::array<Address, 2> Addrs) {
514 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
515 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
520 llvm::ConstantInt::get(this->CGF->SizeTy, Size.
getQuantity());
522 this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
524 this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
525 this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal,
false);
528 this->CGF->getLLVMContext(),
529 Size.
getQuantity() * this->CGF->getContext().getCharWidth());
530 DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
531 SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
532 llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr,
false);
533 this->CGF->Builder.CreateStore(SrcVal, DstAddr,
false);
539 template <
class... Ts>
541 std::array<Address, 2> Addrs) {
545 llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
546 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
547 LValue DstBase = this->CGF->MakeAddrLValue(
548 this->CGF->Builder.CreateBitCast(DstAddr, PtrTy), FT);
549 DstLV = this->CGF->EmitLValueForField(DstBase, FD);
550 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
551 LValue SrcBase = this->CGF->MakeAddrLValue(
552 this->CGF->Builder.CreateBitCast(SrcAddr, PtrTy), FT);
553 SrcLV = this->CGF->EmitLValueForField(SrcBase, FD);
555 llvm::PointerType *Ty = this->CGF->ConvertType(FT)->getPointerTo();
556 Address DstAddr = this->CGF->Builder.CreateBitCast(Addrs[DstIdx], Ty);
557 Address SrcAddr = this->CGF->Builder.CreateBitCast(Addrs[SrcIdx], Ty);
558 DstLV = this->CGF->MakeAddrLValue(DstAddr, FT);
559 SrcLV = this->CGF->MakeAddrLValue(SrcAddr, FT);
562 this->CGF->EmitStoreThroughLValue(SrcVal, DstLV);
567 struct GenDestructor : StructVisitor<GenDestructor>,
568 GenFuncBase<GenDestructor>,
571 GenDestructor(
ASTContext &Ctx) : StructVisitor<GenDestructor>(Ctx) {}
575 std::array<Address, 1> Addrs) {
576 if (
const auto *AT = getContext().getAsArrayType(FT)) {
581 Super::visitWithKind(DK, FT, FD, CurStructOffset, Addrs);
585 CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
586 CGF->destroyARCStrongImprecise(
587 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
591 std::array<Address, 1> Addrs) {
593 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
597 std::array<Address, 1> Addrs) {
598 CGF->callCStructDestructor(
599 CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
603 struct GenDefaultInitialize
604 : StructVisitor<GenDefaultInitialize>,
605 GenFuncBase<GenDefaultInitialize>,
608 typedef GenFuncBase<GenDefaultInitialize> GenFuncBaseTy;
611 : StructVisitor<GenDefaultInitialize>(Ctx) {}
615 std::array<Address, 1> Addrs) {
616 if (
const auto *AT = getContext().getAsArrayType(FT)) {
622 Super::visitWithKind(PDIK, FT, FD, CurStructOffset, Addrs);
626 CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
627 CGF->EmitNullInitialization(
628 getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
632 std::array<Address, 1> Addrs) {
633 CGF->EmitNullInitialization(
634 getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
637 template <
class FieldKind,
size_t... Is>
638 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
640 std::array<Address, 1> Addrs) {
642 return visitTrivial(
QualType(AT, 0), FD, CurStackOffset, Addrs);
649 GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStackOffset, Addrs);
653 llvm::Constant *SizeVal = CGF->Builder.getInt64(Size.
getQuantity());
654 Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
655 Address Loc = CGF->Builder.CreateElementBitCast(DstAddr, CGF->Int8Ty);
656 CGF->Builder.CreateMemSet(Loc, CGF->Builder.getInt8(0), SizeVal,
661 std::array<Address, 1> Addrs) {
662 CGF->callCStructDefaultConstructor(
663 CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
667 struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
669 : GenBinaryFunc<GenCopyConstructor, false>(Ctx) {}
672 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
673 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
674 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
678 CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT),
true);
682 std::array<Address, 2> Addrs) {
683 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
684 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
685 CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]);
689 std::array<Address, 2> Addrs) {
690 CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
691 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
695 struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
697 : GenBinaryFunc<GenMoveConstructor, true>(Ctx) {}
700 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
701 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
702 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
703 LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
707 CGF->EmitStoreOfScalar(SrcVal, CGF->MakeAddrLValue(Addrs[DstIdx], QT),
712 std::array<Address, 2> Addrs) {
713 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
714 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
715 CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]);
719 std::array<Address, 2> Addrs) {
720 CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
721 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
725 struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
727 : GenBinaryFunc<GenCopyAssignment, false>(Ctx) {}
730 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
731 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
732 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
735 CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal,
740 std::array<Address, 2> Addrs) {
741 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
742 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
743 CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
747 std::array<Address, 2> Addrs) {
748 CGF->callCStructCopyAssignmentOperator(
749 CGF->MakeAddrLValue(Addrs[DstIdx], FT),
750 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
754 struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
756 : GenBinaryFunc<GenMoveAssignment, true>(Ctx) {}
759 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
760 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
761 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
762 LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
766 LValue DstLV = CGF->MakeAddrLValue(Addrs[DstIdx], QT);
769 CGF->EmitStoreOfScalar(SrcVal, DstLV);
774 std::array<Address, 2> Addrs) {
775 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
776 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
777 CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
781 std::array<Address, 2> Addrs) {
782 CGF->callCStructMoveAssignmentOperator(
783 CGF->MakeAddrLValue(Addrs[DstIdx], FT),
784 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
798 GenDefaultInitialize Gen(getContext());
803 Gen.visit(QT,
nullptr,
CharUnits::Zero(), std::array<Address, 1>({{DstPtr}}));
806 template <
class G,
size_t N>
809 std::array<Address, N> Addrs) {
810 for (
unsigned I = 0; I < N; ++I)
813 Gen.callFunc(FuncName, QT, Addrs, CGF);
821 GenDefaultInitializeFuncName GenName(DstPtr.
getAlignment(), getContext());
822 std::string FuncName = GenName.getName(QT, IsVolatile);
824 IsVolatile, *
this, std::array<Address, 1>({{DstPtr}}));
831 GenDestructorFuncName GenName(DstPtr.
getAlignment(), getContext());
832 std::string FuncName = GenName.getName(QT, IsVolatile);
834 *
this, std::array<Address, 1>({{DstPtr}}));
841 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstPtr.
getAlignment(),
842 SrcPtr.getAlignment(), getContext());
843 std::string FuncName = GenName.getName(QT, IsVolatile);
846 std::array<Address, 2>({{DstPtr, SrcPtr}}));
855 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstPtr.
getAlignment(),
856 SrcPtr.getAlignment(), getContext());
857 std::string FuncName = GenName.getName(QT, IsVolatile);
859 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
866 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstPtr.
getAlignment(),
867 SrcPtr.getAlignment(), getContext());
868 std::string FuncName = GenName.getName(QT, IsVolatile);
871 std::array<Address, 2>({{DstPtr, SrcPtr}}));
880 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstPtr.
getAlignment(),
881 SrcPtr.getAlignment(), getContext());
882 std::string FuncName = GenName.getName(QT, IsVolatile);
884 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
llvm::PointerType * Int8PtrPtrTy
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
Represents a function declaration or definition.
Other implicit parameter.
A (possibly-)qualified type.
bool isBlockPointerType() const
CodeGenTypes & getTypes()
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
const Type * getTypeForDecl() const
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
The base class of the type hierarchy.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Objects with "hidden" visibility are not seen by the dynamic linker.
const T * getAs() const
Member-template getAs<specific type>'.
llvm::Value * getPointer() const
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
Address getAddress() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
field_range fields() const
Represents a member of a struct/union/class.
static uint64_t getFieldSize(const FieldDecl *FD, QualType FT, ASTContext &Ctx)
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
bool isBitField() const
Determines whether this field is a bitfield.
void defaultInitNonTrivialCStructVar(LValue Dst)
CharUnits - This is an opaque type for sizes expressed in character units.
void callCStructDefaultConstructor(LValue Dst)
CharUnits getAlignment() const
Return the alignment of this pointer.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
unsigned getBitWidthValue(const ASTContext &Ctx) const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void callCStructMoveConstructor(LValue Dst, LValue Src)
PrimitiveDefaultInitializeKind
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, bool isConstexprSpecified=false)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
static CharUnits One()
One - Construct a CharUnits quantity of one.
ASTContext & getContext() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)
const T * castAs() const
Member-template castAs<specific type>.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
ASTContext & getContext() const
void callCStructCopyAssignmentOperator(LValue Dst, LValue Src)
The l-value was considered opaque, so the alignment was determined from a type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
static void callSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile, CodeGenFunction &CGF, std::array< Address, N > Addrs)
FunctionArgList - Type for representing both the decl and type of parameters to a function...
QualType withVolatile() const
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
void callCStructDestructor(LValue Dst)
llvm::Module & getModule() const
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
llvm::PointerType * Int8PtrTy
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
static Destroyer destroyNonTrivialCStruct
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
void callCStructCopyConstructor(LValue Dst, LValue Src)
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
TranslationUnitDecl * getTranslationUnitDecl() const
static llvm::Constant * getNullForVariable(Address addr)
Given the address of a variable of pointer type, find the correct null to store into it...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
LValue - This represents an lvalue references.
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...
Represents the canonical version of C arrays with a specified constant size.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.