18#include "llvm/Support/ScopedPrinter.h"
22using namespace CodeGen;
33enum { DstIdx = 0, SrcIdx = 1 };
34const char *ValNameStr[2] = {
"dst",
"src"};
36template <
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) {}
62 return FD ? Ctx.getASTRecordLayout(FD->
getParent())
68 return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
71 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
77template <
class Derived,
bool IsMove>
78struct CopyStructVisitor : StructVisitor<Derived>,
83 CopyStructVisitor(
ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
85 template <
class... Ts>
89 asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
92 template <
class... Ts>
96 if (
const auto *AT =
asDerived().getContext().getAsArrayType(FT)) {
98 CurStructOffset, std::forward<Ts>(Args)...);
103 std::forward<Ts>(Args)...);
106 template <
class... Ts>
118 uint64_t FEndInBits = FStartInBits + FieldSize;
150template <
class Derived>
struct GenFuncNameBase {
155 S += llvm::to_string(
Offset.getQuantity());
164 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
171 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
177 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 asDerived().flushTrivialFields();
191 CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
197 appendStr(
"_AB" + llvm::to_string(FieldOffset.
getQuantity()) +
"s" +
199 llvm::to_string(NumElts));
201 asDerived().visitWithKind(FK, EltTy,
nullptr, FieldOffset);
205 void appendStr(StringRef Str) { Name += Str; }
213 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
218template <
class Derived>
219struct GenUnaryFuncName : StructVisitor<Derived>, GenFuncNameBase<Derived> {
221 : StructVisitor<Derived>(Ctx) {
222 this->appendStr(Prefix);
223 this->appendStr(llvm::to_string(DstAlignment.
getQuantity()));
230 return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty));
233template <
bool IsMove>
234struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>,
235 GenFuncNameBase<GenBinaryFuncName<IsMove>> {
237 GenBinaryFuncName(StringRef Prefix,
CharUnits DstAlignment,
239 : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>(Ctx) {
240 this->appendStr(Prefix);
241 this->appendStr(llvm::to_string(DstAlignment.
getQuantity()));
242 this->appendStr(
"_" + llvm::to_string(SrcAlignment.
getQuantity()));
245 void flushTrivialFields() {
246 if (this->Start == this->End)
249 this->appendStr(
"_t" + llvm::to_string(this->Start.getQuantity()) +
"w" +
250 llvm::to_string((this->End - this->Start).getQuantity()));
264 this->Ctx.
toBits(CurStructOffset) + this->getFieldOffsetInBits(FD);
265 this->appendStr(
"_tv" + llvm::to_string(OffsetInBits) +
"w" +
270struct GenDefaultInitializeFuncName
271 : GenUnaryFuncName<GenDefaultInitializeFuncName>,
275 : GenUnaryFuncName<GenDefaultInitializeFuncName>(
"__default_constructor_",
276 DstAlignment, Ctx) {}
279 if (
const auto *AT = getContext().getAsArrayType(FT)) {
288struct GenDestructorFuncName : GenUnaryFuncName<GenDestructorFuncName>,
291 GenDestructorFuncName(
const char *Prefix,
CharUnits DstAlignment,
293 : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment, Ctx) {}
296 if (
const auto *AT = getContext().getAsArrayType(FT)) {
313 for (
unsigned I = 0; I < N; ++I)
318 llvm::append_range(Args, Params);
323template <
size_t N,
size_t... Ints>
324static std::array<Address, N> getParamAddrs(std::index_sequence<Ints...> IntSeq,
325 std::array<CharUnits, N> Alignments,
328 return std::array<Address, N>{
335template <
class Derived>
struct GenFuncBase {
338 std::array<Address, N> Addrs) {
339 this->asDerived().callSpecialFunction(
343 template <
class FieldKind,
size_t N>
344 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
346 std::array<Address, N> Addrs) {
349 return asDerived().visitTrivial(
QualType(AT, 0), FD, CurStructOffset,
352 asDerived().flushTrivialFields(Addrs);
358 std::array<Address, N> StartAddrs = Addrs;
359 for (
unsigned I = 0; I < N; ++I)
360 StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
361 Address DstAddr = StartAddrs[DstIdx];
364 llvm::Value *BaseEltSizeVal =
365 llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
366 llvm::Value *SizeInBytes =
367 CGF.
Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
369 llvm::Value *DstArrayEnd =
371 DstArrayEnd = CGF.
Builder.CreateBitCast(
373 llvm::BasicBlock *PreheaderBB = CGF.
Builder.GetInsertBlock();
378 llvm::PHINode *PHIs[N];
380 for (
unsigned I = 0; I < N; ++I) {
382 PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
392 CGF.
Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd,
"done");
393 CGF.
Builder.CreateCondBr(Done, ExitBB, LoopBB);
399 std::array<Address, N> NewAddrs = Addrs;
401 for (
unsigned I = 0; I < N; ++I)
404 StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
410 LoopBB = CGF.
Builder.GetInsertBlock();
412 for (
unsigned I = 0; I < N; ++I) {
415 NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
416 PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB);
420 CGF.
Builder.CreateBr(HeaderBB);
426 assert(Addr.
isValid() &&
"invalid address");
427 if (
Offset.getQuantity() == 0)
436 return getAddrWithOffset(Addr, StructFieldOffset +
441 llvm::Function *getFunction(StringRef FuncName,
QualType QT,
442 std::array<CharUnits, N> Alignments,
445 if (llvm::Function *F = CGM.
getModule().getFunction(FuncName)) {
446 bool WrongType =
false;
447 if (!F->getReturnType()->isVoidTy())
450 for (
const llvm::Argument &Arg : F->args())
456 std::string FuncName = std::string(F->getName());
458 CGM.
Error(Loc,
"special function " + FuncName +
459 " for non-trivial C struct has incorrect type");
470 llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
472 F->setVisibility(llvm::GlobalValue::HiddenVisibility);
479 std::array<Address, N> Addrs =
480 getParamAddrs<N>(std::make_index_sequence<N>{}, Alignments, Args, CGF);
487 void callFunc(StringRef FuncName,
QualType QT, std::array<Address, N> Addrs,
489 std::array<CharUnits, N> Alignments;
490 llvm::Value *Ptrs[N];
492 for (
unsigned I = 0; I < N; ++I) {
493 Alignments[I] = Addrs[I].getAlignment();
498 if (llvm::Function *F =
499 getFunction(FuncName, QT, Alignments, CallerCGF.
CGM))
503 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
510template <
class Derived,
bool IsMove>
511struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
512 GenFuncBase<Derived> {
513 GenBinaryFunc(
ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
515 void flushTrivialFields(std::array<Address, 2> Addrs) {
518 if (
Size.getQuantity() == 0)
521 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
522 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
525 if (
Size.getQuantity() >= 16 ||
526 !llvm::has_single_bit<uint32_t>(
Size.getQuantity())) {
527 llvm::Value *SizeVal =
528 llvm::ConstantInt::get(this->CGF->
SizeTy,
Size.getQuantity());
535 llvm::Type *Ty = llvm::Type::getIntNTy(
537 Size.getQuantity() * this->CGF->getContext().getCharWidth());
547 template <
class... Ts>
549 std::array<Address, 2> Addrs) {
558 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx],
Offset);
562 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx],
Offset);
581struct GenDestructor : StructVisitor<GenDestructor>,
582 GenFuncBase<GenDestructor>,
585 GenDestructor(
ASTContext &Ctx) : StructVisitor<GenDestructor>(Ctx) {}
589 std::array<Address, 1> Addrs) {
590 if (
const auto *AT = getContext().getAsArrayType(FT)) {
599 CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
601 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
605 std::array<Address, 1> Addrs) {
607 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
611 std::array<Address, 1> Addrs) {
617struct GenDefaultInitialize
618 : StructVisitor<GenDefaultInitialize>,
619 GenFuncBase<GenDefaultInitialize>,
622 typedef GenFuncBase<GenDefaultInitialize> GenFuncBaseTy;
625 : StructVisitor<GenDefaultInitialize>(Ctx) {}
629 std::array<Address, 1> Addrs) {
630 if (
const auto *AT = getContext().getAsArrayType(FT)) {
640 CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
642 getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
646 std::array<Address, 1> Addrs) {
648 getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
651 template <
class FieldKind,
size_t... Is>
652 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
654 std::array<Address, 1> Addrs) {
656 return visitTrivial(
QualType(AT, 0), FD, CurStructOffset, Addrs);
663 GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStructOffset, Addrs);
667 llvm::Constant *SizeVal = CGF->
Builder.getInt64(
Size.getQuantity());
668 Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
675 std::array<Address, 1> Addrs) {
681struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
683 : GenBinaryFunc<GenCopyConstructor,
false>(Ctx) {}
686 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
687 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
688 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
696 std::array<Address, 2> Addrs) {
697 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
698 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
703 std::array<Address, 2> Addrs) {
704 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx],
Offset);
705 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx],
Offset);
711struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
713 : GenBinaryFunc<GenMoveConstructor,
true>(Ctx) {}
716 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
717 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
718 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
720 llvm::Value *SrcVal =
728 std::array<Address, 2> Addrs) {
729 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
730 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
735 std::array<Address, 2> Addrs) {
736 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx],
Offset);
737 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx],
Offset);
743struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
745 : GenBinaryFunc<GenCopyAssignment,
false>(Ctx) {}
748 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
749 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
750 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
758 std::array<Address, 2> Addrs) {
759 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
760 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
765 std::array<Address, 2> Addrs) {
766 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx],
Offset);
767 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx],
Offset);
774struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
776 : GenBinaryFunc<GenMoveAssignment,
true>(Ctx) {}
779 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
780 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
781 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
783 llvm::Value *SrcVal =
787 llvm::Value *DstVal =
794 std::array<Address, 2> Addrs) {
795 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
796 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
801 std::array<Address, 2> Addrs) {
802 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx],
Offset);
803 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx],
Offset);
826 Gen.visit(QT,
nullptr,
CharUnits::Zero(), std::array<Address, 1>({{DstPtr}}));
829template <
class G,
size_t N>
832 std::array<Address, N> Addrs) {
834 for (
unsigned I = 0; I < N; ++I)
837 Gen.callFunc(FuncName, QT, Addrs, CGF);
840template <
class G,
size_t N>
841static llvm::Function *
848 return Gen.getFunction(FuncName, QT, Alignments, CGM);
857 std::string FuncName = GenName.getName(QT, IsVolatile);
859 IsVolatile, *
this, std::array<Address, 1>({{DstPtr}}));
864 GenBinaryFuncName<false> GenName(
"", Alignment, Alignment, Ctx);
865 return GenName.getName(QT, IsVolatile);
872 GenDestructorFuncName GenName(
"", Alignment, Ctx);
873 return GenName.getName(QT, IsVolatile);
880 GenDestructorFuncName GenName(
"__destructor_", DstPtr.
getAlignment(),
882 std::string FuncName = GenName.getName(QT, IsVolatile);
884 *
this, std::array<Address, 1>({{DstPtr}}));
891 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstPtr.
getAlignment(),
893 std::string FuncName = GenName.getName(QT, IsVolatile);
896 std::array<Address, 2>({{DstPtr, SrcPtr}}));
905 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstPtr.
getAlignment(),
907 std::string FuncName = GenName.getName(QT, IsVolatile);
909 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
916 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstPtr.
getAlignment(),
918 std::string FuncName = GenName.getName(QT, IsVolatile);
921 std::array<Address, 2>({{DstPtr, SrcPtr}}));
930 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstPtr.
getAlignment(),
932 std::string FuncName = GenName.getName(QT, IsVolatile);
934 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
940 GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
941 std::string FuncName = GenName.getName(QT, IsVolatile);
943 std::array<CharUnits, 1>({{DstAlignment}}), CGM);
950 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstAlignment,
952 std::string FuncName = GenName.getName(QT, IsVolatile);
954 GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
955 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
962 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstAlignment,
964 std::string FuncName = GenName.getName(QT, IsVolatile);
966 GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
967 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
974 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstAlignment,
976 std::string FuncName = GenName.getName(QT, IsVolatile);
978 GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
979 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
986 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstAlignment,
988 std::string FuncName = GenName.getName(QT, IsVolatile);
990 GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
991 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
997 GenDestructorFuncName GenName(
"__destructor_", DstAlignment, Ctx);
998 std::string FuncName = GenName.getName(QT, IsVolatile);
1000 std::array<CharUnits, 1>({{DstAlignment}}), CGM);
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)
static std::string getName(const CallEvent &Call)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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.
uint64_t getCharWidth() const
Return the size of the character type, 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.
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
llvm::Value * getPointer() const
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
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...
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 FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
void EmitARCMoveWeak(Address dst, Address src)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void callCStructDefaultConstructor(LValue Dst)
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 callCStructCopyAssignmentOperator(LValue Dst, LValue Src)
void callCStructMoveConstructor(LValue Dst, LValue Src)
void callCStructCopyConstructor(LValue Dst, LValue Src)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void callCStructDestructor(LValue Dst)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Type * ConvertTypeForMem(QualType T)
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
static std::string getNonTrivialDestructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
void EmitARCCopyWeak(Address dst, Address src)
void defaultInitNonTrivialCStructVar(LValue Dst)
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 * EmitARCRetain(QualType type, llvm::Value *value)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
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 callCStructMoveAssignmentOperator(LValue Dst, LValue Src)
static Destroyer destroyARCWeak
llvm::Type * ConvertType(QualType T)
void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
static Destroyer destroyARCStrongImprecise
llvm::LLVMContext & getLLVMContext()
static std::string getNonTrivialCopyConstructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
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...
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(CodeGenFunction &CGF) 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 getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
bool isZeroLengthBitField(const ASTContext &Ctx) const
Is this a zero-length bit-field? Such bit-fields aren't really bit-fields at all and instead act as a...
unsigned getBitWidthValue(const ASTContext &Ctx) const
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
GlobalDecl - represents a global declaration.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
@ Other
Other implicit parameter.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
PrimitiveDefaultInitializeKind
QualType withVolatile() const
Represents a struct/union/class.
field_range fields() 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.
const Type * getTypeForDecl() const
The base class of the type hierarchy.
bool isBlockPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
const T * getAs() const
Member-template getAs<specific 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,...
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)