forked from OSchip/llvm-project
x86-64 ABI: If a type is a C++ record with either a non-trivial destructor or a non-trivial copy constructor, it should be passed in a pointer. Daniel, plz review.
llvm-svn: 82050
This commit is contained in:
parent
a0f1088134
commit
20759ad54c
|
@ -388,7 +388,7 @@
|
|||
1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateInstantiateDecl.cpp; path = lib/Sema/SemaTemplateInstantiateDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
|
||||
1AE4EE3B103B89CA00888A23 /* TreeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TreeTransform.h; path = lib/Sema/TreeTransform.h; sourceTree = "<group>"; tabWidth = 2; };
|
||||
1AE4EE3D103B89ED00888A23 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtProfile.cpp; path = lib/AST/StmtProfile.cpp; sourceTree = "<group>"; tabWidth = 2; };
|
||||
1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TargetABIInfo.cpp; path = lib/CodeGen/TargetABIInfo.cpp; sourceTree = "<group>"; };
|
||||
1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = TargetABIInfo.cpp; path = lib/CodeGen/TargetABIInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
|
||||
1AFEF4050F8A6B2300476F2B /* clang-cc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = "clang-cc.cpp"; path = "tools/clang-cc/clang-cc.cpp"; sourceTree = "<group>"; tabWidth = 2; };
|
||||
1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGRecordLayoutBuilder.cpp; path = lib/CodeGen/CGRecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
|
||||
1AFF8AE21012BFC900D248DA /* CGRecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGRecordLayoutBuilder.h; path = lib/CodeGen/CGRecordLayoutBuilder.h; sourceTree = "<group>"; tabWidth = 2; };
|
||||
|
|
|
@ -72,11 +72,12 @@ namespace clang {
|
|||
Kind TheKind;
|
||||
const llvm::Type *TypeData;
|
||||
unsigned UIntData;
|
||||
bool BoolData;
|
||||
|
||||
ABIArgInfo(Kind K, const llvm::Type *TD=0,
|
||||
unsigned UI=0) : TheKind(K),
|
||||
TypeData(TD),
|
||||
UIntData(UI) {}
|
||||
unsigned UI=0, bool B = false)
|
||||
: TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {}
|
||||
|
||||
public:
|
||||
ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
|
||||
|
||||
|
@ -92,8 +93,8 @@ namespace clang {
|
|||
static ABIArgInfo getCoerce(const llvm::Type *T) {
|
||||
return ABIArgInfo(Coerce, T);
|
||||
}
|
||||
static ABIArgInfo getIndirect(unsigned Alignment) {
|
||||
return ABIArgInfo(Indirect, 0, Alignment);
|
||||
static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
|
||||
return ABIArgInfo(Indirect, 0, Alignment, ByVal);
|
||||
}
|
||||
static ABIArgInfo getExpand() {
|
||||
return ABIArgInfo(Expand);
|
||||
|
@ -113,12 +114,17 @@ namespace clang {
|
|||
return TypeData;
|
||||
}
|
||||
|
||||
// ByVal accessors
|
||||
// Indirect accessors
|
||||
unsigned getIndirectAlign() const {
|
||||
assert(TheKind == Indirect && "Invalid kind!");
|
||||
return UIntData;
|
||||
}
|
||||
|
||||
bool getIndirectByVal() const {
|
||||
assert(TheKind == Indirect && "Invalid kind!");
|
||||
return BoolData;
|
||||
}
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -492,7 +492,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
|
|||
break;
|
||||
|
||||
case ABIArgInfo::Indirect:
|
||||
Attributes |= llvm::Attribute::ByVal;
|
||||
if (AI.getIndirectByVal())
|
||||
Attributes |= llvm::Attribute::ByVal;
|
||||
|
||||
Attributes |=
|
||||
llvm::Attribute::constructAlignmentFromInt(AI.getIndirectAlign());
|
||||
// byval disables readnone and readonly.
|
||||
|
|
|
@ -86,6 +86,27 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// hasNonTrivialDestructorOrCopyConstructor - Determine if a type has either
|
||||
/// a non-trivial destructor or a non-trivial copy constructor.
|
||||
static bool hasNonTrivialDestructorOrCopyConstructor(const RecordType *RT) {
|
||||
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
|
||||
if (!RD)
|
||||
return false;
|
||||
|
||||
return !RD->hasTrivialDestructor() || !RD->hasTrivialCopyConstructor();
|
||||
}
|
||||
|
||||
/// isRecordWithNonTrivialDestructorOrCopyConstructor - Determine if a type is
|
||||
/// a record type with either a non-trivial destructor or a non-trivial copy
|
||||
/// constructor.
|
||||
static bool isRecordWithNonTrivialDestructorOrCopyConstructor(QualType T) {
|
||||
const RecordType *RT = T->getAs<RecordType>();
|
||||
if (!RT)
|
||||
return false;
|
||||
|
||||
return hasNonTrivialDestructorOrCopyConstructor(RT);
|
||||
}
|
||||
|
||||
/// isSingleElementStruct - Determine if a structure is a "single
|
||||
/// element struct", i.e. it has exactly one non-empty field or
|
||||
/// exactly one field which is itself a single element
|
||||
|
@ -717,6 +738,12 @@ void X86_64ABIInfo::classify(QualType Ty,
|
|||
if (Size > 128)
|
||||
return;
|
||||
|
||||
// AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial
|
||||
// copy constructor or a non-trivial destructor, it is passed by invisible
|
||||
// reference.
|
||||
if (hasNonTrivialDestructorOrCopyConstructor(RT))
|
||||
return;
|
||||
|
||||
const RecordDecl *RD = RT->getDecl();
|
||||
|
||||
// Assume variable sized types are passed in memory.
|
||||
|
@ -830,8 +857,10 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
|
|||
return (Ty->isPromotableIntegerType() ?
|
||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
|
||||
bool ByVal = !isRecordWithNonTrivialDestructorOrCopyConstructor(Ty);
|
||||
|
||||
// FIXME: Set alignment correctly.
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
return ABIArgInfo::getIndirect(0, ByVal);
|
||||
}
|
||||
|
||||
ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s &&
|
||||
struct A { ~A(); };
|
||||
|
||||
// RUN: grep 'define void @_Z2f11A(.struct.A\* .a)' %t &&
|
||||
void f1(A a) { }
|
||||
|
||||
// RUN: grep 'define void @_Z2f2v(.struct.A\* noalias sret .agg.result)' %t &&
|
||||
A f2() { return A(); }
|
||||
|
||||
// RUN: true
|
Loading…
Reference in New Issue