diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h --- a/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -26,12 +26,14 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/Type.h" #include "clang/CodeGen/CGFunctionInfo.h" +#include "llvm/IR/BasicBlock.h" namespace llvm { class DataLayout; class Module; class FunctionType; class Type; + class Value; } namespace clang { @@ -83,6 +85,52 @@ unsigned getLLVMFieldNumber(CodeGenModule &CGM, const RecordDecl *RD, const FieldDecl *FD); +/// Generates a call to the default constructor for a C struct with +/// non-trivially copyable fields. +void callNonTrivialCStructDefaultConstructor( + CodeGenModule &GCM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits Alignment, QualType QT); + +/// Generates a call to the copy constructor for a C struct with non-trivially +/// copyable fields. +void callNonTrivialCStructCopyConstructor( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT); + +/// Generates a call to the move constructor for a C struct with non-trivially +/// copyable fields. +void callNonTrivialCStructMoveConstructor( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT); + +/// Generates a call to the copy assignment operator for a C struct with +/// non-trivially copyable fields. +void callNonTrivialCStructCopyAssignmentOperator( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT); + +/// Generates a call to the move assignment operator for a C struct with +/// non-trivially copyable fields. +void callNonTrivialCStructMoveAssignmentOperator( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT); + +/// Generates a call to the destructor for a C struct with non-trivially +/// copyable fields. +void callNonTrivialCStructDestructor(CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, + llvm::Value *Dst, CharUnits Alignment, + QualType QT); + } // end namespace CodeGen } // end namespace clang diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -14,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 @@ -907,3 +908,71 @@ callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile, *this, std::array({{DstPtr, SrcPtr}})); } + +void clang::CodeGen::callNonTrivialCStructDefaultConstructor( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, QualType QT) { + CodeGenFunction CGF(CGM, true); + CGF.Builder.SetInsertPoint(BB, InsertPoint); + LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment); + CGF.callCStructDefaultConstructor(DstLValue); +} + +void clang::CodeGen::callNonTrivialCStructCopyConstructor( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT) { + CodeGenFunction CGF(CGM, true); + CGF.Builder.SetInsertPoint(BB, InsertPoint); + LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment); + LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment); + CGF.callCStructCopyConstructor(DstLValue, SrcLValue); +} + +void clang::CodeGen::callNonTrivialCStructMoveConstructor( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT) { + CodeGenFunction CGF(CGM, true); + CGF.Builder.SetInsertPoint(BB, InsertPoint); + LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment); + LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment); + CGF.callCStructMoveConstructor(DstLValue, SrcLValue); +} + +void clang::CodeGen::callNonTrivialCStructCopyAssignmentOperator( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT) { + CodeGenFunction CGF(CGM, true); + CGF.Builder.SetInsertPoint(BB, InsertPoint); + LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment); + LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment); + CGF.callCStructCopyAssignmentOperator(DstLValue, SrcLValue); +} + +void clang::CodeGen::callNonTrivialCStructMoveAssignmentOperator( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment, + QualType QT) { + CodeGenFunction CGF(CGM, true); + CGF.Builder.SetInsertPoint(BB, InsertPoint); + LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment); + LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment); + CGF.callCStructMoveAssignmentOperator(DstLValue, SrcLValue); +} + +void clang::CodeGen::callNonTrivialCStructDestructor( + CodeGenModule &CGM, llvm::BasicBlock *BB, + llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst, + CharUnits Alignment, QualType QT) { + CodeGenFunction CGF(CGM, true); + CGF.Builder.SetInsertPoint(BB, InsertPoint); + LValue lvalue = CGF.MakeAddrLValue(Dst, QT, Alignment); + CGF.callCStructDestructor(lvalue); +}