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);
|
InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
|
||||||
|
|
||||||
// C99 6.2.5p11.
|
// C99 6.2.5p11.
|
||||||
InitBuiltinType(FloatComplexTy, BuiltinType::FloatComplex);
|
FloatComplexTy = getComplexType(FloatTy);
|
||||||
InitBuiltinType(DoubleComplexTy, BuiltinType::DoubleComplex);
|
DoubleComplexTy = getComplexType(DoubleTy);
|
||||||
InitBuiltinType(LongDoubleComplexTy, BuiltinType::LongDoubleComplex);
|
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
|
/// getPointerType - Return the uniqued reference to the type for a pointer to
|
||||||
/// the specified type.
|
/// the specified type.
|
||||||
QualType ASTContext::getPointerType(QualType T) {
|
QualType ASTContext::getPointerType(QualType T) {
|
||||||
|
@ -399,19 +428,16 @@ static int getIntegerRank(QualType t) {
|
||||||
|
|
||||||
/// getFloatingRank - Return a relative rank for floating point types.
|
/// getFloatingRank - Return a relative rank for floating point types.
|
||||||
/// This routine will assert if passed a built-in type that isn't a float.
|
/// This routine will assert if passed a built-in type that isn't a float.
|
||||||
static int getFloatingRank(QualType t) {
|
static int getFloatingRank(QualType T) {
|
||||||
switch (cast<BuiltinType>(t.getCanonicalType())->getKind()) {
|
T = T.getCanonicalType();
|
||||||
default:
|
if (ComplexType *CT = dyn_cast<ComplexType>(T))
|
||||||
assert(0 && "getFloatingPointRank(): not a floating type");
|
return getFloatingRank(CT->getElementType());
|
||||||
case BuiltinType::Float:
|
|
||||||
case BuiltinType::FloatComplex:
|
switch (cast<BuiltinType>(T)->getKind()) {
|
||||||
return FloatRank;
|
default: assert(0 && "getFloatingPointRank(): not a floating type");
|
||||||
case BuiltinType::Double:
|
case BuiltinType::Float: return FloatRank;
|
||||||
case BuiltinType::DoubleComplex:
|
case BuiltinType::Double: return DoubleRank;
|
||||||
return DoubleRank;
|
case BuiltinType::LongDouble: return LongDoubleRank;
|
||||||
case BuiltinType::LongDouble:
|
|
||||||
case BuiltinType::LongDoubleComplex:
|
|
||||||
return LongDoubleRank;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,14 +458,10 @@ static int getFloatingRank(QualType t) {
|
||||||
|
|
||||||
QualType ASTContext::maxComplexType(QualType lt, QualType rt) const {
|
QualType ASTContext::maxComplexType(QualType lt, QualType rt) const {
|
||||||
switch (std::max(getFloatingRank(lt), getFloatingRank(rt))) {
|
switch (std::max(getFloatingRank(lt), getFloatingRank(rt))) {
|
||||||
default:
|
default: assert(0 && "convertRankToComplex(): illegal value for rank");
|
||||||
assert(0 && "convertRankToComplex(): illegal value for rank");
|
case FloatRank: return FloatComplexTy;
|
||||||
case FloatRank:
|
case DoubleRank: return DoubleComplexTy;
|
||||||
return FloatComplexTy;
|
case LongDoubleRank: return LongDoubleComplexTy;
|
||||||
case DoubleRank:
|
|
||||||
return DoubleComplexTy;
|
|
||||||
case LongDoubleRank:
|
|
||||||
return LongDoubleComplexTy;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,9 @@ bool Type::isUnsignedIntegerType() const {
|
||||||
bool Type::isFloatingType() const {
|
bool Type::isFloatingType() const {
|
||||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||||
return BT->getKind() >= BuiltinType::Float &&
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,32 +275,27 @@ bool Type::isRealType() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Type::isComplexType() const {
|
bool Type::isComplexType() const {
|
||||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
return isa<ComplexType>(CanonicalType);
|
||||||
return BT->getKind() >= BuiltinType::FloatComplex &&
|
|
||||||
BT->getKind() <= BuiltinType::LongDoubleComplex;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Type::isArithmeticType() const {
|
bool Type::isArithmeticType() const {
|
||||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||||
return BT->getKind() >= BuiltinType::Bool &&
|
return BT->getKind() != BuiltinType::Void;
|
||||||
BT->getKind() <= BuiltinType::LongDoubleComplex;
|
|
||||||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
|
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
|
||||||
if (TT->getDecl()->getKind() == Decl::Enum)
|
if (TT->getDecl()->getKind() == Decl::Enum)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return isa<ComplexType>(CanonicalType);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Type::isScalarType() const {
|
bool Type::isScalarType() const {
|
||||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||||
return BT->getKind() >= BuiltinType::Bool &&
|
return BT->getKind() != BuiltinType::Void;
|
||||||
BT->getKind() <= BuiltinType::LongDoubleComplex;
|
|
||||||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
|
if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
|
||||||
if (TT->getDecl()->getKind() == Decl::Enum)
|
if (TT->getDecl()->getKind() == Decl::Enum)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return CanonicalType->getTypeClass() == Pointer;
|
return isa<PointerType>(CanonicalType) || isa<ComplexType>(CanonicalType);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Type::isAggregateType() const {
|
bool Type::isAggregateType() const {
|
||||||
|
@ -378,9 +375,6 @@ const char *BuiltinType::getName() const {
|
||||||
case Float: return "float";
|
case Float: return "float";
|
||||||
case Double: return "double";
|
case Double: return "double";
|
||||||
case LongDouble: return "long 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 {
|
void PointerType::getAsStringInternal(std::string &S) const {
|
||||||
S = '*' + S;
|
S = '*' + S;
|
||||||
|
|
||||||
|
|
|
@ -150,17 +150,13 @@ llvm::Value *CodeGenFunction::ConvertScalarValueToBool(RValue Val, QualType Ty){
|
||||||
Result = Builder.CreateFCmpUNE(Result, Zero, "tobool");
|
Result = Builder.CreateFCmpUNE(Result, Zero, "tobool");
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BuiltinType::FloatComplex:
|
|
||||||
case BuiltinType::DoubleComplex:
|
|
||||||
case BuiltinType::LongDoubleComplex:
|
|
||||||
assert(0 && "comparisons against complex not implemented yet");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else if (isa<PointerType>(Ty) ||
|
||||||
assert((isa<PointerType>(Ty) ||
|
cast<TagType>(Ty)->getDecl()->getKind() == Decl::Enum) {
|
||||||
cast<TagType>(Ty)->getDecl()->getKind() == Decl::Enum) &&
|
|
||||||
"Unknown scalar type");
|
|
||||||
// Code below handles this fine.
|
// 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.
|
// Usual case for integers, pointers, and enums: compare against zero.
|
||||||
|
|
|
@ -63,24 +63,15 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
// FIXME: mapping long double onto double.
|
// FIXME: mapping long double onto double.
|
||||||
return llvm::Type::DoubleTy;
|
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;
|
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: {
|
case Type::Pointer: {
|
||||||
const PointerType &P = cast<PointerType>(Ty);
|
const PointerType &P = cast<PointerType>(Ty);
|
||||||
return llvm::PointerType::get(ConvertType(P.getPointeeType()));
|
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.
|
/// decls) that can be referred to throughout the semantic analysis of a file.
|
||||||
class ASTContext {
|
class ASTContext {
|
||||||
std::vector<Type*> Types;
|
std::vector<Type*> Types;
|
||||||
|
llvm::FoldingSet<ComplexType> ComplexTypes;
|
||||||
llvm::FoldingSet<PointerType> PointerTypes;
|
llvm::FoldingSet<PointerType> PointerTypes;
|
||||||
llvm::FoldingSet<ReferenceType> ReferenceTypes;
|
llvm::FoldingSet<ReferenceType> ReferenceTypes;
|
||||||
llvm::FoldingSet<ArrayType> ArrayTypes;
|
llvm::FoldingSet<ArrayType> ArrayTypes;
|
||||||
|
@ -52,6 +53,10 @@ public:
|
||||||
~ASTContext();
|
~ASTContext();
|
||||||
|
|
||||||
void PrintStats() const;
|
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
|
/// getPointerType - Return the uniqued reference to the type for a pointer to
|
||||||
/// the specified type.
|
/// the specified type.
|
||||||
|
|
|
@ -179,7 +179,7 @@ namespace clang {
|
||||||
class Type {
|
class Type {
|
||||||
public:
|
public:
|
||||||
enum TypeClass {
|
enum TypeClass {
|
||||||
Builtin, Pointer, Reference, Array, FunctionNoProto, FunctionProto,
|
Builtin, Complex, Pointer, Reference, Array, FunctionNoProto, FunctionProto,
|
||||||
TypeName, Tagged
|
TypeName, Tagged
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
|
@ -188,7 +188,7 @@ private:
|
||||||
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
|
/// 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
|
/// Note that this should stay at the end of the ivars for Type so that
|
||||||
/// subclasses can pack their bitfields into the same word.
|
/// subclasses can pack their bitfields into the same word.
|
||||||
TypeClass TC : 3;
|
TypeClass TC : 4;
|
||||||
protected:
|
protected:
|
||||||
Type(TypeClass tc, QualType Canonical)
|
Type(TypeClass tc, QualType Canonical)
|
||||||
: CanonicalType(Canonical.isNull() ? QualType(this,0) : Canonical), TC(tc){}
|
: CanonicalType(Canonical.isNull() ? QualType(this,0) : Canonical), TC(tc){}
|
||||||
|
@ -293,8 +293,8 @@ public:
|
||||||
Long,
|
Long,
|
||||||
LongLong,
|
LongLong,
|
||||||
|
|
||||||
Float, Double, LongDouble,
|
Float, Double, LongDouble//,
|
||||||
FloatComplex, DoubleComplex, LongDoubleComplex
|
// FloatComplex, DoubleComplex, LongDoubleComplex
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
Kind TypeKind;
|
Kind TypeKind;
|
||||||
|
@ -310,6 +310,33 @@ public:
|
||||||
static bool classof(const BuiltinType *) { return true; }
|
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.
|
/// PointerType - C99 6.7.5.1 - Pointer Declarators.
|
||||||
///
|
///
|
||||||
class PointerType : public Type, public llvm::FoldingSetNode {
|
class PointerType : public Type, public llvm::FoldingSetNode {
|
||||||
|
|
Loading…
Reference in New Issue