forked from OSchip/llvm-project
Fix for PR3687: use the memory representation for booleans when a
sub-type describes a memory location, like the pointee type of a pointer or the element type of an array. llvm-svn: 65925
This commit is contained in:
parent
463421deb1
commit
78350edafb
|
@ -91,7 +91,7 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
|||
// We can handle bare pointers here because we know that the only pointers
|
||||
// to the Opaque type are P.second and from other types. Refining the
|
||||
// opqaue type away will invalidate P.second, but we don't mind :).
|
||||
const llvm::Type *NT = ConvertTypeRecursive(P.first);
|
||||
const llvm::Type *NT = ConvertTypeForMemRecursive(P.first);
|
||||
P.second->refineAbstractTypeTo(NT);
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,13 @@ const llvm::Type *CodeGenTypes::ConvertTypeRecursive(QualType T) {
|
|||
return ResultType;
|
||||
}
|
||||
|
||||
const llvm::Type *CodeGenTypes::ConvertTypeForMemRecursive(QualType T) {
|
||||
const llvm::Type *ResultType = ConvertTypeRecursive(T);
|
||||
if (ResultType == llvm::Type::Int1Ty)
|
||||
return llvm::IntegerType::get((unsigned)Context.getTypeSize(T));
|
||||
return ResultType;
|
||||
}
|
||||
|
||||
/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
|
||||
/// ConvertType in that it is used to convert to the memory representation for
|
||||
/// a type. For example, the scalar representation for _Bool is i1, but the
|
||||
|
@ -245,18 +252,18 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
|||
"FIXME: We only handle trivial array types so far!");
|
||||
// VLAs resolve to the innermost element type; this matches
|
||||
// the return of alloca, and there isn't any obviously better choice.
|
||||
return ConvertTypeRecursive(A.getElementType());
|
||||
return ConvertTypeForMemRecursive(A.getElementType());
|
||||
}
|
||||
case Type::IncompleteArray: {
|
||||
const IncompleteArrayType &A = cast<IncompleteArrayType>(Ty);
|
||||
assert(A.getIndexTypeQualifier() == 0 &&
|
||||
"FIXME: We only handle trivial array types so far!");
|
||||
// int X[] -> [0 x int]
|
||||
return llvm::ArrayType::get(ConvertTypeRecursive(A.getElementType()), 0);
|
||||
return llvm::ArrayType::get(ConvertTypeForMemRecursive(A.getElementType()), 0);
|
||||
}
|
||||
case Type::ConstantArray: {
|
||||
const ConstantArrayType &A = cast<ConstantArrayType>(Ty);
|
||||
const llvm::Type *EltTy = ConvertTypeRecursive(A.getElementType());
|
||||
const llvm::Type *EltTy = ConvertTypeForMemRecursive(A.getElementType());
|
||||
return llvm::ArrayType::get(EltTy, A.getSize().getZExtValue());
|
||||
}
|
||||
case Type::ExtVector:
|
||||
|
@ -481,7 +488,7 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
|
|||
FieldEnd = RD.field_end();
|
||||
Field != FieldEnd; ++Field) {
|
||||
uint64_t offset = RL.getFieldOffset(curField);
|
||||
const llvm::Type *Ty = CGT.ConvertTypeRecursive(Field->getType());
|
||||
const llvm::Type *Ty = CGT.ConvertTypeForMemRecursive(Field->getType());
|
||||
uint64_t size = CGT.getTargetData().getTypePaddedSizeInBits(Ty);
|
||||
|
||||
if (Field->isBitField()) {
|
||||
|
|
|
@ -144,6 +144,7 @@ public:
|
|||
/// a type. For example, the scalar representation for _Bool is i1, but the
|
||||
/// memory representation is usually i8 or i32, depending on the target.
|
||||
const llvm::Type *ConvertTypeForMem(QualType T);
|
||||
const llvm::Type *ConvertTypeForMemRecursive(QualType T);
|
||||
|
||||
/// GetFunctionType - Get the LLVM function type for \arg Info.
|
||||
const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info,
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// RUN: clang -emit-llvm < %s | grep i1 | count 1
|
||||
// All of these should uses the memory representation of _Bool
|
||||
struct teststruct1 {_Bool a, b;} test1;
|
||||
_Bool* test2;
|
||||
_Bool test3[10];
|
||||
_Bool (*test4)[];
|
||||
|
Loading…
Reference in New Issue