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())
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 {
151 std::string getVolatileOffsetStr(
bool IsVolatile,
CharUnits Offset) {
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()));
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)
316 ImplicitParamKind::Other));
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);
370 llvm::BasicBlock *PreheaderBB = CGF.
Builder.GetInsertBlock();
375 llvm::PHINode *PHIs[N];
377 for (
unsigned I = 0; I < N; ++I) {
379 PHIs[I]->addIncoming(StartAddrs[I].emitRawPointer(CGF), PreheaderBB);
389 CGF.
Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd,
"done");
390 CGF.
Builder.CreateCondBr(Done, ExitBB, LoopBB);
396 std::array<Address, N> NewAddrs = Addrs;
398 for (
unsigned I = 0; I < N; ++I)
401 StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
407 LoopBB = CGF.
Builder.GetInsertBlock();
409 for (
unsigned I = 0; I < N; ++I) {
412 NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
413 PHIs[I]->addIncoming(NewAddrs[I].emitRawPointer(CGF), LoopBB);
417 CGF.
Builder.CreateBr(HeaderBB);
423 assert(Addr.
isValid() &&
"invalid address");
424 if (Offset.getQuantity() == 0)
433 return getAddrWithOffset(Addr, StructFieldOffset +
438 llvm::Function *getFunction(StringRef FuncName,
QualType QT,
439 std::array<CharUnits, N> Alignments,
442 if (llvm::Function *F = CGM.
getModule().getFunction(FuncName)) {
443 bool WrongType =
false;
444 if (!F->getReturnType()->isVoidTy())
447 for (
const llvm::Argument &Arg : F->args())
453 std::string FuncName = std::string(F->getName());
455 CGM.
Error(
Loc,
"special function " + FuncName +
456 " for non-trivial C struct has incorrect type");
467 llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
469 F->setVisibility(llvm::GlobalValue::HiddenVisibility);
476 std::array<Address, N> Addrs =
477 getParamAddrs<N>(std::make_index_sequence<N>{}, Alignments, Args, CGF);
484 void callFunc(StringRef FuncName,
QualType QT, std::array<Address, N> Addrs,
486 std::array<CharUnits, N> Alignments;
487 llvm::Value *Ptrs[N];
489 for (
unsigned I = 0; I < N; ++I) {
490 Alignments[I] = Addrs[I].getAlignment();
491 Ptrs[I] = Addrs[I].emitRawPointer(CallerCGF);
494 if (llvm::Function *F =
495 getFunction(FuncName, QT, Alignments, CallerCGF.
CGM))
499 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
506template <
class Derived,
bool IsMove>
507struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
508 GenFuncBase<Derived> {
509 GenBinaryFunc(
ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
511 void flushTrivialFields(std::array<Address, 2> Addrs) {
514 if (
Size.getQuantity() == 0)
517 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
518 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
521 if (
Size.getQuantity() >= 16 ||
522 !llvm::has_single_bit<uint32_t>(
Size.getQuantity())) {
523 llvm::Value *SizeVal =
524 llvm::ConstantInt::get(this->CGF->
SizeTy,
Size.getQuantity());
529 llvm::Type *Ty = llvm::Type::getIntNTy(
531 Size.getQuantity() * this->CGF->getContext().getCharWidth());
541 template <
class... Ts>
543 std::array<Address, 2> Addrs) {
552 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
556 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
573struct GenDestructor : StructVisitor<GenDestructor>,
574 GenFuncBase<GenDestructor>,
577 GenDestructor(
ASTContext &Ctx) : StructVisitor<GenDestructor>(Ctx) {}
581 std::array<Address, 1> Addrs) {
582 if (
const auto *AT = getContext().getAsArrayType(FT)) {
591 CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
593 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
597 std::array<Address, 1> Addrs) {
599 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
603 std::array<Address, 1> Addrs) {
605 CGF->
MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
609struct GenDefaultInitialize
610 : StructVisitor<GenDefaultInitialize>,
611 GenFuncBase<GenDefaultInitialize>,
614 typedef GenFuncBase<GenDefaultInitialize> GenFuncBaseTy;
617 : StructVisitor<GenDefaultInitialize>(Ctx) {}
621 std::array<Address, 1> Addrs) {
622 if (
const auto *AT = getContext().getAsArrayType(FT)) {
632 CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
634 getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
638 std::array<Address, 1> Addrs) {
640 getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
643 template <
class FieldKind,
size_t... Is>
644 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
646 std::array<Address, 1> Addrs) {
648 return visitTrivial(
QualType(AT, 0), FD, CurStructOffset, Addrs);
655 GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStructOffset, Addrs);
659 llvm::Constant *SizeVal = CGF->
Builder.getInt64(
Size.getQuantity());
660 Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
667 std::array<Address, 1> Addrs) {
669 CGF->
MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
673struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
675 : GenBinaryFunc<GenCopyConstructor,
false>(Ctx) {}
678 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
679 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
680 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
688 std::array<Address, 2> Addrs) {
689 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
690 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
695 std::array<Address, 2> Addrs) {
696 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
697 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
703struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
705 : GenBinaryFunc<GenMoveConstructor,
true>(Ctx) {}
708 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
709 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
710 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
712 llvm::Value *SrcVal =
720 std::array<Address, 2> Addrs) {
721 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
722 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
727 std::array<Address, 2> Addrs) {
728 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
729 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
735struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
737 : GenBinaryFunc<GenCopyAssignment,
false>(Ctx) {}
740 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
741 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
742 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
750 std::array<Address, 2> Addrs) {
751 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
752 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
757 std::array<Address, 2> Addrs) {
758 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
759 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
766struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
768 : GenBinaryFunc<GenMoveAssignment,
true>(Ctx) {}
771 CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
772 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
773 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
775 llvm::Value *SrcVal =
779 llvm::Value *DstVal =
786 std::array<Address, 2> Addrs) {
787 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
788 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
793 std::array<Address, 2> Addrs) {
794 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
795 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
817 Gen.visit(QT,
nullptr,
CharUnits::Zero(), std::array<Address, 1>({{DstPtr}}));
820template <
class G,
size_t N>
823 std::array<Address, N> Addrs) {
825 for (
unsigned I = 0; I < N; ++I)
828 Gen.callFunc(FuncName, QT, Addrs, CGF);
831template <
class G,
size_t N>
832static llvm::Function *
839 return Gen.getFunction(FuncName, QT, Alignments, CGM);
848 std::string FuncName = GenName.getName(QT, IsVolatile);
850 IsVolatile, *
this, std::array<Address, 1>({{DstPtr}}));
855 GenBinaryFuncName<false> GenName(
"", Alignment, Alignment, Ctx);
856 return GenName.getName(QT, IsVolatile);
863 GenDestructorFuncName GenName(
"", Alignment, Ctx);
864 return GenName.getName(QT, IsVolatile);
871 GenDestructorFuncName GenName(
"__destructor_", DstPtr.
getAlignment(),
873 std::string FuncName = GenName.getName(QT, IsVolatile);
875 *
this, std::array<Address, 1>({{DstPtr}}));
882 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstPtr.
getAlignment(),
884 std::string FuncName = GenName.getName(QT, IsVolatile);
887 std::array<Address, 2>({{DstPtr, SrcPtr}}));
896 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstPtr.
getAlignment(),
898 std::string FuncName = GenName.getName(QT, IsVolatile);
900 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
907 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstPtr.
getAlignment(),
909 std::string FuncName = GenName.getName(QT, IsVolatile);
912 std::array<Address, 2>({{DstPtr, SrcPtr}}));
921 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstPtr.
getAlignment(),
923 std::string FuncName = GenName.getName(QT, IsVolatile);
925 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
931 GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
932 std::string FuncName = GenName.getName(QT, IsVolatile);
934 std::array<CharUnits, 1>({{DstAlignment}}), CGM);
941 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstAlignment,
943 std::string FuncName = GenName.getName(QT, IsVolatile);
945 GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
946 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
953 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstAlignment,
955 std::string FuncName = GenName.getName(QT, IsVolatile);
957 GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
958 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
965 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstAlignment,
967 std::string FuncName = GenName.getName(QT, IsVolatile);
969 GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
970 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
977 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstAlignment,
979 std::string FuncName = GenName.getName(QT, IsVolatile);
981 GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
982 std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
988 GenDestructorFuncName GenName(
"__destructor_", DstAlignment, Ctx);
989 std::string FuncName = GenName.getName(QT, IsVolatile);
991 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)
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.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address 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 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() 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
Computes the bit width of this field, if this is a bit field.
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.
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,...
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)