forked from OSchip/llvm-project
Split complex types out from being members of BuiltinType to being their own
types. llvm-svn: 39672
This commit is contained in:
parent
f033c147c9
commit
c6395936ae
|
@ -132,11 +132,40 @@ void ASTContext::InitBuiltinTypes() {
|
|||
InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
|
||||
|
||||
// C99 6.2.5p11.
|
||||
InitBuiltinType(FloatComplexTy, BuiltinType::FloatComplex);
|
||||
InitBuiltinType(DoubleComplexTy, BuiltinType::DoubleComplex);
|
||||
InitBuiltinType(LongDoubleComplexTy, BuiltinType::LongDoubleComplex);
|
||||
FloatComplexTy = getComplexType(FloatTy);
|
||||
DoubleComplexTy = getComplexType(DoubleTy);
|
||||
LongDoubleComplexTy = getComplexType(LongDoubleTy);
|
||||
}
|
||||
|
||||
/// getComplexType - Return the uniqued reference to the type for a complex
|
||||
/// number with the specified element type.
|
||||
QualType ASTContext::getComplexType(QualType T) {
|
||||
// Unique pointers, to guarantee there is only one pointer of a particular
|
||||
// structure.
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ComplexType::Profile(ID, T);
|
||||
|
||||
void *InsertPos = 0;
|
||||
if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(CT, 0);
|
||||
|
||||
// If the pointee type isn't canonical, this won't be a canonical type either,
|
||||
// so fill in the canonical type field.
|
||||
QualType Canonical;
|
||||
if (!T->isCanonical()) {
|
||||
Canonical = getComplexType(T.getCanonicalType());
|
||||
|
||||
// Get the new insert position for the node we care about.
|
||||
ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
|
||||
assert(NewIP == 0 && "Shouldn't be in the map!");
|
||||
}
|
||||
ComplexType *New = new ComplexType(T, Canonical);
|
||||
Types.push_back(New);
|
||||
ComplexTypes.InsertNode(New, InsertPos);
|
||||
return QualType(New, 0);
|
||||
}
|
||||
|
||||
|
||||
/// getPointerType - Return the uniqued reference to the type for a pointer to
|
||||
/// the specified type.
|
||||
QualType ASTContext::getPointerType(QualType T) {
|
||||
|
@ -399,19 +428,16 @@ static int getIntegerRank(QualType t) {
|
|||
|
||||
/// getFloatingRank - Return a relative rank for floating point types.
|
||||
/// This routine will assert if passed a built-in type that isn't a float.
|
||||
static int getFloatingRank(QualType t) {
|
||||
switch (cast<BuiltinType>(t.getCanonicalType())->getKind()) {
|
||||
default:
|
||||
assert(0 && "getFloatingPointRank(): not a floating type");
|
||||
case BuiltinType::Float:
|
||||
case BuiltinType::FloatComplex:
|
||||
return FloatRank;
|
||||
case BuiltinType::Double:
|
||||
case BuiltinType::DoubleComplex:
|
||||
return DoubleRank;
|
||||
case BuiltinType::LongDouble:
|
||||
case BuiltinType::LongDoubleComplex:
|
||||
return LongDoubleRank;
|
||||
static int getFloatingRank(QualType T) {
|
||||
T = T.getCanonicalType();
|
||||
if (ComplexType *CT = dyn_cast<ComplexType>(T))
|
||||
return getFloatingRank(CT->getElementType());
|
||||
|
||||
switch (cast<BuiltinType>(T)->getKind()) {
|
||||
default: assert(0 && "getFloatingPointRank(): not a floating type");
|
||||
case BuiltinType::Float: return FloatRank;
|
||||
case BuiltinType::Double: return DoubleRank;
|
||||
case BuiltinType::LongDouble: return LongDoubleRank;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,14 +458,10 @@ static int getFloatingRank(QualType t) {
|
|||
|
||||
QualType ASTContext::maxComplexType(QualType lt, QualType rt) const {
|
||||
switch (std::max(getFloatingRank(lt), getFloatingRank(rt))) {
|
||||
default:
|
||||
assert(0 && "convertRankToComplex(): illegal value for rank");
|
||||
case FloatRank:
|
||||
return FloatComplexTy;
|
||||
case DoubleRank:
|
||||
return DoubleComplexTy;
|
||||
case LongDoubleRank:
|
||||
return LongDoubleComplexTy;
|
||||
default: assert(0 && "convertRankToComplex(): illegal value for rank");
|
||||
case FloatRank: return FloatComplexTy;
|
||||
case DoubleRank: return DoubleComplexTy;
|
||||
case LongDoubleRank: return LongDoubleComplexTy;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,9 @@ bool Type::isUnsignedIntegerType() const {
|
|||
bool Type::isFloatingType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Float &&
|
||||
BT->getKind() <= BuiltinType::LongDoubleComplex;
|
||||
BT->getKind() <= BuiltinType::LongDouble;
|
||||
if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
|
||||
return CT->isFloatingType();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -273,32 +275,27 @@ bool Type::isRealType() const {
|
|||
}
|
||||
|
||||
bool Type::isComplexType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::FloatComplex &&
|
||||
BT->getKind() <= BuiltinType::LongDoubleComplex;
|
||||
return false;
|
||||
return isa<ComplexType>(CanonicalType);
|
||||
}
|
||||
|
||||
bool Type::isArithmeticType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::LongDoubleComplex;
|
||||
return BT->getKind() != BuiltinType::Void;
|
||||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
|
||||
if (TT->getDecl()->getKind() == Decl::Enum)
|
||||
return true;
|
||||
return false;
|
||||
return isa<ComplexType>(CanonicalType);
|
||||
}
|
||||
|
||||
bool Type::isScalarType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::LongDoubleComplex;
|
||||
return BT->getKind() != BuiltinType::Void;
|
||||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
|
||||
if (TT->getDecl()->getKind() == Decl::Enum)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return CanonicalType->getTypeClass() == Pointer;
|
||||
return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType);
|
||||
}
|
||||
|
||||
bool Type::isAggregateType() const {
|
||||
|
@ -378,9 +375,6 @@ const char *BuiltinType::getName() const {
|
|||
case Float: return "float";
|
||||
case Double: return "double";
|
||||
case LongDouble: return "long double";
|
||||
case FloatComplex: return "float _Complex";
|
||||
case DoubleComplex: return "double _Complex";
|
||||
case LongDoubleComplex: return "long double _Complex";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,6 +452,11 @@ void BuiltinType::getAsStringInternal(std::string &S) const {
|
|||
}
|
||||
}
|
||||
|
||||
void ComplexType::getAsStringInternal(std::string &S) const {
|
||||
ElementType->getAsStringInternal(S);
|
||||
S = "_Complex " + S;
|
||||
}
|
||||
|
||||
void PointerType::getAsStringInternal(std::string &S) const {
|
||||
S = '*' + S;
|
||||
|
||||
|
|
|
@ -150,17 +150,13 @@ llvm::Value *CodeGenFunction::ConvertScalarValueToBool(RValue Val, QualType Ty){
|
|||
Result = Builder.CreateFCmpUNE(Result, Zero, "tobool");
|
||||
return Result;
|
||||
}
|
||||
|
||||
case BuiltinType::FloatComplex:
|
||||
case BuiltinType::DoubleComplex:
|
||||
case BuiltinType::LongDoubleComplex:
|
||||
assert(0 && "comparisons against complex not implemented yet");
|
||||
}
|
||||
} else {
|
||||
assert((isa<PointerType>(Ty) ||
|
||||
cast<TagType>(Ty)->getDecl()->getKind() == Decl::Enum) &&
|
||||
"Unknown scalar type");
|
||||
} else if (isa<PointerType>(Ty) ||
|
||||
cast<TagType>(Ty)->getDecl()->getKind() == Decl::Enum) {
|
||||
// Code below handles this fine.
|
||||
} else {
|
||||
assert(isa<ComplexType>(Ty) && "Unknwon type!");
|
||||
assert(0 && "FIXME: comparisons against complex not implemented yet");
|
||||
}
|
||||
|
||||
// Usual case for integers, pointers, and enums: compare against zero.
|
||||
|
|
|
@ -63,24 +63,15 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
|||
case BuiltinType::LongDouble:
|
||||
// FIXME: mapping long double onto double.
|
||||
return llvm::Type::DoubleTy;
|
||||
case BuiltinType::FloatComplex: {
|
||||
std::vector<const llvm::Type*> Elts;
|
||||
Elts.push_back(llvm::Type::FloatTy);
|
||||
Elts.push_back(llvm::Type::FloatTy);
|
||||
return llvm::StructType::get(Elts);
|
||||
}
|
||||
|
||||
case BuiltinType::LongDoubleComplex:
|
||||
// FIXME: mapping long double complex onto double complex.
|
||||
case BuiltinType::DoubleComplex: {
|
||||
std::vector<const llvm::Type*> Elts;
|
||||
Elts.push_back(llvm::Type::DoubleTy);
|
||||
Elts.push_back(llvm::Type::DoubleTy);
|
||||
return llvm::StructType::get(Elts);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type::Complex: {
|
||||
std::vector<const llvm::Type*> Elts;
|
||||
Elts.push_back(ConvertType(cast<ComplexType>(Ty).getElementType()));
|
||||
Elts.push_back(Elts[0]);
|
||||
return llvm::StructType::get(Elts);
|
||||
}
|
||||
case Type::Pointer: {
|
||||
const PointerType &P = cast<PointerType>(Ty);
|
||||
return llvm::PointerType::get(ConvertType(P.getPointeeType()));
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace clang {
|
|||
/// decls) that can be referred to throughout the semantic analysis of a file.
|
||||
class ASTContext {
|
||||
std::vector<Type*> Types;
|
||||
llvm::FoldingSet<ComplexType> ComplexTypes;
|
||||
llvm::FoldingSet<PointerType> PointerTypes;
|
||||
llvm::FoldingSet<ReferenceType> ReferenceTypes;
|
||||
llvm::FoldingSet<ArrayType> ArrayTypes;
|
||||
|
@ -52,6 +53,10 @@ public:
|
|||
~ASTContext();
|
||||
|
||||
void PrintStats() const;
|
||||
|
||||
/// getComplexType - Return the uniqued reference to the type for a complex
|
||||
/// number with the specified element type.
|
||||
QualType getComplexType(QualType T);
|
||||
|
||||
/// getPointerType - Return the uniqued reference to the type for a pointer to
|
||||
/// the specified type.
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace clang {
|
|||
class Type {
|
||||
public:
|
||||
enum TypeClass {
|
||||
Builtin, Pointer, Reference, Array, FunctionNoProto, FunctionProto,
|
||||
Builtin, Complex, Pointer, Reference, Array, FunctionNoProto, FunctionProto,
|
||||
TypeName, Tagged
|
||||
};
|
||||
private:
|
||||
|
@ -188,7 +188,7 @@ private:
|
|||
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
|
||||
/// Note that this should stay at the end of the ivars for Type so that
|
||||
/// subclasses can pack their bitfields into the same word.
|
||||
TypeClass TC : 3;
|
||||
TypeClass TC : 4;
|
||||
protected:
|
||||
Type(TypeClass tc, QualType Canonical)
|
||||
: CanonicalType(Canonical.isNull() ? QualType(this,0) : Canonical), TC(tc){}
|
||||
|
@ -293,8 +293,8 @@ public:
|
|||
Long,
|
||||
LongLong,
|
||||
|
||||
Float, Double, LongDouble,
|
||||
FloatComplex, DoubleComplex, LongDoubleComplex
|
||||
Float, Double, LongDouble//,
|
||||
// FloatComplex, DoubleComplex, LongDoubleComplex
|
||||
};
|
||||
private:
|
||||
Kind TypeKind;
|
||||
|
@ -310,6 +310,33 @@ public:
|
|||
static bool classof(const BuiltinType *) { return true; }
|
||||
};
|
||||
|
||||
/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex
|
||||
/// types (_Complex float etc) as well as the GCC integer complex extensions.
|
||||
///
|
||||
class ComplexType : public Type, public llvm::FoldingSetNode {
|
||||
QualType ElementType;
|
||||
ComplexType(QualType Element, QualType CanonicalPtr) :
|
||||
Type(Complex, CanonicalPtr), ElementType(Element) {
|
||||
}
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
public:
|
||||
QualType getElementType() const { return ElementType; }
|
||||
|
||||
virtual void getAsStringInternal(std::string &InnerString) const;
|
||||
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, getElementType());
|
||||
}
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
|
||||
ID.AddPointer(Element.getAsOpaquePtr());
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
|
||||
static bool classof(const ComplexType *) { return true; }
|
||||
};
|
||||
|
||||
|
||||
/// PointerType - C99 6.7.5.1 - Pointer Declarators.
|
||||
///
|
||||
class PointerType : public Type, public llvm::FoldingSetNode {
|
||||
|
|
Loading…
Reference in New Issue