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 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); }
218 template <
class Derived>
219 struct 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));
233 template <
bool IsMove>
234 struct 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()));
259 uint64_t OffsetInBits =
260 this->Ctx.
toBits(CurStackOffset) + this->getFieldOffsetInBits(FD);
261 this->appendStr(
"_tv" + llvm::to_string(OffsetInBits) +
"w" +
266 struct GenDefaultInitializeFuncName
267 : GenUnaryFuncName<GenDefaultInitializeFuncName>,
271 : GenUnaryFuncName<GenDefaultInitializeFuncName>(
"__default_constructor_",
272 DstAlignment, Ctx) {}
275 if (
const auto *AT = getContext().getAsArrayType(FT)) {
280 Super::visitWithKind(PDIK, FT, FD, CurStructOffset);
284 struct GenDestructorFuncName : GenUnaryFuncName<GenDestructorFuncName>,
287 GenDestructorFuncName(
const char *Prefix,
CharUnits DstAlignment,
289 : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment,
293 if (
const auto *AT = getContext().getAsArrayType(FT)) {
298 Super::visitWithKind(DK, FT, FD, CurStructOffset);
310 for (
unsigned I = 0; I < N; ++I)
315 for (
auto &
P : Params)
323 template <
class Derived>
struct GenFuncBase {
326 std::array<Address, N> Addrs) {
327 this->asDerived().callSpecialFunction(
331 template <
class FieldKind,
size_t N>
332 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
334 std::array<Address, N> Addrs) {
337 return asDerived().visitTrivial(
QualType(AT, 0), FD, CurStackOffset,
340 asDerived().flushTrivialFields(Addrs);
346 std::array<Address, N> StartAddrs = Addrs;
347 for (
unsigned I = 0; I < N; ++I)
348 StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStackOffset, FD);
349 Address DstAddr = StartAddrs[DstIdx];
353 llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
355 CGF.
Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
361 llvm::BasicBlock *PreheaderBB = CGF.
Builder.GetInsertBlock();
366 llvm::PHINode *PHIs[N];
368 for (
unsigned I = 0; I < N; ++I) {
370 PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
380 CGF.
Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd,
"done");
381 CGF.
Builder.CreateCondBr(Done, ExitBB, LoopBB);
387 std::array<Address, N> NewAddrs = Addrs;
389 for (
unsigned I = 0; I < N; ++I)
391 PHIs[I], StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
397 LoopBB = CGF.
Builder.GetInsertBlock();
399 for (
unsigned I = 0; I < N; ++I) {
402 NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
403 PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB);
407 CGF.
Builder.CreateBr(HeaderBB);
413 assert(Addr.
isValid() &&
"invalid address");
416 Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
417 Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.
getQuantity(),
419 return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
424 return getAddrWithOffset(Addr, StructFieldOffset +
430 getFunction(StringRef FuncName,
QualType QT, std::array<Address, N> Addrs,
433 if (llvm::Function *F = CGM.
getModule().getFunction(FuncName)) {
434 bool WrongType =
false;
435 if (!F->getReturnType()->isVoidTy())
438 for (
const llvm::Argument &Arg : F->args())
444 std::string FuncName = F->getName();
446 CGM.
Error(Loc,
"special function " + FuncName +
447 " for non-trivial C struct has incorrect type");
456 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
459 FuncName, &CGM.getModule());
461 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, F);
462 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
470 CGF->StartFunction(FD, Ctx.
VoidTy, F, FI, Args);
472 for (
unsigned I = 0; I < N; ++I) {
473 llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
474 Addrs[I] =
Address(V, Alignments[I]);
478 CGF->FinishFunction();
483 void callFunc(StringRef FuncName,
QualType QT, std::array<Address, N> Addrs,
485 std::array<CharUnits, N> Alignments;
488 for (
unsigned I = 0; I < N; ++I) {
489 Alignments[I] = Addrs[I].getAlignment();
495 if (llvm::Function *F =
496 getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.
CGM))
500 Derived &asDerived() {
return static_cast<Derived &
>(*this); }
507 template <
class Derived,
bool IsMove>
508 struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
509 GenFuncBase<Derived> {
510 GenBinaryFunc(
ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
512 void flushTrivialFields(std::array<Address, 2> Addrs) {
518 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
519 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
524 llvm::ConstantInt::get(this->CGF->SizeTy, Size.
getQuantity());
526 this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
528 this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
529 this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal,
false);
532 this->CGF->getLLVMContext(),
533 Size.
getQuantity() * this->CGF->getContext().getCharWidth());
534 DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
535 SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
536 llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr,
false);
537 this->CGF->Builder.CreateStore(SrcVal, DstAddr,
false);
543 template <
class... Ts>
545 std::array<Address, 2> Addrs) {
549 llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
550 Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
551 LValue DstBase = this->CGF->MakeAddrLValue(
552 this->CGF->Builder.CreateBitCast(DstAddr, PtrTy), FT);
553 DstLV = this->CGF->EmitLValueForField(DstBase, FD);
554 Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
555 LValue SrcBase = this->CGF->MakeAddrLValue(
556 this->CGF->Builder.CreateBitCast(SrcAddr, PtrTy), FT);
557 SrcLV = this->CGF->EmitLValueForField(SrcBase, FD);
559 llvm::PointerType *Ty = this->CGF->ConvertType(FT)->getPointerTo();
560 Address DstAddr = this->CGF->Builder.CreateBitCast(Addrs[DstIdx], Ty);
561 Address SrcAddr = this->CGF->Builder.CreateBitCast(Addrs[SrcIdx], Ty);
562 DstLV = this->CGF->MakeAddrLValue(DstAddr, FT);
563 SrcLV = this->CGF->MakeAddrLValue(SrcAddr, FT);
566 this->CGF->EmitStoreThroughLValue(SrcVal, DstLV);
571 struct GenDestructor : StructVisitor<GenDestructor>,
572 GenFuncBase<GenDestructor>,
575 GenDestructor(
ASTContext &Ctx) : StructVisitor<GenDestructor>(Ctx) {}
579 std::array<Address, 1> Addrs) {
580 if (
const auto *AT = getContext().getAsArrayType(FT)) {
585 Super::visitWithKind(DK, FT, FD, CurStructOffset, Addrs);
589 CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
590 CGF->destroyARCStrongImprecise(
591 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
595 std::array<Address, 1> Addrs) {
597 *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
601 std::array<Address, 1> Addrs) {
602 CGF->callCStructDestructor(
603 CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
607 struct GenDefaultInitialize
608 : StructVisitor<GenDefaultInitialize>,
609 GenFuncBase<GenDefaultInitialize>,
612 typedef GenFuncBase<GenDefaultInitialize> GenFuncBaseTy;
615 : StructVisitor<GenDefaultInitialize>(Ctx) {}
619 std::array<Address, 1> Addrs) {
620 if (
const auto *AT = getContext().getAsArrayType(FT)) {
626 Super::visitWithKind(PDIK, FT, FD, CurStructOffset, Addrs);
630 CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
631 CGF->EmitNullInitialization(
632 getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
636 std::array<Address, 1> Addrs) {
637 CGF->EmitNullInitialization(
638 getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
641 template <
class FieldKind,
size_t... Is>
642 void visitArray(FieldKind FK,
const ArrayType *AT,
bool IsVolatile,
644 std::array<Address, 1> Addrs) {
646 return visitTrivial(
QualType(AT, 0), FD, CurStackOffset, Addrs);
653 GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStackOffset, Addrs);
657 llvm::Constant *SizeVal = CGF->Builder.getInt64(Size.
getQuantity());
658 Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
659 Address Loc = CGF->Builder.CreateElementBitCast(DstAddr, CGF->Int8Ty);
660 CGF->Builder.CreateMemSet(Loc, CGF->Builder.getInt8(0), SizeVal,
665 std::array<Address, 1> Addrs) {
666 CGF->callCStructDefaultConstructor(
667 CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
671 struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
673 : GenBinaryFunc<GenCopyConstructor, false>(Ctx) {}
676 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
677 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
678 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
682 CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT),
true);
686 std::array<Address, 2> Addrs) {
687 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
688 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
689 CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]);
693 std::array<Address, 2> Addrs) {
694 CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
695 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
699 struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
701 : GenBinaryFunc<GenMoveConstructor, true>(Ctx) {}
704 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
705 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
706 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
707 LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
711 CGF->EmitStoreOfScalar(SrcVal, CGF->MakeAddrLValue(Addrs[DstIdx], QT),
716 std::array<Address, 2> Addrs) {
717 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
718 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
719 CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]);
723 std::array<Address, 2> Addrs) {
724 CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
725 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
729 struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
731 : GenBinaryFunc<GenCopyAssignment, false>(Ctx) {}
734 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
735 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
736 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
739 CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal,
744 std::array<Address, 2> Addrs) {
745 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
746 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
747 CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
751 std::array<Address, 2> Addrs) {
752 CGF->callCStructCopyAssignmentOperator(
753 CGF->MakeAddrLValue(Addrs[DstIdx], FT),
754 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
758 struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
760 : GenBinaryFunc<GenMoveAssignment, true>(Ctx) {}
763 CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
764 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
765 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
766 LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
770 LValue DstLV = CGF->MakeAddrLValue(Addrs[DstIdx], QT);
773 CGF->EmitStoreOfScalar(SrcVal, DstLV);
778 std::array<Address, 2> Addrs) {
779 Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
780 Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
781 CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
785 std::array<Address, 2> Addrs) {
786 CGF->callCStructMoveAssignmentOperator(
787 CGF->MakeAddrLValue(Addrs[DstIdx], FT),
788 CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
802 GenDefaultInitialize Gen(getContext());
807 Gen.visit(QT,
nullptr,
CharUnits::Zero(), std::array<Address, 1>({{DstPtr}}));
810 template <
class G,
size_t N>
813 std::array<Address, N> Addrs) {
814 for (
unsigned I = 0; I < N; ++I)
817 Gen.callFunc(FuncName, QT, Addrs, CGF);
825 GenDefaultInitializeFuncName GenName(DstPtr.
getAlignment(), getContext());
826 std::string FuncName = GenName.getName(QT, IsVolatile);
828 IsVolatile, *
this, std::array<Address, 1>({{DstPtr}}));
836 GenBinaryFuncName<false> GenName(
"", Alignment, Alignment, Ctx);
837 return GenName.getName(QT, IsVolatile);
843 GenDestructorFuncName GenName(
"", Alignment, Ctx);
844 return GenName.getName(QT, IsVolatile);
851 GenDestructorFuncName GenName(
"__destructor_", DstPtr.
getAlignment(),
853 std::string FuncName = GenName.getName(QT, IsVolatile);
855 *
this, std::array<Address, 1>({{DstPtr}}));
862 GenBinaryFuncName<false> GenName(
"__copy_constructor_", DstPtr.
getAlignment(),
863 SrcPtr.getAlignment(), getContext());
864 std::string FuncName = GenName.getName(QT, IsVolatile);
867 std::array<Address, 2>({{DstPtr, SrcPtr}}));
876 GenBinaryFuncName<false> GenName(
"__copy_assignment_", DstPtr.
getAlignment(),
877 SrcPtr.getAlignment(), getContext());
878 std::string FuncName = GenName.getName(QT, IsVolatile);
880 *
this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
887 GenBinaryFuncName<true> GenName(
"__move_constructor_", DstPtr.
getAlignment(),
888 SrcPtr.getAlignment(), getContext());
889 std::string FuncName = GenName.getName(QT, IsVolatile);
892 std::array<Address, 2>({{DstPtr, SrcPtr}}));
901 GenBinaryFuncName<true> GenName(
"__move_assignment_", DstPtr.
getAlignment(),
902 SrcPtr.getAlignment(), getContext());
903 std::string FuncName = GenName.getName(QT, IsVolatile);
905 *
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 std::string getNonTrivialCopyConstructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
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.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
ASTContext & getContext() const
GlobalDecl - represents a global declaration.
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 std::string getNonTrivialDestructorStr(QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx)
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.