19#include "llvm/Support/ScopedPrinter.h"
23using namespace CodeGen;
34enum { DstIdx = 0, SrcIdx = 1 };
35const char *ValNameStr[2] = {
"dst",
"src"};
37template <
class Derived>
struct StructVisitor {
40 template <
class... Ts>
45 for (
const FieldDecl *FD : RD->fields()) {
48 asDerived().visit(FT, FD, CurStructOffset, Args...);
51 asDerived().flushTrivialFields(Args...);
54 template <
class... Ts>
void visitTrivial(Ts... Args) {}
56 template <
class... Ts>
void visitCXXDestructor(Ts... Args) {
57 llvm_unreachable(
"field of a C++ struct type is not expected");
60 template <
class... Ts>
void flushTrivialFields(Ts... Args) {}
72 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
78template <
class Derived,
bool IsMove>
79struct CopyStructVisitor : StructVisitor<Derived>,
84 CopyStructVisitor(
ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
86 template <
class... Ts>
90 asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
93 template <
class... Ts>
97 if (
const auto *AT =
asDerived().getContext().getAsArrayType(FT)) {
99 CurStructOffset, std::forward<Ts>(Args)...);
104 std::forward<Ts>(Args)...);
107 template <
class... Ts>
119 uint64_t FEndInBits = FStartInBits + FieldSize;
151template <
class Derived>
struct GenFuncNameBase {
152 std::string getVolatileOffsetStr(
bool IsVolatile,
CharUnits Offset) {
156 S += llvm::to_string(Offset.getQuantity());
165 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
172 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
178 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
180 asDerived().visitStructFields(QT, FieldOffset);
183 template <
class FieldKind>
184 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
189 return asDerived().visitTrivial(
QualType(AT, 0), FD, CurStructOffset);
191 asDerived().flushTrivialFields();
192 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
198 appendStr(
"_AB" + llvm::to_string(FieldOffset.
getQuantity()) +
"s" +
200 llvm::to_string(NumElts));
202 asDerived().visitWithKind(FK, EltTy,
nullptr, FieldOffset);
206 void appendStr(StringRef Str) { Name += Str; }
214 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
219template <
class Derived>
220struct GenUnaryFuncName : StructVisitor<Derived>, GenFuncNameBase<Derived> {
222 : StructVisitor<Derived>(Ctx) {
223 this->appendStr(Prefix);
224 this->appendStr(llvm::to_string(DstAlignment.
getQuantity()));
230 llvm::Type *Ty =
Addr.getElementType();
231 return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty));
234template <
bool IsMove>
235struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>,
236 GenFuncNameBase<GenBinaryFuncName<IsMove>> {
238 GenBinaryFuncName(StringRef Prefix,
CharUnits DstAlignment,
240 : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>(Ctx) {
241 this->appendStr(Prefix);
242 this->appendStr(llvm::to_string(DstAlignment.
getQuantity()));
243 this->appendStr(
"_" + llvm::to_string(SrcAlignment.
getQuantity()));
246 void flushTrivialFields() {
247 if (this->Start == this->End)
250 this->appendStr(
"_t" + llvm::to_string(this->Start.getQuantity()) +
"w" +
251 llvm::to_string((this->End - this->Start).getQuantity()));
266 this->appendStr(
"_tv" + llvm::to_string(OffsetInBits) +
"w" +
272 this->appendStr(
"_pa");
274 this->appendStr(llvm::to_string(PtrAuth.
getKey()) +
"_");
277 this->appendStr(
"anv_");
279 this->appendStr(llvm::to_string(FieldOffset.
getQuantity()));
283struct GenDefaultInitializeFuncName
284 : GenUnaryFuncName<GenDefaultInitializeFuncName>,
288 : GenUnaryFuncName<GenDefaultInitializeFuncName>(
"__default_constructor_",
289 DstAlignment, Ctx) {}
292 if (
const auto *AT = getContext().getAsArrayType(FT)) {
301struct GenDestructorFuncName : GenUnaryFuncName<GenDestructorFuncName>,
304 GenDestructorFuncName(
const char *Prefix,
CharUnits DstAlignment,
306 : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment, Ctx) {}
309 if (
const auto *AT = getContext().getAsArrayType(FT)) {
326 for (
unsigned I = 0; I < N; ++I)
329 ImplicitParamKind::Other));
331 llvm::append_range(Args, Params);
336template <
size_t N,
size_t... Ints>
337static std::array<Address, N> getParamAddrs(std::index_sequence<Ints...> IntSeq,
338 std::array<CharUnits, N> Alignments,
341 return std::array<Address, N>{
348template <
class Derived>
struct GenFuncBase {
351 std::array<Address, N> Addrs) {
352 this->asDerived().callSpecialFunction(
356 template <
class FieldKind,
size_t N>
357 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
359 std::array<Address, N> Addrs) {
362 return asDerived().visitTrivial(
QualType(AT, 0), FD, CurStructOffset,
365 asDerived().flushTrivialFields(Addrs);
371 std::array<Address, N> StartAddrs = Addrs;
372 for (
unsigned I = 0; I < N; ++I)
373 StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
374 Address DstAddr = StartAddrs[DstIdx];
377 llvm::Value *BaseEltSizeVal =
378 llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
379 llvm::Value *SizeInBytes =
380 CGF.
Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
383 llvm::BasicBlock *PreheaderBB = CGF.
Builder.GetInsertBlock();
388 llvm::PHINode *PHIs[N];
390 for (
unsigned I = 0; I < N; ++I) {
392 PHIs[I]->addIncoming(StartAddrs[I].emitRawPointer(CGF), PreheaderBB);
402 CGF.
Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd,
"done");
403 CGF.
Builder.CreateCondBr(Done, ExitBB, LoopBB);
409 std::array<Address, N> NewAddrs = Addrs;
411 for (
unsigned I = 0; I < N; ++I)
414 StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
420 LoopBB = CGF.
Builder.GetInsertBlock();
422 for (
unsigned I = 0; I < N; ++I) {
425 NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
426 PHIs[I]->addIncoming(NewAddrs[I].emitRawPointer(CGF), LoopBB);
430 CGF.
Builder.CreateBr(HeaderBB);
436 assert(
Addr.isValid() &&
"invalid address");
437 if (Offset.getQuantity() == 0)
446 return getAddrWithOffset(
Addr, StructFieldOffset +
451 llvm::Function *getFunction(StringRef FuncName,
QualType QT,
452 std::array<CharUnits, N> Alignments,
455 if (llvm::Function *F = CGM.
getModule().getFunction(FuncName)) {
456 bool WrongType =
false;
457 if (!F->getReturnType()->isVoidTy())
460 for (
const llvm::Argument &Arg : F->args())
466 std::string FuncName = std::string(F->getName());
469 CGM.
Error(
Loc,
"special function " + FuncName +
470 " for non-trivial C struct has incorrect type");
481 llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
483 F->setVisibility(llvm::GlobalValue::HiddenVisibility);
490 std::array<Address, N> Addrs =
491 getParamAddrs<N>(std::make_index_sequence<N>{}, Alignments, Args, CGF);
498 void callFunc(StringRef FuncName,
QualType QT, std::array<Address, N> Addrs,
500 std::array<CharUnits, N> Alignments;
501 llvm::Value *Ptrs[N];
503 for (
unsigned I = 0; I < N; ++I) {
504 Alignments[I] = Addrs[I].getAlignment();
505 Ptrs[I] = Addrs[I].emitRawPointer(CallerCGF);
508 if (llvm::Function *F =
509 getFunction(FuncName, QT, Alignments, CallerCGF.
CGM))
513 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
520template <
class Derived,
bool IsMove>
521struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
522 GenFuncBase<Derived> {
523 GenBinaryFunc(
ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
525 void flushTrivialFields(std::array<Address, 2> Addrs) {
528 if (
Size.getQuantity() == 0)
531 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
532 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
535 if (
Size.getQuantity() >= 16 ||
536 !llvm::has_single_bit<uint32_t>(
Size.getQuantity())) {
537 llvm::Value *SizeVal =
538 llvm::ConstantInt::get(this->CGF->
SizeTy,
Size.getQuantity());
543 llvm::Type *Ty = llvm::Type::getIntNTy(
545 Size.getQuantity() * this->CGF->getContext().getCharWidth());
555 template <
class... Ts>
557 std::array<Address, 2> Addrs) {
567 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
571 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
586 std::array<Address, 2> Addrs) {
588 Addrs[DstIdx] = this->getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
589 Addrs[SrcIdx] = this->getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
595struct GenDestructor : StructVisitor<GenDestructor>,
596 GenFuncBase<GenDestructor>,
599 GenDestructor(
ASTContext &Ctx) : StructVisitor<GenDestructor>(Ctx) {}
603 std::array<Address, 1> Addrs) {
604 if (
const auto *AT = getContext().getAsArrayType(FT)) {
613 CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
615 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
619 std::array<Address, 1> Addrs) {
621 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
625 std::array<Address, 1> Addrs) {
627 CGF->
MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
631struct GenDefaultInitialize
632 : StructVisitor<GenDefaultInitialize>,
633 GenFuncBase<GenDefaultInitialize>,
636 typedef GenFuncBase<GenDefaultInitialize> GenFuncBaseTy;
639 : StructVisitor<GenDefaultInitialize>(Ctx) {}
643 std::array<Address, 1> Addrs) {
644 if (
const auto *AT = getContext().getAsArrayType(FT)) {
654 CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
656 getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
660 std::array<Address, 1> Addrs) {
662 getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
665 template <
class FieldKind,
size_t... Is>
666 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
668 std::array<Address, 1> Addrs) {
670 return visitTrivial(
QualType(AT, 0), FD, CurStructOffset, Addrs);
678 GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStructOffset, Addrs);
682 llvm::Constant *SizeVal = CGF->
Builder.getInt64(
Size.getQuantity());
683 Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
690 std::array<Address, 1> Addrs) {
692 CGF->
MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
696struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
698 : GenBinaryFunc<GenCopyConstructor,
false>(Ctx) {}
701 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
702 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
703 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
711 std::array<Address, 2> Addrs) {
712 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
713 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
718 std::array<Address, 2> Addrs) {
719 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
720 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
726struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
728 : GenBinaryFunc<GenMoveConstructor,
true>(Ctx) {}
731 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
732 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
733 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
735 llvm::Value *SrcVal =
743 std::array<Address, 2> Addrs) {
744 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
745 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
750 std::array<Address, 2> Addrs) {
751 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
752 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
758struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
760 : GenBinaryFunc<GenCopyAssignment,
false>(Ctx) {}
763 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
764 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
765 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
773 std::array<Address, 2> Addrs) {
774 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
775 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
780 std::array<Address, 2> Addrs) {
781 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
782 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
789struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
791 : GenBinaryFunc<GenMoveAssignment,
true>(Ctx) {}
794 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
795 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
796 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
798 llvm::Value *SrcVal =
802 llvm::Value *DstVal =
809 std::array<Address, 2> Addrs) {
810 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
811 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
816 std::array<Address, 2> Addrs) {
817 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
818 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
840 Gen.visit(QT,
nullptr,
CharUnits::Zero(), std::array<Address, 1>({{DstPtr}}));
843template <
class G,
size_t N>
846 std::array<Address, N> Addrs) {
848 for (
unsigned I = 0; I < N; ++I)
851 Gen.callFunc(FuncName, QT, Addrs, CGF);
854template <
class G,
size_t N>
855static llvm::Function *
862 return Gen.getFunction(FuncName, QT, Alignments, CGM);
871 std::string FuncName = GenName.getName(QT, IsVolatile);
873 IsVolatile, *
this, std::array<Address, 1>({{DstPtr}}));
878 GenBinaryFuncName<false> GenName(
"", Alignment, Alignment, Ctx);
879 return GenName.getName(QT, IsVolatile);
886 GenDestructorFuncName GenName(
"", Alignment, Ctx);
887 return GenName.getName(QT, IsVolatile);
894 GenDestructorFuncName GenName(
"__destructor_", DstPtr.
getAlignment(),
896 std::string FuncName = GenName.getName(QT, IsVolatile);
898 *
this, std::array<Address, 1>({{DstPtr}}));
905 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstPtr.
getAlignment(),
907 std::string FuncName = GenName.getName(QT, IsVolatile);
910 std::array<Address, 2>({{DstPtr, SrcPtr}}));
919 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstPtr.
getAlignment(),
921 std::string FuncName = GenName.getName(QT, IsVolatile);
923 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
930 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstPtr.
getAlignment(),
932 std::string FuncName = GenName.getName(QT, IsVolatile);
935 std::array<Address, 2>({{DstPtr, SrcPtr}}));
944 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstPtr.
getAlignment(),
946 std::string FuncName = GenName.getName(QT, IsVolatile);
948 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
954 GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
955 std::string FuncName = GenName.getName(QT, IsVolatile);
957 std::array<CharUnits, 1>({{DstAlignment}}), CGM);
964 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstAlignment,
966 std::string FuncName = GenName.getName(QT, IsVolatile);
968 GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
969 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
976 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstAlignment,
978 std::string FuncName = GenName.getName(QT, IsVolatile);
980 GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
981 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
988 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstAlignment,
990 std::string FuncName = GenName.getName(QT, IsVolatile);
992 GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
993 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
1000 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstAlignment,
1002 std::string FuncName = GenName.getName(QT, IsVolatile);
1004 GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
1005 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
1011 GenDestructorFuncName GenName(
"__destructor_", DstAlignment, Ctx);
1012 std::string FuncName = GenName.getName(QT, IsVolatile);
1014 std::array<CharUnits, 1>({{DstAlignment}}), CGM);
static bool getFieldOffsetInBits(CodeGenFunction &CGF, const RecordDecl *RD, const FieldDecl *Field, int64_t &Offset)
The offset of a field from the beginning of the record.
static uint64_t getFieldSize(const FieldDecl *FD, QualType FT, ASTContext &Ctx)
static void callSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile, CodeGenFunction &CGF, std::array< Address, N > Addrs)
static llvm::Function * getSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile, std::array< CharUnits, N > Alignments, CodeGenModule &CGM)
static llvm::Constant * getNullForVariable(Address addr)
Given the address of a variable of pointer type, find the correct null to store into it.
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
CGFunctionInfo - Class to encapsulate the information about a function definition.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitARCMoveWeak(Address dst, Address src)
void @objc_moveWeak(i8** dest, i8** src) Disregards the current value in dest.
static Destroyer destroyNonTrivialCStruct
void callCStructMoveConstructor(LValue Dst, LValue Src)
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::Type * ConvertType(QualType T)
static Destroyer destroyARCWeak
void callCStructDestructor(LValue Dst)
llvm::Value * EmitARCRetain(QualType type, llvm::Value *value)
Produce the code to do a retain.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
static std::string getNonTrivialDestructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field, bool IsInBounds=true)
void defaultInitNonTrivialCStructVar(LValue Dst)
void callCStructDefaultConstructor(LValue Dst)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void callCStructCopyAssignmentOperator(LValue Dst, LValue Src)
static Destroyer destroyARCStrongImprecise
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
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 callCStructCopyConstructor(LValue Dst, LValue Src)
void EmitPointerAuthCopy(PointerAuthQualifier Qualifier, QualType Type, Address DestField, Address SrcField)
void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::Type * ConvertTypeForMem(QualType T)
static std::string getNonTrivialCopyConstructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::LLVMContext & getLLVMContext()
void EmitARCCopyWeak(Address dst, Address src)
void @objc_copyWeak(i8** dest, i8** src) Disregards the current value in dest.
void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
CodeGenTypes & getTypes()
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
ASTContext & getContext() const
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Represents the canonical version of C arrays with a specified constant size.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
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.
bool isZeroLengthBitField() const
Is this a zero-length bit-field? Such bit-fields aren't really bit-fields at all and instead act as a...
GlobalDecl - represents a global declaration.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Pointer-authentication qualifiers.
bool authenticatesNullValues() const
PointerAuthQualifier withoutKeyNone() const
unsigned getExtraDiscriminator() const
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withVolatile() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Encodes a location in the source.
The base class of the type hierarchy.
bool isBlockPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
RecordDecl * castAsRecordDecl() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
llvm::Function * getNonTrivialCStructCopyConstructor(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Returns the copy constructor for a C struct with non-trivially copyable fields, generating it if nece...
llvm::Function * getNonTrivialCStructMoveConstructor(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Returns the move constructor for a C struct with non-trivially copyable fields, generating it if nece...
llvm::Function * getNonTrivialCStructCopyAssignmentOperator(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Returns the copy assignment operator for a C struct with non-trivially copyable fields,...
llvm::Function * getNonTrivialCStructMoveAssignmentOperator(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Return the move assignment operator for a C struct with non-trivially copyable fields,...
llvm::Function * getNonTrivialCStructDestructor(CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT)
Returns the destructor for a C struct with non-trivially copyable fields, generating it if necessary.
llvm::Function * getNonTrivialCStructDefaultConstructor(CodeGenModule &GCM, CharUnits DstAlignment, bool IsVolatile, QualType QT)
Returns the default constructor for a C struct with non-trivially copyable fields,...
StringRef getName(const HeaderType T)
The JSON file list parser is used to communicate input to InstallAPI.
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::PointerType * Int8PtrTy
RetTy visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT, Ts &&... Args)
RetTy visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK, QualType FT, Ts &&... Args)
RetTy visitWithKind(QualType::DestructionKind DK, QualType FT, Ts &&... Args)