diff options
author | arphaman <arphaman@gmail.com> | 2013-09-19 16:27:51 +0100 |
---|---|---|
committer | arphaman <arphaman@gmail.com> | 2013-09-19 16:27:51 +0100 |
commit | 3b95e9a2d88dbcc4e83ce1184a591f15f21add9b (patch) | |
tree | ba286f7e458b9838ae642f5ddccc1fc0b70e7a5e | |
parent | 2d9553a89153be4ed76408c439e749b88a16b8d2 (diff) | |
download | flang-3b95e9a2d88dbcc4e83ce1184a591f15f21add9b.tar.gz |
Moved type kinds from ExtQuals to Type
-rw-r--r-- | include/flang/AST/ASTContext.h | 143 | ||||
-rw-r--r-- | include/flang/AST/Type.h | 133 | ||||
-rw-r--r-- | include/flang/AST/TypeVisitor.h | 9 | ||||
-rw-r--r-- | include/flang/Sema/Sema.h | 6 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 93 | ||||
-rw-r--r-- | lib/AST/ASTDumper.cpp | 33 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGIOLibflang.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGIntrinsic.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CGSystemLibflang.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 1 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 87 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 64 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 83 | ||||
-rw-r--r-- | lib/Sema/SemaIntrinsic.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/Spec.cpp | 22 |
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)); |