summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-19 16:27:51 +0100
committerarphaman <arphaman@gmail.com>2013-09-19 16:27:51 +0100
commit3b95e9a2d88dbcc4e83ce1184a591f15f21add9b (patch)
treeba286f7e458b9838ae642f5ddccc1fc0b70e7a5e
parent2d9553a89153be4ed76408c439e749b88a16b8d2 (diff)
downloadflang-3b95e9a2d88dbcc4e83ce1184a591f15f21add9b.tar.gz
Moved type kinds from ExtQuals to Type
-rw-r--r--include/flang/AST/ASTContext.h143
-rw-r--r--include/flang/AST/Type.h133
-rw-r--r--include/flang/AST/TypeVisitor.h9
-rw-r--r--include/flang/Sema/Sema.h6
-rw-r--r--lib/AST/ASTContext.cpp93
-rw-r--r--lib/AST/ASTDumper.cpp33
-rw-r--r--lib/AST/ExprConstant.cpp7
-rw-r--r--lib/CodeGen/CGCall.cpp4
-rw-r--r--lib/CodeGen/CGDecl.cpp7
-rw-r--r--lib/CodeGen/CGIOLibflang.cpp5
-rw-r--r--lib/CodeGen/CGIntrinsic.cpp2
-rw-r--r--lib/CodeGen/CGStmt.cpp11
-rw-r--r--lib/CodeGen/CGSystemLibflang.cpp3
-rw-r--r--lib/CodeGen/CodeGenFunction.h1
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp87
-rw-r--r--lib/CodeGen/CodeGenTypes.h3
-rw-r--r--lib/CodeGen/TargetInfo.cpp3
-rw-r--r--lib/Sema/SemaChecking.cpp64
-rw-r--r--lib/Sema/SemaDecl.cpp40
-rw-r--r--lib/Sema/SemaExpr.cpp83
-rw-r--r--lib/Sema/SemaIntrinsic.cpp10
-rw-r--r--lib/Sema/Spec.cpp22
22 files changed, 312 insertions, 457 deletions
diff --git a/include/flang/AST/ASTContext.h b/include/flang/AST/ASTContext.h
index 0708c96b7a..5191122dcd 100644
--- a/include/flang/AST/ASTContext.h
+++ b/include/flang/AST/ASTContext.h
@@ -43,6 +43,7 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
mutable std::vector<Type*> Types;
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
+ mutable llvm::FoldingSet<BuiltinType> BuiltinTypes;
mutable llvm::FoldingSet<CharacterType> CharTypes;
mutable llvm::FoldingSet<PointerType> PointerTypes;
mutable llvm::FoldingSet<ArrayType> ArrayTypes;
@@ -62,103 +63,9 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
LangOptions LanguageOptions;
- //===--------------------------------------------------------------------===//
- // Type Constructors
- //===--------------------------------------------------------------------===//
-
-public:
- /// getExtQualType - Return a type with extended qualifiers.
- QualType getExtQualType(const Type *Base, Qualifiers Quals,
- unsigned KindSel = BuiltinType::NoKind, bool IsDoublePrecisionKind = false) const;
- QualType getQualTypeOtherKind(QualType Type, QualType KindType);
- QualType getComplexTypeElementType(QualType Type);
- QualType getComplexType(QualType ElementType);
- QualType getTypeWithQualifers(QualType Type, Qualifiers Quals);
-
- const llvm::fltSemantics& getFPTypeSemantics(QualType Type);
-
- /// \brief Returns the kind of an integer type or the
- /// default integer kind if the type has no extended
- /// qualifiers or if kind wasn't specified.
- BuiltinType::TypeKind getIntTypeKind(const ExtQuals *Ext) const {
- return Ext && Ext->hasKindSelector()? Ext->getKindSelector() :
- BuiltinType::Int4;
- }
-
- /// \brief Returns the kind of a logical type or the
- /// default logical kind if the type has no extended
- /// qualifiers or if kind wasn't specified.
- BuiltinType::TypeKind getLogicalTypeKind(const ExtQuals *Ext) const {
- return Ext && Ext->hasKindSelector()? Ext->getKindSelector() :
- BuiltinType::Int4;
- }
-
- /// \brief Returns the kind of a real type or the
- /// default real kind if the type has no extended
- /// qualifiers or if kind wasn't specified.
- BuiltinType::TypeKind getRealTypeKind(const ExtQuals *Ext) const {
- return Ext && Ext->hasKindSelector()? Ext->getKindSelector() :
- BuiltinType::Real4;
- }
-
- /// \brief Returns the kind of a complex type or the
- /// default complex kind if the type has no extended
- /// qualifiers or if kind wasn't specified.
- BuiltinType::TypeKind getComplexTypeKind(const ExtQuals *Ext) const {
- return Ext && Ext->hasKindSelector()? Ext->getKindSelector() :
- BuiltinType::Real4;
- }
-
- /// \brief Returns the kind of a real or complex type or the appropriate
- /// default kind if the type has no extended qualifiers or if the kind
- /// wasn't specified.
- BuiltinType::TypeKind getRealOrComplexTypeKind(const ExtQuals *Ext,
- QualType T) const {
- if(T->isRealType()) return getRealTypeKind(Ext);
- else return getComplexTypeKind(Ext);
- }
-
- /// \brief Returns the kind of an integer, real or complex type
- /// or the appropriate default kind if the type has no extended
- /// qualifiers or if the kind wasn't specified.
- BuiltinType::TypeKind getArithmeticTypeKind(const ExtQuals *Ext,
- QualType T) const {
- if(T->isIntegerType()) return getIntTypeKind(Ext);
- else if(T->isRealType()) return getRealTypeKind(Ext);
- else return getComplexTypeKind(Ext);
- }
-
- /// \brief Returns the kind of an integer, real, logical or complex type
- /// or the appropriate default kind if the type has no extended
- /// qualifiers or if the kind wasn't specified.
- BuiltinType::TypeKind getArithmeticOrLogicalTypeKind(const ExtQuals *Ext,
- QualType T) const {
- if(T->isIntegerType()) return getIntTypeKind(Ext);
- else if(T->isRealType()) return getRealTypeKind(Ext);
- else if(T->isComplexType()) return getLogicalTypeKind(Ext);
- else return getComplexTypeKind(Ext);
- }
-
- /// \brief Returns true if two arithmetic types have the same kind
- bool ArithmeticTypesSameKind(const ExtQuals *AExt, QualType A,
- const ExtQuals *BExt, QualType B) const {
- return getArithmeticTypeKind(AExt, A) ==
- getArithmeticTypeKind(BExt, B);
- }
-
- /// \brief Returns the amount of bits that an arithmetic type kind occupies
- unsigned getTypeKindBitWidth(BuiltinType::TypeKind Kind) const;
-
- /// \brief Returns a type kind big enough to store a value
- /// ranging from -10^Range to 10^Range, or
- /// NoKind if such value can't be stored.
- BuiltinType::TypeKind getSelectedIntKind(int64_t Range) const;
-
-private:
QualType getTypeDeclTypeSlow(const TypeDecl *Decl);
void InitBuiltinTypes();
- void InitBuiltinType(QualType &R, BuiltinType::TypeSpec K);
public:
ASTContext(llvm::SourceMgr &SM, LangOptions LangOpts);
@@ -185,16 +92,45 @@ public:
QualType IntegerTy;
QualType RealTy;
QualType DoublePrecisionTy;
- QualType CharacterTy;
QualType LogicalTy;
QualType ComplexTy;
QualType DoubleComplexTy;
+ QualType CharacterTy;
+
+ /// \brief This is a character type with a '*' length specification
QualType NoLengthCharacterTy;
- /// getBuiltinQualType - Return the QualType for the specified builtin type.
- QualType getBuiltinQualType(BuiltinType::TypeSpec TS) const;
+ bool isTypeDoublePrecision(QualType T) const {
+ return T->getBuiltinTypeKind() == DoublePrecisionTy->getBuiltinTypeKind();
+ }
+
+ bool isTypeDoubleComplex(QualType T) const {
+ return T->getBuiltinTypeKind() == DoubleComplexTy->getBuiltinTypeKind();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Type Constructors
+ //===--------------------------------------------------------------------===//
+
+ /// getExtQualType - Return a type with extended qualifiers.
+ QualType getExtQualType(const Type *Base, Qualifiers Quals) const;
+ QualType getQualTypeOtherKind(QualType Type, QualType KindType);
+ QualType getTypeWithQualifers(QualType Type, Qualifiers Quals);
+
+ /// getBuiltinType - Return the unique reference for the specified builtin type.
+ BuiltinType *getBuiltinType(BuiltinType::TypeSpec TS,
+ BuiltinType::TypeKind Kind,
+ bool IsKindExplicitlySpecified = false,
+ bool IsDoublePrecisionKindSpecified = false);
+
+ /// getComplexTypeElementType - Returns the type of an element in a complex pair.
+ QualType getComplexTypeElementType(QualType Type);
+
+ /// getComplexType - Returns the unique reference for a complex type
+ /// with a given element type.
+ QualType getComplexType(QualType ElementType);
- /// getCharacterType - Return the QualType for the specified character type.
+ /// getCharacterType - Return the unique reference for the specified character type.
CharacterType *getCharacterType(uint64_t Length) const;
/// getPointerType - Return the uniqued reference to the type for a pointer to
@@ -261,6 +197,17 @@ public:
return T->getCanonicalTypeInternal().getTypePtr();
}
+ /// \brief Returns the floating point semantics for the given real type.
+ const llvm::fltSemantics& getFPTypeSemantics(QualType Type);
+
+ /// \brief Returns the amount of bits that an arithmetic type kind occupies.
+ unsigned getTypeKindBitWidth(BuiltinType::TypeKind Kind) const;
+
+ /// \brief Returns a type kind big enough to store a value
+ /// ranging from -10^Range to 10^Range, or
+ /// NoKind if such value can't be stored.
+ BuiltinType::TypeKind getSelectedIntKind(int64_t Range) const;
+
private:
// FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext,
diff --git a/include/flang/AST/Type.h b/include/flang/AST/Type.h
index 9f93e512a2..75400901a1 100644
--- a/include/flang/AST/Type.h
+++ b/include/flang/AST/Type.h
@@ -37,6 +37,7 @@ namespace flang {
class Type;
class ExtQuals;
class QualType;
+ class BuiltinType;
class CharacterType;
class FunctionType;
class RecordType;
@@ -334,16 +335,22 @@ public:
const Type *getTypePtr() const;
const Type *getTypePtrOrNull() const;
- const ExtQuals *getExtQualsPtrOrNull() const;
-
- /// \brief Retrieves a pointer to the name of the base type.
- const IdentifierInfo *getBaseTypeIdentifier() const;
-
/// \brief Divides a QualType into its unqualified type and a set of local
/// qualifiers.
SplitQualType split() const;
+ /// \brief Returns the qualifiers for this type has.
+ Qualifiers getQualifiers() const {
+ return split().second;
+ }
+
+ /// \brief Returns true if this type has the given attribute spec.
+ bool hasAttributeSpec(Qualifiers::AS A) const {
+ return split().second.hasAttributeSpec(A);
+ }
+
void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+
static QualType getFromOpaquePtr(const void *Ptr) {
QualType T;
T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
@@ -486,6 +493,13 @@ public:
None
};
+ enum TypeKind {
+#define INTEGER_KIND(NAME, VALUE) NAME,
+#define FLOATING_POINT_KIND(NAME, VALUE) NAME,
+#include "flang/AST/BuiltinTypeKinds.def"
+ NoKind
+ };
+
private:
Type(const Type&); // DO NOT IMPLEMENT.
void operator=(const Type&); // DO NOT IMPLEMENT.
@@ -493,14 +507,18 @@ private:
protected:
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
unsigned TypeBitsTC : 8;
- /// The kind (BuiltinType::Kind) of builtin type this is.
+ /// The spec (BuiltinType::TypeSpec) of builtin type this is.
+ unsigned BuiltinTypeBitsSpec : 8;
unsigned BuiltinTypeBitsKind : 8;
+ unsigned BuiltinTypeKindSpecified : 1;
+ unsigned BuiltinTypeDoublePrecisionKindSpecified : 1;
Type *this_() { return this; }
Type(TypeClass TC, QualType Canon)
: ExtQualsTypeCommonBase(this,
Canon.isNull() ? QualType(this_(), 0) : Canon) {
TypeBitsTC = TC;
+ BuiltinTypeBitsKind = NoKind;
}
friend class ASTContext;
@@ -526,10 +544,13 @@ public:
bool isBuiltinType() const;
bool isIntegerType() const;
bool isRealType() const;
- bool isCharacterType() const;
- const CharacterType *asCharacterType() const;
bool isComplexType() const;
bool isLogicalType() const;
+ const BuiltinType *asBuiltinType() const;
+ TypeKind getBuiltinTypeKind() const;
+
+ bool isCharacterType() const;
+ const CharacterType *asCharacterType() const;
bool isArrayOfCharacterType() const;
bool isArrayType() const;
@@ -557,7 +578,7 @@ public:
};
/// BuiltinType - Intrinsic Fortran types.
-class BuiltinType : public Type {
+class BuiltinType : public Type, public llvm::FoldingSetNode {
public:
/// TypeSpec - The intrinsic Fortran type specifications. REAL is the default
/// if "IMPLICIT NONE" isn't specified.
@@ -567,25 +588,27 @@ public:
Invalid
};
- enum TypeKind {
-#define INTEGER_KIND(NAME, VALUE) NAME,
-#define FLOATING_POINT_KIND(NAME, VALUE) NAME,
-#include "flang/AST/BuiltinTypeKinds.def"
- NoKind
- };
-
-protected:
+private:
friend class ASTContext; // ASTContext creates these.
- BuiltinType()
- : Type(Builtin, QualType()) {
- BuiltinTypeBitsKind = Real;
- }
- BuiltinType(TypeSpec TS)
+ BuiltinType(TypeSpec TS, TypeKind K,
+ bool IsKindSpecified,
+ bool IsDoublePrecisionKindSpecified)
: Type(Builtin, QualType()) {
- BuiltinTypeBitsKind = TS;
+ BuiltinTypeBitsSpec = TS;
+ BuiltinTypeBitsKind = K;
+ BuiltinTypeKindSpecified = IsKindSpecified? 1: 0;
+ BuiltinTypeDoublePrecisionKindSpecified = IsDoublePrecisionKindSpecified? 1: 0;
}
public:
- TypeSpec getTypeSpec() const { return TypeSpec(BuiltinTypeBitsKind); }
+ TypeSpec getTypeSpec() const { return TypeSpec(BuiltinTypeBitsSpec); }
+
+ bool isKindExplicitlySpecified() const {
+ return BuiltinTypeKindSpecified != 0;
+ }
+
+ bool isDoublePrecisionKindSpecified() const {
+ return BuiltinTypeDoublePrecisionKindSpecified != 0;
+ }
bool isIntegerType() const {
return getTypeSpec() == Integer;
@@ -611,6 +634,21 @@ public:
static const char *getTypeKindString(TypeKind Kind);
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getTypeSpec(), getBuiltinTypeKind(),
+ isKindExplicitlySpecified(),
+ isDoublePrecisionKindSpecified());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ TypeSpec Spec, TypeKind Kind,
+ bool KindSpecified,
+ bool DoublePrecisionKindSpecified) {
+ ID.AddInteger(Spec);
+ ID.AddInteger(Kind);
+ ID.AddBoolean(KindSpecified);
+ ID.AddBoolean(DoublePrecisionKindSpecified);
+ }
+
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
};
@@ -803,22 +841,13 @@ class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
/// contains extended qualifiers.
Qualifiers Quals;
- /// KindSelector - The kind-selector for a type.
- unsigned KindSelector : 16;
-
- /// IsDoublePrecisionKind - This assumes that a
- /// kind-selector was applied using
- /// DOUBLE PRECISION/DOUBLE COMPLEX statement.
- unsigned IsDoublePrecisionKind : 1;
-
ExtQuals *this_() { return this; }
public:
- ExtQuals(const Type *BaseTy, QualType Canon, Qualifiers Quals,
- unsigned KS = BuiltinType::NoKind, bool DBL = false)
+ ExtQuals(const Type *BaseTy, QualType Canon, Qualifiers Quals)
: ExtQualsTypeCommonBase(BaseTy,
Canon.isNull() ? QualType(this_(), 0) : Canon),
- Quals(Quals), KindSelector(KS), IsDoublePrecisionKind(DBL?1:0)
+ Quals(Quals)
{}
Qualifiers getQualifiers() const { return Quals; }
@@ -834,21 +863,12 @@ public:
const Type *getBaseType() const { return BaseType; }
- bool hasKindSelector() const { return KindSelector != BuiltinType::NoKind; }
- BuiltinType::TypeKind getKindSelector() const {
- return (BuiltinType::TypeKind)KindSelector;
- }
- bool isDoublePrecisionKind() const { return IsDoublePrecisionKind != 0; }
-
void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, getBaseType(), Quals, KindSelector, IsDoublePrecisionKind != 0);
+ Profile(ID, getBaseType(), Quals);
}
static void Profile(llvm::FoldingSetNodeID &ID,
- const Type *BaseType, Qualifiers Quals,
- unsigned KS, bool IsDBL) {
+ const Type *BaseType, Qualifiers Quals) {
ID.AddPointer(BaseType);
- ID.AddInteger(KS);
- ID.AddBoolean(IsDBL);
Quals.Profile(ID);
}
};
@@ -886,9 +906,6 @@ inline const Type *QualType::getTypePtr() const {
inline const Type *QualType::getTypePtrOrNull() const {
return (isNull() ? 0 : getCommonPtr()->BaseType);
}
-inline const ExtQuals *QualType::getExtQualsPtrOrNull() const {
- return Value.getPointer().dyn_cast<const ExtQuals*>();
-}
inline bool QualType::isCanonical() const {
return getTypePtr()->isCanonicalUnqualified();
}
@@ -929,12 +946,6 @@ inline bool Type::isRealType() const {
return BT->getTypeSpec() == BuiltinType::Real;
return false;
}
-inline bool Type::isCharacterType() const {
- return isa<CharacterType>(CanonicalType);
-}
-inline const CharacterType *Type::asCharacterType() const {
- return dyn_cast<CharacterType>(CanonicalType);
-}
inline bool Type::isLogicalType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getTypeSpec() == BuiltinType::Logical;
@@ -945,6 +956,18 @@ inline bool Type::isComplexType() const {
return BT->getTypeSpec() == BuiltinType::Complex;
return false;
}
+inline const BuiltinType *Type::asBuiltinType() const {
+ return dyn_cast<BuiltinType>(CanonicalType);
+}
+inline BuiltinType::TypeKind Type::getBuiltinTypeKind() const {
+ return TypeKind(BuiltinTypeBitsKind);
+}
+inline bool Type::isCharacterType() const {
+ return isa<CharacterType>(CanonicalType);
+}
+inline const CharacterType *Type::asCharacterType() const {
+ return dyn_cast<CharacterType>(CanonicalType);
+}
inline bool Type::isArrayType() const {
return isa<ArrayType>(CanonicalType);
}
diff --git a/include/flang/AST/TypeVisitor.h b/include/flang/AST/TypeVisitor.h
index baa674c306..42d8bad4f2 100644
--- a/include/flang/AST/TypeVisitor.h
+++ b/include/flang/AST/TypeVisitor.h
@@ -33,10 +33,11 @@ class TypeVisitor {
public:
#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<const CLASS*>(T.getTypePtr()), T.getExtQualsPtrOrNull())
+ return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<const CLASS*>(Split.first), Split.second)
/// \brief Performs the operation associated with this visitor object.
RetTy Visit(QualType T) {
+ auto Split = T.split();
// Top switch stmt: dispatch to VisitFooType for each FooType.
switch (T->getTypeClass()) {
#define TYPE(Class, Parent) case Type::Class: DISPATCH(Class##Type, Class##Type);
@@ -47,14 +48,14 @@ public:
// If the implementation chooses not to implement a certain visit method, fall
// back on superclass.
-#define TYPE(Class, Parent) RetTy Visit##Class##Type(const Class##Type *T, const ExtQuals *E) { \
- return static_cast<ImplClass*>(this)->Visit ## Parent(static_cast<const Parent*>(T), E); \
+#define TYPE(Class, Parent) RetTy Visit##Class##Type(const Class##Type *T, Qualifiers QS) { \
+ return static_cast<ImplClass*>(this)->Visit ## Parent(static_cast<const Parent*>(T), QS); \
}
#include "flang/AST/TypeNodes.def"
/// \brief Method called if \c ImpClass doesn't provide specific handler
/// for some type class.
- RetTy VisitType(const Type*, const ExtQuals *E) { return RetTy(); }
+ RetTy VisitType(const Type*, Qualifiers) { return RetTy(); }
};
#undef DISPATCH
diff --git a/include/flang/Sema/Sema.h b/include/flang/Sema/Sema.h
index be5fd96d37..1e9da62e70 100644
--- a/include/flang/Sema/Sema.h
+++ b/include/flang/Sema/Sema.h
@@ -518,6 +518,12 @@ public:
SourceLocation MaxLoc,
ExprResult RealPart, ExprResult ImPart);
+ /// Returns true if a type is a double precision real type.
+ bool IsTypeDoublePrecisionReal(QualType T) const;
+
+ /// Returns true if a type is a double precision complex type.
+ bool IsTypeDoublePrecisionComplex(QualType T) const;
+
/// GetUnaryReturnType - Returns the type T with the
/// required qualifiers and array type from the given expression.
QualType GetUnaryReturnType(const Expr *E, QualType T);
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 98450defc8..19102ed3b9 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -31,45 +31,29 @@ ASTContext::~ASTContext() {
ReleaseDeclContextMaps();
}
-void ASTContext::InitBuiltinType(QualType &R, BuiltinType::TypeSpec K) {
- BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K);
- R = QualType(Ty, 0);
- Types.push_back(Ty);
-}
-
void ASTContext::InitBuiltinTypes() {
// [R404]
VoidTy = QualType(new (*this, TypeAlignment) VoidType(), 0);
- InitBuiltinType(IntegerTy, BuiltinType::Integer);
- InitBuiltinType(RealTy, BuiltinType::Real);
- DoublePrecisionTy = getExtQualType(RealTy.getTypePtr(), Qualifiers(),
- BuiltinType::Real8, true);
- InitBuiltinType(ComplexTy, BuiltinType::Complex);
- DoubleComplexTy = getExtQualType(ComplexTy.getTypePtr(), Qualifiers(),
- BuiltinType::Real8, true);
- InitBuiltinType(LogicalTy, BuiltinType::Logical);
+ IntegerTy = QualType(getBuiltinType(BuiltinType::Integer, BuiltinType::Int4), 0);
+ RealTy = QualType(getBuiltinType(BuiltinType::Real, BuiltinType::Real4), 0);
+ DoublePrecisionTy = QualType(getBuiltinType(BuiltinType::Real, BuiltinType::Real8,
+ false, true), 0);
+ ComplexTy = QualType(getBuiltinType(BuiltinType::Complex, BuiltinType::Real4), 0);
+ DoubleComplexTy = QualType(getBuiltinType(BuiltinType::Complex, BuiltinType::Real8,
+ false, true), 0);
+ LogicalTy = QualType(getBuiltinType(BuiltinType::Logical, BuiltinType::Int4), 0);
CharacterTy = QualType(getCharacterType(1), 0);
NoLengthCharacterTy = QualType(getCharacterType(0), 0);
}
-QualType ASTContext::getBuiltinQualType(BuiltinType::TypeSpec TS) const {
- switch (TS) {
- case BuiltinType::Invalid: assert(false && "Invalid type spec!"); break;
- case BuiltinType::Integer: return IntegerTy;
- case BuiltinType::Real: return RealTy;
- case BuiltinType::Logical: return LogicalTy;
- case BuiltinType::Complex: return ComplexTy;
- }
- return QualType();
-}
-
const llvm::fltSemantics& ASTContext::getFPTypeSemantics(QualType Type) {
- switch(getRealOrComplexTypeKind(Type.getExtQualsPtrOrNull(), Type)) {
+ switch(Type->getBuiltinTypeKind()) {
case BuiltinType::Real4: return llvm::APFloat::IEEEsingle;
case BuiltinType::Real8: return llvm::APFloat::IEEEdouble;
case BuiltinType::Real16: return llvm::APFloat::IEEEquad;
+ default: break;
}
llvm_unreachable("invalid real type");
}
@@ -105,11 +89,10 @@ BuiltinType::TypeKind ASTContext::getSelectedIntKind(int64_t Range) const {
// Type creation/memoization methods
//===----------------------------------------------------------------------===//
-QualType ASTContext::getExtQualType(const Type *BaseType, Qualifiers Quals,
- unsigned KindSel, bool IsDoublePrecisionKind) const {
+QualType ASTContext::getExtQualType(const Type *BaseType, Qualifiers Quals) const {
// Check if we've already instantiated this type.
llvm::FoldingSetNodeID ID;
- ExtQuals::Profile(ID, BaseType, Quals, KindSel, IsDoublePrecisionKind);
+ ExtQuals::Profile(ID, BaseType, Quals);
void *InsertPos = 0;
if (ExtQuals *EQ = ExtQualNodes.FindNodeOrInsertPos(ID, InsertPos)) {
assert(EQ->getQualifiers() == Quals);
@@ -121,53 +104,65 @@ QualType ASTContext::getExtQualType(const Type *BaseType, Qualifiers Quals,
if (!BaseType->isCanonicalUnqualified()) {
SplitQualType CanonSplit = BaseType->getCanonicalTypeInternal().split();
CanonSplit.second.addConsistentQualifiers(Quals);
- Canon = getExtQualType(CanonSplit.first, CanonSplit.second, KindSel,
- IsDoublePrecisionKind);
+ Canon = getExtQualType(CanonSplit.first, CanonSplit.second);
// Re-find the insert position.
(void) ExtQualNodes.FindNodeOrInsertPos(ID, InsertPos);
}
- ExtQuals *EQ = new (*this, TypeAlignment) ExtQuals(BaseType, Canon, Quals,
- KindSel, IsDoublePrecisionKind);
+ ExtQuals *EQ = new (*this, TypeAlignment) ExtQuals(BaseType, Canon, Quals);
ExtQualNodes.InsertNode(EQ, InsertPos);
return QualType(EQ, 0);
}
QualType ASTContext::getQualTypeOtherKind(QualType Type, QualType KindType) {
- auto ExtQuals = Type.getExtQualsPtrOrNull();
- auto DesiredExtQuals = KindType.getExtQualsPtrOrNull();
- assert(DesiredExtQuals);
-
- return getExtQualType(Type.getTypePtr(),
- ExtQuals? ExtQuals->getQualifiers() : Qualifiers(),
- DesiredExtQuals->getKindSelector(),
- DesiredExtQuals->isDoublePrecisionKind());
+ auto BTy = Type->asBuiltinType();
+ auto DesiredBTy = KindType->asBuiltinType();
+ if(BTy->getBuiltinTypeKind() == DesiredBTy->getBuiltinTypeKind())
+ return Type;
+ auto Split = Type.split();
+ return getExtQualType(getBuiltinType(BTy->getTypeSpec(), DesiredBTy->getBuiltinTypeKind(),
+ DesiredBTy->isKindExplicitlySpecified(),
+ DesiredBTy->isDoublePrecisionKindSpecified()), Split.second);
}
// NB: this assumes that real and complex have have the same default kind.
QualType ASTContext::getComplexTypeElementType(QualType Type) {
assert(Type->isComplexType());
- if(Type.getExtQualsPtrOrNull())
+ if(Type->getBuiltinTypeKind() != RealTy->getBuiltinTypeKind())
return getQualTypeOtherKind(RealTy, Type);
return RealTy;
}
QualType ASTContext::getComplexType(QualType ElementType) {
assert(ElementType->isRealType());
- if(ElementType.getExtQualsPtrOrNull())
+ if(ElementType->getBuiltinTypeKind() != ComplexTy->getBuiltinTypeKind())
return getQualTypeOtherKind(ComplexTy, ElementType);
return ComplexTy;
}
QualType ASTContext::getTypeWithQualifers(QualType Type, Qualifiers Quals) {
- auto ExtQuals = Type.getExtQualsPtrOrNull();
+ auto Split = Type.split();
+ return getExtQualType(Split.first, Quals);
+}
+
+BuiltinType *ASTContext::getBuiltinType(BuiltinType::TypeSpec TS,
+ BuiltinType::TypeKind Kind,
+ bool IsKindExplicitlySpecified,
+ bool IsDoublePrecisionKindSpecified) {
+ llvm::FoldingSetNodeID ID;
+ BuiltinType::Profile(ID, TS, Kind, IsKindExplicitlySpecified,
+ IsDoublePrecisionKindSpecified);
- return ExtQuals? getExtQualType(Type.getTypePtr(),
- Quals,
- ExtQuals->getKindSelector(),
- ExtQuals->isDoublePrecisionKind()) :
- getExtQualType(Type.getTypePtr(), Quals);
+ void *InsertPos = 0;
+ if (auto BT = BuiltinTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return BT;
+
+ auto BT = new (*this, TypeAlignment) BuiltinType(TS, Kind, IsKindExplicitlySpecified,
+ IsDoublePrecisionKindSpecified);
+ Types.push_back(BT);
+ BuiltinTypes.InsertNode(BT, InsertPos);
+ return BT;
}
CharacterType *ASTContext::getCharacterType(uint64_t Length) const {
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 546db1fdd1..eec7e82944 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -50,11 +50,11 @@ public:
// types
void dumpType(QualType T);
- void VisitBuiltinType(const BuiltinType *T, const ExtQuals *E);
- void VisitCharacterType(const CharacterType *T, const ExtQuals *E);
- void VisitArrayType(const ArrayType *T, const ExtQuals *E);
- void VisitFunctionType(const FunctionType *T, const ExtQuals *E);
- void VisitRecordType(const RecordType *T, const ExtQuals *E);
+ void VisitBuiltinType(const BuiltinType *T, Qualifiers QS);
+ void VisitCharacterType(const CharacterType *T, Qualifiers QS);
+ void VisitArrayType(const ArrayType *T, Qualifiers QS);
+ void VisitFunctionType(const FunctionType *T, Qualifiers QS);
+ void VisitRecordType(const RecordType *T, Qualifiers QS);
// statements
void dumpStmt(const Stmt *S);
@@ -278,8 +278,8 @@ void ASTDumper::dumpType(QualType T) {
} */
}
-void ASTDumper::VisitBuiltinType(const BuiltinType *T, const ExtQuals *E) {
- if(E && E->isDoublePrecisionKind()) {
+void ASTDumper::VisitBuiltinType(const BuiltinType *T, Qualifiers QS) {
+ if(T->isDoublePrecisionKindSpecified()) {
if(T->isRealType())
OS << "double precision";
else OS << "double complex";
@@ -301,32 +301,31 @@ void ASTDumper::VisitBuiltinType(const BuiltinType *T, const ExtQuals *E) {
}
}
- if (!E) return;
- if (!E->isDoublePrecisionKind() && E->hasKindSelector()) {
- OS << " (Kind=" << BuiltinType::getTypeKindString(E->getKindSelector());
+ if(T->isKindExplicitlySpecified()) {
+ OS << " (Kind=" << BuiltinType::getTypeKindString(T->getBuiltinTypeKind());
OS << ")";
}
}
-void ASTDumper::VisitCharacterType(const CharacterType *T, const ExtQuals *E) {
+void ASTDumper::VisitCharacterType(const CharacterType *T, Qualifiers QS) {
OS << "character";
if(T->hasLength() && T->getLength() > 1)
OS << " (Len=" << T->getLength() << ")";
}
-void ASTDumper::VisitArrayType(const ArrayType *T, const ExtQuals *E) {
+void ASTDumper::VisitArrayType(const ArrayType *T, Qualifiers QS) {
dumpType(T->getElementType());
OS << " array";
}
-void ASTDumper::VisitFunctionType(const FunctionType *T, const ExtQuals *E) {
+void ASTDumper::VisitFunctionType(const FunctionType *T, Qualifiers QS) {
OS << "procedure (";
if(T->hasPrototype())
OS << T->getPrototype()->getName();
OS << ")";
}
-void ASTDumper::VisitRecordType(const RecordType *T, const ExtQuals *E) {
+void ASTDumper::VisitRecordType(const RecordType *T, Qualifiers QS) {
auto Record = T->getDecl();
OS << "type " << Record->getName();
}
@@ -746,9 +745,9 @@ void ASTDumper::VisitImplicitCastExpr(const ImplicitCastExpr *E) {
OS << "(";
}
dumpExpr(E->getExpression());
- if(const ExtQuals *Ext = Type.getExtQualsPtrOrNull()) {
- if(Ext->hasKindSelector())
- OS << ",Kind=" << BuiltinType::getTypeKindString(Ext->getKindSelector());
+ if(auto BTy = Type->asBuiltinType()) {
+ if(BTy->isKindExplicitlySpecified() || BTy->isDoublePrecisionKindSpecified())
+ OS << ",Kind=" << BuiltinType::getTypeKindString(BTy->getBuiltinTypeKind());
}
OS << ')';
}
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index ac34850581..a7477cc96b 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -275,7 +275,6 @@ bool IntExprEvaluator::VisitIntrinsicCallExpr(const IntrinsicCallExpr *E) {
switch(E->getIntrinsicFunction()) {
case intrinsic::SELECTED_INT_KIND: {
- //FIXME
if(!Eval(Args[0]))
return false;
auto Kind = Context.getSelectedIntKind(getResult());
@@ -284,6 +283,7 @@ bool IntExprEvaluator::VisitIntrinsicCallExpr(const IntrinsicCallExpr *E) {
return true;
}
case intrinsic::SELECTED_REAL_KIND:
+ //FIXME
return false;
case intrinsic::KIND: {
auto T = Args[0]->getType().getSelfOrArrayElementType();
@@ -295,14 +295,13 @@ bool IntExprEvaluator::VisitIntrinsicCallExpr(const IntrinsicCallExpr *E) {
Result.Assign(llvm::APInt(64, 4, true));
return true;
}
- auto Kind = Context.getArithmeticOrLogicalTypeKind(T.getExtQualsPtrOrNull(), T);
- Result.Assign(llvm::APInt(64, Context.getTypeKindBitWidth(Kind)/8, true));
+ Result.Assign(llvm::APInt(64, Context.getTypeKindBitWidth(T->getBuiltinTypeKind())/8, true));
return true;
}
case intrinsic::BIT_SIZE: {
auto T = Args[0]->getType().getSelfOrArrayElementType();
auto Val = T->isIntegerType()?
- Context.getTypeKindBitWidth(Context.getIntTypeKind(T.getExtQualsPtrOrNull())) : 1;
+ Context.getTypeKindBitWidth(T->getBuiltinTypeKind()) : 1;
Result.Assign(llvm::APInt(64, Val, true));
return true;
}
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index a80fedf681..bbef51ec3b 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -279,9 +279,7 @@ void CodeGenFunction::EmitCallArg(CallArgList &Args,
auto EType = E->getType();
auto Ptr = EmitCallArgPtr(E);
Args.add(Builder.CreateBitCast(Ptr, CGM.VoidPtrTy));
- Args.add(Builder.getInt32(getContext().getTypeKindBitWidth(
- getContext().getArithmeticOrLogicalTypeKind(
- EType.getExtQualsPtrOrNull(), EType))/8));
+ Args.add(Builder.getInt32(getContext().getTypeKindBitWidth(EType->getBuiltinTypeKind())/8));
break;
}
}
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index e00566b3ea..b9599ed839 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -50,9 +50,7 @@ void CodeGenFunction::EmitVarDecl(const VarDecl *D) {
llvm::Value *Ptr;
auto Type = D->getType();
- auto Quals = Type.getExtQualsPtrOrNull();
- if(Quals && Quals->getQualifiers().hasAttributeSpec(Qualifiers::AS_save) &&
- !IsMainProgram) {
+ if(Type.hasAttributeSpec(Qualifiers::AS_save) && !IsMainProgram) {
Ptr = CGM.EmitGlobalVariable(CurFn->getName(), D);
HasSavedVariables = true;
} else {
@@ -75,8 +73,7 @@ public:
if(D->isParameter() || D->isArgument() ||
D->isFunctionResult())
return;
- auto Ext = D->getType().getExtQualsPtrOrNull();
- bool HasSave = Ext && Ext->getQualifiers().hasAttributeSpec(Qualifiers::AS_save);
+ bool HasSave = D->getType().hasAttributeSpec(Qualifiers::AS_save);
if(HasSave != VisitSaveQualified)
return;
if(D->hasInit())
diff --git a/lib/CodeGen/CGIOLibflang.cpp b/lib/CodeGen/CGIOLibflang.cpp
index cadcb4df61..c2a3ab7bba 100644
--- a/lib/CodeGen/CGIOLibflang.cpp
+++ b/lib/CodeGen/CGIOLibflang.cpp
@@ -72,7 +72,6 @@ public:
void EmitEnd();
void EmitWriteUnformattedList(ArrayRef<Expr*> Values);
void EmitWriteUnformattedBuiltin(const BuiltinType *BTy,
- const ExtQuals *ExtTy,
const Expr *E);
void EmitWriteUnformattedChar(const Expr *E);
};
@@ -93,13 +92,11 @@ void CGLibflangWriteEmitter::EmitWriteUnformattedList(ArrayRef<Expr*> Values) {
if(EType->isCharacterType())
EmitWriteUnformattedChar(E);
if(auto BTy = dyn_cast<BuiltinType>(EType.getTypePtr()))
- EmitWriteUnformattedBuiltin(BTy,
- EType.getExtQualsPtrOrNull(), E);
+ EmitWriteUnformattedBuiltin(BTy, E);
}
}
void CGLibflangWriteEmitter::EmitWriteUnformattedBuiltin(const BuiltinType *BTy,
- const ExtQuals *ExtTy,
const Expr *E) {
CGFunction Func;
switch(BTy->getTypeSpec()) {
diff --git a/lib/CodeGen/CGIntrinsic.cpp b/lib/CodeGen/CGIntrinsic.cpp
index af8da96806..e0f833e25f 100644
--- a/lib/CodeGen/CGIntrinsic.cpp
+++ b/lib/CodeGen/CGIntrinsic.cpp
@@ -390,7 +390,7 @@ llvm::Value *CodeGenFunction::EmitIntrinsicNumericInquiry(intrinsic::FunctionKin
auto RetT = ConvertType(Result);
auto T = ArgType;
- auto TKind = getContext().getArithmeticTypeKind(T.getExtQualsPtrOrNull(), T);
+ auto TKind = T->getBuiltinTypeKind();
int IntResult;
#define HANDLE_INT(Result, func) \
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 9d0b3e4db8..5af6b01215 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -485,17 +485,6 @@ void CodeGenFunction::EmitCallStmt(const CallStmt *S) {
EmitCall(S->getFunction(), ArgList, S->getArguments(), true);
}
-bool CodeGenFunction::IsAssignmentStmtAssignmentToSaved(const AssignmentStmt *S) {
- auto LHS = S->getLHS();
- DesignatorExpr *Designator;
- while(Designator = dyn_cast<DesignatorExpr>(LHS))
- LHS = Designator->getTarget();
- auto Var = dyn_cast<VarExpr>(LHS);
- if(!Var) return false;
- auto Ext = Var->getVarDecl()->getType().getExtQualsPtrOrNull();
- return Ext && Ext->getQualifiers().hasAttributeSpec(Qualifiers::AS_save);
-}
-
void CodeGenFunction::EmitAssignmentStmt(const AssignmentStmt *S) {
auto RHS = S->getRHS();
auto RHSType = RHS->getType();
diff --git a/lib/CodeGen/CGSystemLibflang.cpp b/lib/CodeGen/CGSystemLibflang.cpp
index b17e2dbcc2..deed482ddf 100644
--- a/lib/CodeGen/CGSystemLibflang.cpp
+++ b/lib/CodeGen/CGSystemLibflang.cpp
@@ -53,8 +53,7 @@ void CGLibflangSystemRuntime::EmitFree(CodeGenFunction &CGF, llvm::Value *Ptr) {
llvm::Value *CGLibflangSystemRuntime::EmitETIME(CodeGenFunction &CGF, ArrayRef<Expr*> Arguments) {
auto RealTy = CGM.getContext().RealTy;
auto RealPtrTy = llvm::PointerType::get(CGF.ConvertTypeForMem(RealTy) ,0);
- auto Kind = CGM.getContext().getRealTypeKind(RealTy.getExtQualsPtrOrNull());
- auto Func = CGM.GetRuntimeFunction2(Kind == BuiltinType::Real4? "etimef" : "etime",
+ auto Func = CGM.GetRuntimeFunction2(RealTy->getBuiltinTypeKind() == BuiltinType::Real4? "etimef" : "etime",
RealPtrTy, RealPtrTy, RealTy);
auto Arr = CGF.EmitArrayArgumentPointerValueABI(Arguments[0]);
CallArgList ArgList;
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 11d5a5cc01..141e8f97e9 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -261,7 +261,6 @@ public:
void EmitReturnStmt(const ReturnStmt *S);
void EmitCallStmt(const CallStmt *S);
void EmitAssignmentStmt(const AssignmentStmt *S);
- bool IsAssignmentStmtAssignmentToSaved(const AssignmentStmt *S);
void EmitAssignment(const Expr *LHS, const Expr *RHS);
void EmitAssignment(LValueTy LHS, RValueTy RHS);
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 89af3d678d..e19b7edc7e 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -30,10 +30,10 @@ CodeGenTypes::CodeGenTypes(CodeGenModule &cgm)
CodeGenTypes::~CodeGenTypes() { }
llvm::Type *CodeGenTypes::ConvertType(QualType T) {
- auto Ext = T.getExtQualsPtrOrNull();
auto TPtr = T.getTypePtr();
if(const BuiltinType *BTy = dyn_cast<BuiltinType>(TPtr))
- return ConvertBuiltInType(BTy, Ext);
+ return ConvertBuiltInType(BTy->getTypeSpec(),
+ BTy->getBuiltinTypeKind());
else if(const CharacterType *CTy = dyn_cast<CharacterType>(TPtr))
return ConvertCharType(CTy);
else if(const ArrayType *ATy = dyn_cast<ArrayType>(TPtr))
@@ -43,33 +43,24 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
else if(const RecordType *RTy = dyn_cast<RecordType>(TPtr))
return ConvertRecordType(RTy);
+ llvm_unreachable("invalid type");
return nullptr;
}
-llvm::Type *CodeGenTypes::ConvertBuiltInTypeForMem(const BuiltinType *T,
- const ExtQuals *Ext) {
- return ConvertBuiltInType(T, Ext);
-}
+llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
+ auto TPtr = T.getTypePtr();
+ if(const BuiltinType *BTy = dyn_cast<BuiltinType>(TPtr))
+ return ConvertBuiltInType(BTy->getTypeSpec(),
+ BTy->getBuiltinTypeKind());
+ else if(const CharacterType *CTy = dyn_cast<CharacterType>(TPtr))
+ return ConvertCharTypeForMem(CTy);
+ else if(const ArrayType *ATy = dyn_cast<ArrayType>(TPtr))
+ return ConvertArrayTypeForMem(ATy);
+ else if(const RecordType *RTy = dyn_cast<RecordType>(TPtr))
+ return ConvertRecordType(RTy);
-llvm::Type *CodeGenTypes::ConvertBuiltInType(const BuiltinType *T,
- const ExtQuals *Ext) {
- BuiltinType::TypeKind Kind;
- switch(T->getTypeSpec()) {
- case BuiltinType::Integer:
- Kind = CGM.getContext().getIntTypeKind(Ext);
- break;
- case BuiltinType::Real:
- Kind = CGM.getContext().getRealTypeKind(Ext);
- break;
- case BuiltinType::Complex:
- Kind = CGM.getContext().getComplexTypeKind(Ext);
- break;
- case BuiltinType::Logical:
- Kind = CGM.getContext().getLogicalTypeKind(Ext);
- break;
- }
- return ConvertBuiltInType(T->getTypeSpec(),
- Kind);
+ llvm_unreachable("invalid type");
+ return nullptr;
}
llvm::Type *CodeGenTypes::ConvertBuiltInType(BuiltinType::TypeSpec Spec,
@@ -77,17 +68,13 @@ llvm::Type *CodeGenTypes::ConvertBuiltInType(BuiltinType::TypeSpec Spec,
llvm::Type *Type;
switch(Kind) {
case BuiltinType::Int1:
- Type = CGM.Int8Ty;
- break;
+ return CGM.Int8Ty;
case BuiltinType::Int2:
- Type = CGM.Int16Ty;
- break;
+ return CGM.Int16Ty;
case BuiltinType::Int4:
- Type = CGM.Int32Ty;
- break;
+ return CGM.Int32Ty;
case BuiltinType::Int8:
- Type = CGM.Int64Ty;
- break;
+ return CGM.Int64Ty;
case BuiltinType::Real4:
Type = CGM.FloatTy;
break;
@@ -104,6 +91,15 @@ llvm::Type *CodeGenTypes::ConvertBuiltInType(BuiltinType::TypeSpec Spec,
return Type;
}
+llvm::Type *CodeGenTypes::GetComplexType(llvm::Type *ElementType) {
+ llvm::Type *Pair[2] = { ElementType, ElementType };
+ return llvm::StructType::get(CGM.getLLVMContext(),
+ ArrayRef<llvm::Type*>(Pair,2));
+}
+
+llvm::Type *CodeGenTypes::GetComplexTypeAsVector(llvm::Type *ElementType) {
+ return llvm::VectorType::get(ElementType, 2);
+}
llvm::Type *CodeGenTypes::ConvertCharType(const CharacterType *T) {
llvm::Type *Pair[2] = { CGM.Int8PtrTy, CGM.SizeTy };
@@ -116,11 +112,6 @@ llvm::Type *CodeGenTypes::ConvertCharTypeForMem(const CharacterType *T) {
return llvm::ArrayType::get(CGM.Int8Ty, T->getLength());
}
-llvm::Type *CodeGenTypes::GetComplexType(llvm::Type *ElementType) {
- llvm::Type *Pair[2] = { ElementType, ElementType };
- return llvm::StructType::get(CGM.getLLVMContext(),
- ArrayRef<llvm::Type*>(Pair,2));
-}
llvm::Type *CodeGenTypes::GetCharacterType(llvm::Type *PtrType) {
llvm::Type *Pair[2] = { PtrType, CGM.SizeTy };
@@ -128,10 +119,6 @@ llvm::Type *CodeGenTypes::GetCharacterType(llvm::Type *PtrType) {
ArrayRef<llvm::Type*>(Pair,2));
}
-llvm::Type *CodeGenTypes::GetComplexTypeAsVector(llvm::Type *ElementType) {
- return llvm::VectorType::get(ElementType, 2);
-}
-
llvm::Type *CodeGenTypes::ConvertRecordType(const RecordType *T) {
SmallVector<llvm::Type*, 16> Fields;
for(auto I : T->getElements()) {
@@ -140,22 +127,6 @@ llvm::Type *CodeGenTypes::ConvertRecordType(const RecordType *T) {
return llvm::StructType::get(CGM.getLLVMContext(), Fields);
}
-llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
- auto Ext = T.getExtQualsPtrOrNull();
- auto TPtr = T.getTypePtr();
- if(const BuiltinType *BTy = dyn_cast<BuiltinType>(TPtr))
- return ConvertBuiltInTypeForMem(BTy, Ext);
- else if(const CharacterType *CTy = dyn_cast<CharacterType>(TPtr))
- return ConvertCharTypeForMem(CTy);
- else if(const ArrayType *ATy = dyn_cast<ArrayType>(TPtr))
- return ConvertArrayTypeForMem(ATy);
- else if(const RecordType *RTy = dyn_cast<RecordType>(TPtr))
- return ConvertRecordType(RTy);
-
- llvm_unreachable("invalid type");
- return nullptr;
-}
-
llvm::Type *CodeGenTypes::ConvertFunctionType(const FunctionType *T) {
return llvm::PointerType::get(GetFunctionType(T->getPrototype())->getFunctionType(), 0);
}
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 8fcddd7694..29e9ff3295 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -89,9 +89,6 @@ public:
llvm::Type *GetCharacterType(llvm::Type *PtrType);
- llvm::Type *ConvertBuiltInTypeForMem(const BuiltinType *T,
- const ExtQuals *Ext);
- llvm::Type *ConvertBuiltInType(const BuiltinType *T, const ExtQuals *Ext);
llvm::Type *ConvertBuiltInType(BuiltinType::TypeSpec Spec,
BuiltinType::TypeKind Kind);
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 0a9bce32ea..9e746232e4 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -67,8 +67,7 @@ void X86_64ABIInfo::computeReturnTypeInfo(QualType T, ABIRetInfo &Info) const {
return;
if(Info.getKind() == ABIRetInfo::Value) {
- auto Kind = CGM.getContext().getComplexTypeKind(T.getExtQualsPtrOrNull());
- switch(Kind) {
+ switch(T->getBuiltinTypeKind()) {
case BuiltinType::Real4:
Info = ABIRetInfo(ABIRetInfo::Value, llvm::VectorType::get(CGM.FloatTy, 2));
break;
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 2de3edc60a..dc997f185a 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -78,7 +78,8 @@ BuiltinType::TypeKind Sema::EvalAndCheckTypeKind(QualType T,
QualType Sema::ApplyTypeKind(QualType T, const Expr *E) {
auto Kind = EvalAndCheckTypeKind(T, E);
return Kind != BuiltinType::NoKind?
- Context.getExtQualType(T.getTypePtr(), Qualifiers(), Kind) : T;
+ QualType(Context.getBuiltinType(T->asBuiltinType()->getTypeSpec(),
+ Kind, true), 0) : T;
}
bool Sema::CheckConstantExpression(const Expr *E) {
@@ -286,25 +287,10 @@ bool Sema::AreTypesOfSameKind(QualType A, QualType B) const {
return B->isCharacterType();
if(auto ABTy = dyn_cast<BuiltinType>(A.getTypePtr())) {
auto BBTy = dyn_cast<BuiltinType>(B.getTypePtr());
- if(!BBTy) return false;
+ if(!BBTy) return false;
auto Spec = ABTy->getTypeSpec();
if(Spec != BBTy->getTypeSpec()) return false;
- auto AExt = A.getExtQualsPtrOrNull();
- auto BExt = B.getExtQualsPtrOrNull();
- switch(Spec) {
- case BuiltinType::Integer:
- return Context.getIntTypeKind(AExt) ==
- Context.getIntTypeKind(BExt);
- case BuiltinType::Real:
- return Context.getRealTypeKind(AExt) ==
- Context.getRealTypeKind(BExt);
- case BuiltinType::Complex:
- return Context.getComplexTypeKind(AExt) ==
- Context.getComplexTypeKind(BExt);
- case BuiltinType::Logical:
- return Context.getLogicalTypeKind(AExt) ==
- Context.getLogicalTypeKind(BExt);
- }
+ return ABTy->getBuiltinTypeKind() == BBTy->getBuiltinTypeKind();
}
return false;
}
@@ -353,12 +339,13 @@ Expr *Sema::TypecheckExprIntegerOrLogicalOrSameCharacter(Expr *E,
}
bool Sema::IsDefaultBuiltinOrDoublePrecisionType(QualType T) {
- if(!(T->isBuiltinType() || T->isCharacterType()))
+ if(T->isCharacterType())
+ return true;
+ if(!T->isBuiltinType())
return false;
- auto Ext = T.getExtQualsPtrOrNull();
- if(!Ext) return true;
- if(Ext->getKindSelector() == BuiltinType::NoKind ||
- Ext->isDoublePrecisionKind())
+ auto BTy = T->asBuiltinType();
+ if(BTy->isDoublePrecisionKindSpecified() ||
+ !BTy->isKindExplicitlySpecified())
return true;
return false;
}
@@ -398,27 +385,6 @@ static const BuiltinType *getBuiltinType(QualType T) {
return dyn_cast<BuiltinType>(T.getTypePtr());
}
-/// Returns true if a type is a double precision real type (Kind is 8).
-static bool IsTypeDoublePrecisionReal(QualType T) {
- auto Ext = T.getExtQualsPtrOrNull();
- return T->isRealType() &&
- Ext && Ext->getKindSelector() == BuiltinType::Real8? true : false;
-}
-
-/// Returns true if a type is a single precision real type (Kind is 4).
-static bool IsTypeSinglePrecisionReal(QualType T) {
- if(T->isRealType())
- return !IsTypeDoublePrecisionReal(T);
- return false;
-}
-
-/// Returns true if a type is a double precision complex type (Kind is 8).
-static bool IsTypeDoublePrecisionComplex(QualType T) {
- auto Ext = T.getExtQualsPtrOrNull();
- return T->isComplexType() &&
- Ext && Ext->getKindSelector() == BuiltinType::Real8? true : false;
-}
-
bool Sema::DiagnoseIncompatiblePassing(const Expr *E, QualType T,
bool AllowArrays,
StringRef ArgName) {
@@ -460,10 +426,8 @@ bool Sema::CheckArgumentsTypeCompability(const Expr *E1, const Expr *E2,
} else {
auto Type1 = getBuiltinType(E1, AllowArrays);
auto Type2 = getBuiltinType(E2, AllowArrays);
- auto Ext1 = T1.getExtQualsPtrOrNull();
- auto Ext2 = T2.getExtQualsPtrOrNull();
if(!(!Type2 || Type1->getTypeSpec() != Type2->getTypeSpec() ||
- Context.getArithmeticOrLogicalTypeKind(Ext1,T1) != Context.getArithmeticOrLogicalTypeKind(Ext2, T2)))
+ Type1->getBuiltinTypeKind() != Type2->getBuiltinTypeKind()))
return false;
}
@@ -503,7 +467,8 @@ bool Sema::CheckComplexArgument(const Expr *E, bool AllowArrays) {
}
bool Sema::CheckStrictlyRealArgument(const Expr *E, bool AllowArrays) {
- if(!IsTypeSinglePrecisionReal(ScalarizeType(E->getType(), AllowArrays)))
+ auto T = ScalarizeType(E->getType(), AllowArrays);
+ if(!T->isRealType() || IsTypeDoublePrecisionReal(T))
return DiagnoseIncompatiblePassing(E, Context.RealTy, AllowArrays);
return false;
}
@@ -511,7 +476,8 @@ bool Sema::CheckStrictlyRealArgument(const Expr *E, bool AllowArrays) {
bool Sema::CheckStrictlyRealArrayArgument(const Expr *E, StringRef ArgName) {
auto T = E->getType()->asArrayType();
if(T) {
- if(IsTypeSinglePrecisionReal(T->getElementType()))
+ auto ET = T->getElementType();
+ if(ET->isRealType() && !IsTypeDoublePrecisionReal(ET))
return false;
}
return DiagnoseIncompatiblePassing(E, "'real array'", false, ArgName);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 224379d939..6c39ce2166 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -145,6 +145,33 @@ QualType Sema::ActOnTypeName(ASTContext &C, DeclSpec &DS) {
break;
}
+ Type::TypeKind Kind = Type::NoKind;
+ if(DS.hasKindSelector())
+ Kind = EvalAndCheckTypeKind(Result, DS.getKindSelector());
+
+ if(Kind != Type::NoKind || DS.isDoublePrecision()) {
+ switch (DS.getTypeSpecType()) {
+ case DeclSpec::TST_integer:
+ Result = Kind == Type::NoKind? C.IntegerTy :
+ QualType(C.getBuiltinType(BuiltinType::Integer, Kind, true), 0);
+ break;
+ case DeclSpec::TST_real:
+ Result = Kind == Type::NoKind? (DS.isDoublePrecision()? C.DoublePrecisionTy : C.RealTy) :
+ QualType(C.getBuiltinType(BuiltinType::Real, Kind, true), 0);
+ break;
+ case DeclSpec::TST_logical:
+ Result = Kind == Type::NoKind? C.LogicalTy :
+ QualType(C.getBuiltinType(BuiltinType::Logical, Kind, true), 0);
+ break;
+ case DeclSpec::TST_complex:
+ Result = Kind == Type::NoKind? (DS.isDoublePrecision()? C.DoubleComplexTy : C.ComplexTy) :
+ QualType(C.getBuiltinType(BuiltinType::Complex, Kind, true), 0);
+ break;
+ default:
+ break;
+ }
+ }
+
if (!DS.hasAttributes())
return Result;
@@ -153,15 +180,7 @@ QualType Sema::ActOnTypeName(ASTContext &C, DeclSpec &DS) {
Quals.setIntentAttr(DS.getIntentSpec());
Quals.setAccessAttr(DS.getAccessSpec());
- unsigned Kind = BuiltinType::NoKind;
- if(DS.isDoublePrecision()) {
- assert(!DS.getKindSelector());
- Kind = BuiltinType::Real8;
- } else if(DS.hasKindSelector())
- Kind = EvalAndCheckTypeKind(Result, DS.getKindSelector());
-
- Result = C.getExtQualType(TypeNode, Quals, Kind,
- DS.isDoublePrecision());
+ Result = C.getExtQualType(TypeNode, Quals);
if (!Quals.hasAttributeSpec(Qualifiers::AS_dimension))
return Result;
@@ -322,8 +341,7 @@ Decl *Sema::ActOnParameterEntityDecl(ASTContext &C, QualType T,
Decl *Sema::ActOnEntityDecl(ASTContext &C, const QualType &T,
SourceLocation IDLoc, const IdentifierInfo *IDInfo) {
- auto Ext = T.getExtQualsPtrOrNull();
- Qualifiers Quals(Ext? Ext->getQualifiers() : Qualifiers());
+ auto Quals = T.getQualifiers();
if(Quals.hasAttributeSpec(Qualifiers::AS_external))
return ActOnExternalEntityDecl(C, T, IDLoc, IDInfo);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 0c2ef67f28..4f955aaf09 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -18,6 +18,16 @@
namespace flang {
+/// Returns true if a type is a double precision real type.
+bool Sema::IsTypeDoublePrecisionReal(QualType T) const {
+ return T->isRealType() && Context.isTypeDoublePrecision(T);
+}
+
+/// Returns true if a type is a double precision complex type.
+bool Sema::IsTypeDoublePrecisionComplex(QualType T) const {
+ return T->isComplexType() && Context.isTypeDoubleComplex(T);
+}
+
/// Returns TST_integer/TST_real/TST_complex if a given type
/// is an arithmetic type, or TST_unspecified otherwise
static TypeSpecifierType GetArithmeticTypeSpec(QualType T) {
@@ -27,46 +37,12 @@ static TypeSpecifierType GetArithmeticTypeSpec(QualType T) {
else return TST_unspecified;
}
-/// Returns true if a real type is also a double precision type (Kind is 8).
-static bool IsRealTypeDoublePrecision(QualType T) {
- auto Ext = T.getExtQualsPtrOrNull();
- return Ext && Ext->getKindSelector() == BuiltinType::Real8? true : false;
-}
-
-/// Returns true if a type is a double precision real type (Kind is 8).
-static bool IsTypeDoublePrecisionReal(QualType T) {
- auto Ext = T.getExtQualsPtrOrNull();
- return T->isRealType() &&
- Ext && Ext->getKindSelector() == BuiltinType::Real8? true : false;
-}
-
-/// Returns true if a type is a single precision real type (Kind is 4).
-static bool IsTypeSinglePrecisionReal(QualType T) {
- if(T->isRealType())
- return !IsRealTypeDoublePrecision(T);
- return false;
-}
-
-/// Returns true if a type is a double precision complex type (Kind is 8).
-static bool IsTypeDoublePrecisionComplex(QualType T) {
- auto Ext = T.getExtQualsPtrOrNull();
- return T->isComplexType() &&
- Ext && Ext->getKindSelector() == BuiltinType::Real8? true : false;
-}
-
-/// Returns true if two arithmetic type qualifiers have the same kind
-static bool ExtQualsSameKind(const ASTContext &C,
- const ExtQuals *A, const ExtQuals *B,
- QualType AT, QualType BT) {
- return C.ArithmeticTypesSameKind(A, AT, B, BT);
-}
-
/// Returns the largest kind between two arithmetic type qualifiers.
static int GetLargestKind(const ASTContext &C,
const ExtQuals *A, const ExtQuals *B,
QualType AT, QualType BT) {
- auto KindA = C.getArithmeticTypeKind(A, AT);
- auto KindB = C.getArithmeticTypeKind(B, BT);
+ auto KindA = AT->getBuiltinTypeKind();
+ auto KindB = BT->getBuiltinTypeKind();
return C.getTypeKindBitWidth(KindA) >= C.getTypeKindBitWidth(KindB)? 0 : 1;
}
@@ -83,8 +59,8 @@ static Expr *ImplicitCast(ASTContext &C, QualType T, ExprResult E) {
static QualType SelectLargestKindApplyConversions(ASTContext &C,
ExprResult &A, ExprResult &B,
QualType AType, QualType BType) {
- auto AK = C.getArithmeticTypeKind(AType.getExtQualsPtrOrNull(), AType);
- auto BK = C.getArithmeticTypeKind(BType.getExtQualsPtrOrNull(), BType);
+ auto AK = AType->getBuiltinTypeKind();
+ auto BK = BType->getBuiltinTypeKind();
if(AK == BK) return AType;
else if(C.getTypeKindBitWidth(AK) >=
@@ -107,10 +83,8 @@ static QualType TakeTypeSelectLargestKindApplyConversion(ASTContext &C,
ExprResult &A, ExprResult &B,
QualType AType, QualType BType) {
QualType ChosenType = Chosen == 0? AType : BType;
- const ExtQuals *AExt = AType.getExtQualsPtrOrNull();
- const ExtQuals *BExt = BType.getExtQualsPtrOrNull();
- auto AK = C.getArithmeticTypeKind(AExt, AType);
- auto BK = C.getArithmeticTypeKind(BExt, BType);
+ auto AK = AType->getBuiltinTypeKind();
+ auto BK = BType->getBuiltinTypeKind();
auto AKWidth = C.getTypeKindBitWidth(AK);
auto BKWidth = C.getTypeKindBitWidth(BK);
if(AK == BK ||
@@ -129,11 +103,6 @@ static QualType TakeTypeSelectLargestKindApplyConversion(ASTContext &C,
}
static QualType TypeWithKind(ASTContext &C, QualType T, QualType TKind) {
- const ExtQuals *AExt = T.getExtQualsPtrOrNull();
- const ExtQuals *BExt = TKind.getExtQualsPtrOrNull();
- auto AK = C.getArithmeticTypeKind(AExt, T);
- auto BK = C.getArithmeticTypeKind(BExt, TKind);
- if(AK == BK) return T;
return C.getQualTypeOtherKind(T, TKind);
}
@@ -146,8 +115,6 @@ enum TypecheckAction {
static TypecheckAction TypecheckAssignment(ASTContext &Context,
QualType LHSType, QualType RHSType) {
TypecheckAction Result = NoAction;
- auto LHSExtQuals = LHSType.getExtQualsPtrOrNull();
- auto RHSExtQuals = RHSType.getExtQualsPtrOrNull();
// Arithmetic assigment
bool IsRHSInteger = RHSType->isIntegerType();
@@ -155,20 +122,19 @@ static TypecheckAction TypecheckAssignment(ASTContext &Context,
bool IsRHSComplex = RHSType->isComplexType();
bool IsRHSArithmetic = IsRHSInteger || IsRHSReal ||
IsRHSComplex;
+ auto LHSKind = LHSType->getBuiltinTypeKind();
+ auto RHSKind = RHSType->getBuiltinTypeKind();
if(LHSType->isIntegerType()) {
- if(IsRHSInteger && ExtQualsSameKind(Context, LHSExtQuals, RHSExtQuals,
- LHSType, RHSType)) ;
+ if(IsRHSInteger && LHSKind == RHSKind) ;
else if(IsRHSArithmetic) Result = ImplicitCastAction;
else Result = ErrorAction;
} else if(LHSType->isRealType()) {
- if(IsRHSReal && ExtQualsSameKind(Context, LHSExtQuals, RHSExtQuals,
- LHSType, RHSType)) ;
+ if(IsRHSReal && LHSKind == RHSKind) ;
else if(IsRHSArithmetic) Result = ImplicitCastAction;
else Result = ErrorAction;
} else if(LHSType->isComplexType()) {
- if(IsRHSComplex && ExtQualsSameKind(Context, LHSExtQuals, RHSExtQuals,
- LHSType, RHSType)) ;
+ if(IsRHSComplex && LHSKind == RHSKind) ;
else if(IsRHSArithmetic) Result = ImplicitCastAction;
else Result = ErrorAction;
}
@@ -177,8 +143,7 @@ static TypecheckAction TypecheckAssignment(ASTContext &Context,
else if(LHSType->isLogicalType()) {
if(!RHSType->isLogicalType())
Result = ErrorAction;
- else if(!ExtQualsSameKind(Context, LHSExtQuals, RHSExtQuals,
- LHSType, RHSType))
+ else if(LHSKind != RHSKind)
Result = ImplicitCastAction;
}
@@ -316,8 +281,8 @@ ExprResult Sema::ActOnComplexConstantExpr(ASTContext &C, SourceLocation Loc,
CheckIntegerOrRealConstantExpression(ImPart.get());
if(RealType->isRealType() && ImType->isRealType()) {
- auto ReWidth = C.getTypeKindBitWidth(C.getRealTypeKind(RealType.getExtQualsPtrOrNull()));
- auto ImWidth = C.getTypeKindBitWidth(C.getRealTypeKind(ImType.getExtQualsPtrOrNull()));
+ auto ReWidth = C.getTypeKindBitWidth(RealType->getBuiltinTypeKind());
+ auto ImWidth = C.getTypeKindBitWidth(ImType->getBuiltinTypeKind());
if(ReWidth > ImWidth) {
ElementType = RealType;
ImPart = ImplicitCast(C, ElementType, ImPart);
diff --git a/lib/Sema/SemaIntrinsic.cpp b/lib/Sema/SemaIntrinsic.cpp
index 124590f4ef..a856320968 100644
--- a/lib/Sema/SemaIntrinsic.cpp
+++ b/lib/Sema/SemaIntrinsic.cpp
@@ -208,11 +208,6 @@ bool Sema::CheckIntrinsicComplexFunc(intrinsic::FunctionKind Function,
}
static QualType TypeWithKind(ASTContext &C, QualType T, QualType TKind) {
- const ExtQuals *AExt = T.getExtQualsPtrOrNull();
- const ExtQuals *BExt = TKind.getExtQualsPtrOrNull();
- auto AK = C.getArithmeticTypeKind(AExt, T);
- auto BK = C.getArithmeticTypeKind(BExt, TKind);
- if(AK == BK) return T;
return C.getQualTypeOtherKind(T, TKind);
}
@@ -523,9 +518,8 @@ bool Sema::CheckIntrinsicInquiryFunc(intrinsic::FunctionKind Function,
if(CheckIntegerArgument(Args[0], true))
ReturnType = Context.IntegerTy;
else {
- auto Kind = Context.getIntTypeKind(Args[0]->getType().getSelfOrArrayElementType()
- .getExtQualsPtrOrNull());
- ReturnType = Context.getExtQualType(Context.IntegerTy.getTypePtr(), Qualifiers(), Kind);
+ auto Kind = Args[0]->getType().getSelfOrArrayElementType();
+ ReturnType = Context.getQualTypeOtherKind(Context.IntegerTy, Kind);
}
break;
}
diff --git a/lib/Sema/Spec.cpp b/lib/Sema/Spec.cpp
index a617dbc70d..254707a133 100644
--- a/lib/Sema/Spec.cpp
+++ b/lib/Sema/Spec.cpp
@@ -143,20 +143,16 @@ bool Sema::ApplySpecification(SourceLocation StmtLoc, const SaveStmt *S) {
bool Sema::ApplySpecification(SourceLocation StmtLoc, const SaveStmt *S, VarDecl *VD) {
auto Type = VD->getType();
- auto Ext = Type.getExtQualsPtrOrNull();
- Qualifiers Quals;
- if(Ext){
- Quals = Ext->getQualifiers();
- if(Quals.hasAttributeSpec(Qualifiers::AS_save)) {
- if(S->getIdentifier()) {
- Diags.Report(StmtLoc, diag::err_spec_qual_reapplication)
- << "save" << VD->getIdentifier() << getTokenRange(S->getLocation());
- } else {
- Diags.Report(StmtLoc, diag::err_spec_qual_reapplication)
- << "save" << VD->getIdentifier();
- }
- return true;
+ auto Quals = Type.getQualifiers();
+ if(Quals.hasAttributeSpec(Qualifiers::AS_save)) {
+ if(S->getIdentifier()) {
+ Diags.Report(StmtLoc, diag::err_spec_qual_reapplication)
+ << "save" << VD->getIdentifier() << getTokenRange(S->getLocation());
+ } else {
+ Diags.Report(StmtLoc, diag::err_spec_qual_reapplication)
+ << "save" << VD->getIdentifier();
}
+ return true;
}
Quals.addAttributeSpecs(Qualifiers::AS_save);
VD->setType(Context.getQualifiedType(Type, Quals));