summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGNonTrivialStruct.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGNonTrivialStruct.cpp')
-rw-r--r--lib/CodeGen/CGNonTrivialStruct.cpp225
1 files changed, 159 insertions, 66 deletions
diff --git a/lib/CodeGen/CGNonTrivialStruct.cpp b/lib/CodeGen/CGNonTrivialStruct.cpp
index c6a96a9126..caf62d2ac9 100644
--- a/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -1,9 +1,8 @@
//===--- CGNonTrivialStruct.cpp - Emit Special Functions for C Structs ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -15,6 +14,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/NonTrivialTypeVisitor.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
#include "llvm/Support/ScopedPrinter.h"
#include <array>
@@ -84,23 +84,22 @@ struct CopyStructVisitor : StructVisitor<Derived>,
template <class... Ts>
void preVisit(QualType::PrimitiveCopyKind PCK, QualType FT,
- const FieldDecl *FD, CharUnits CurStructOffsset,
- Ts &&... Args) {
+ const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
if (PCK)
asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
}
template <class... Ts>
void visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,
- const FieldDecl *FD, CharUnits CurStructOffsset,
+ const FieldDecl *FD, CharUnits CurStructOffset,
Ts &&... Args) {
if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
- CurStructOffsset, std::forward<Ts>(Args)...);
+ CurStructOffset, std::forward<Ts>(Args)...);
return;
}
- Super::visitWithKind(PCK, FT, FD, CurStructOffsset,
+ Super::visitWithKind(PCK, FT, FD, CurStructOffset,
std::forward<Ts>(Args)...);
}
@@ -140,8 +139,8 @@ struct CopyStructVisitor : StructVisitor<Derived>,
// <alignment-info> ::= <dst-alignment> ["_" <src-alignment>]
// <struct-field-info> ::= <field-info>+
// <field-info> ::= <struct-or-scalar-field-info> | <array-field-info>
-// <struct-or-scalar-field-info> ::= <struct-field-info> | <strong-field-info> |
-// <trivial-field-info>
+// <struct-or-scalar-field-info> ::= "_S" <struct-field-info> |
+// <strong-field-info> | <trivial-field-info>
// <array-field-info> ::= "_AB" <array-offset> "s" <element-size> "n"
// <num-elements> <innermost-element-info> "_AE"
// <innermost-element-info> ::= <struct-or-scalar-field-info>
@@ -176,6 +175,7 @@ template <class Derived> struct GenFuncNameBase {
void visitStruct(QualType QT, const FieldDecl *FD,
CharUnits CurStructOffset) {
CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
+ appendStr("_S");
asDerived().visitStructFields(QT, FieldOffset);
}
@@ -253,11 +253,11 @@ struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>,
}
void visitVolatileTrivial(QualType FT, const FieldDecl *FD,
- CharUnits CurStackOffset) {
+ CharUnits CurStructOffset) {
// Because volatile fields can be bit-fields and are individually copied,
// their offset and width are in bits.
uint64_t OffsetInBits =
- this->Ctx.toBits(CurStackOffset) + this->getFieldOffsetInBits(FD);
+ this->Ctx.toBits(CurStructOffset) + this->getFieldOffsetInBits(FD);
this->appendStr("_tv" + llvm::to_string(OffsetInBits) + "w" +
llvm::to_string(getFieldSize(FD, FT, this->Ctx)));
}
@@ -286,8 +286,7 @@ struct GenDestructorFuncName : GenUnaryFuncName<GenDestructorFuncName>,
using Super = DestructedTypeVisitor<GenDestructorFuncName>;
GenDestructorFuncName(const char *Prefix, CharUnits DstAlignment,
ASTContext &Ctx)
- : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment,
- Ctx) {}
+ : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment, Ctx) {}
void visitWithKind(QualType::DestructionKind DK, QualType FT,
const FieldDecl *FD, CharUnits CurStructOffset) {
if (const auto *AT = getContext().getAsArrayType(FT)) {
@@ -322,19 +321,19 @@ static const CGFunctionInfo &getFunctionInfo(CodeGenModule &CGM,
// functions.
template <class Derived> struct GenFuncBase {
template <size_t N>
- void visitStruct(QualType FT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitStruct(QualType FT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, N> Addrs) {
this->asDerived().callSpecialFunction(
- FT, CurStackOffset + asDerived().getFieldOffset(FD), Addrs);
+ FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
}
template <class FieldKind, size_t N>
void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
- const FieldDecl *FD, CharUnits CurStackOffset,
+ const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, N> Addrs) {
// Non-volatile trivial fields are copied when flushTrivialFields is called.
if (!FK)
- return asDerived().visitTrivial(QualType(AT, 0), FD, CurStackOffset,
+ return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
Addrs);
asDerived().flushTrivialFields(Addrs);
@@ -345,7 +344,7 @@ template <class Derived> struct GenFuncBase {
QualType BaseEltQT;
std::array<Address, N> StartAddrs = Addrs;
for (unsigned I = 0; I < N; ++I)
- StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStackOffset, FD);
+ StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
Address DstAddr = StartAddrs[DstIdx];
llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
@@ -414,8 +413,7 @@ template <class Derived> struct GenFuncBase {
if (Offset.getQuantity() == 0)
return Addr;
Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
- Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity(),
- CharUnits::One());
+ Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
}
@@ -586,15 +584,15 @@ struct GenDestructor : StructVisitor<GenDestructor>,
}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
+ CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
CGF->destroyARCStrongImprecise(
- *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 1> Addrs) {
CGF->destroyARCWeak(
- *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
@@ -627,35 +625,35 @@ struct GenDefaultInitialize
}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
+ CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
CGF->EmitNullInitialization(
- getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 1> Addrs) {
CGF->EmitNullInitialization(
- getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
template <class FieldKind, size_t... Is>
void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
- const FieldDecl *FD, CharUnits CurStackOffset,
+ const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 1> Addrs) {
if (!FK)
- return visitTrivial(QualType(AT, 0), FD, CurStackOffset, Addrs);
+ return visitTrivial(QualType(AT, 0), FD, CurStructOffset, Addrs);
ASTContext &Ctx = getContext();
CharUnits Size = Ctx.getTypeSizeInChars(QualType(AT, 0));
QualType EltTy = Ctx.getBaseElementType(QualType(AT, 0));
if (Size < CharUnits::fromQuantity(16) || EltTy->getAs<RecordType>()) {
- GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStackOffset, Addrs);
+ GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStructOffset, Addrs);
return;
}
llvm::Constant *SizeVal = CGF->Builder.getInt64(Size.getQuantity());
- Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
+ Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
Address Loc = CGF->Builder.CreateElementBitCast(DstAddr, CGF->Int8Ty);
CGF->Builder.CreateMemSet(Loc, CGF->Builder.getInt8(0), SizeVal,
IsVolatile);
@@ -673,24 +671,26 @@ struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
: GenBinaryFunc<GenCopyConstructor, false>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
llvm::Value *Val = CGF->EmitARCRetain(QT, SrcVal);
CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT), true);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
}
@@ -701,9 +701,9 @@ struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
: GenBinaryFunc<GenMoveConstructor, true>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
llvm::Value *SrcVal =
CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
@@ -712,15 +712,17 @@ struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
/* isInitialization */ true);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
}
@@ -731,24 +733,26 @@ struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
: GenBinaryFunc<GenCopyAssignment, false>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal,
false);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructCopyAssignmentOperator(
CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
@@ -760,9 +764,9 @@ struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
: GenBinaryFunc<GenMoveAssignment, true>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
llvm::Value *SrcVal =
CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
@@ -774,15 +778,17 @@ struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
CGF->EmitARCRelease(DstVal, ARCImpreciseLifetime);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructMoveAssignmentOperator(
CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
@@ -817,6 +823,29 @@ static void callSpecialFunction(G &&Gen, StringRef FuncName, QualType QT,
Gen.callFunc(FuncName, QT, Addrs, CGF);
}
+template <size_t N> std::array<Address, N> createNullAddressArray();
+
+template <> std::array<Address, 1> createNullAddressArray() {
+ return std::array<Address, 1>({{Address(nullptr, CharUnits::Zero())}});
+}
+
+template <> std::array<Address, 2> createNullAddressArray() {
+ return std::array<Address, 2>({{Address(nullptr, CharUnits::Zero()),
+ Address(nullptr, CharUnits::Zero())}});
+}
+
+template <class G, size_t N>
+static llvm::Function *
+getSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile,
+ std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
+ QT = IsVolatile ? QT.withVolatile() : QT;
+ // The following call requires an array of addresses as arguments, but doesn't
+ // actually use them (it overwrites them with the addresses of the arguments
+ // of the created function).
+ return Gen.getFunction(FuncName, QT, createNullAddressArray<N>(), Alignments,
+ CGM);
+}
+
// Functions to emit calls to the special functions of a non-trivial C struct.
void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
bool IsVolatile = Dst.isVolatile();
@@ -828,18 +857,16 @@ void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
IsVolatile, *this, std::array<Address, 1>({{DstPtr}}));
}
-std::string
-CodeGenFunction::getNonTrivialCopyConstructorStr(QualType QT,
- CharUnits Alignment,
- bool IsVolatile,
- ASTContext &Ctx) {
+std::string CodeGenFunction::getNonTrivialCopyConstructorStr(
+ QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx) {
GenBinaryFuncName<false> GenName("", Alignment, Alignment, Ctx);
return GenName.getName(QT, IsVolatile);
}
-std::string
-CodeGenFunction::getNonTrivialDestructorStr(QualType QT, CharUnits Alignment,
- bool IsVolatile, ASTContext &Ctx) {
+std::string CodeGenFunction::getNonTrivialDestructorStr(QualType QT,
+ CharUnits Alignment,
+ bool IsVolatile,
+ ASTContext &Ctx) {
GenDestructorFuncName GenName("", Alignment, Ctx);
return GenName.getName(QT, IsVolatile);
}
@@ -904,3 +931,69 @@ void CodeGenFunction::callCStructMoveAssignmentOperator(LValue Dst, LValue Src
callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile,
*this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructDefaultConstructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(GenDefaultInitialize(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 1>({{DstAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructCopyConstructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<false> GenName("__copy_constructor_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructMoveConstructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<true> GenName("__move_constructor_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructCopyAssignmentOperator(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<false> GenName("__copy_assignment_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructMoveAssignmentOperator(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<true> GenName("__move_assignment_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructDestructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenDestructorFuncName GenName("__destructor_", DstAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(GenDestructor(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 1>({{DstAlignment}}), CGM);
+}