diff options
Diffstat (limited to 'include/clang/AST/Type.h')
| -rw-r--r-- | include/clang/AST/Type.h | 160 |
1 files changed, 108 insertions, 52 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 09862e4fb7f77..1bda01fee8ad8 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -16,6 +16,7 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" +#include "clang/Basic/AddressSpaces.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/LLVM.h" @@ -25,11 +26,11 @@ #include "clang/Basic/Visibility.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/Twine.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" namespace clang { @@ -400,21 +401,36 @@ public: Mask |= qs.Mask; } + /// \brief Returns true if this address space is a superset of the other one. + /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of + /// overlapping address spaces. + /// CL1.1 or CL1.2: + /// every address space is a superset of itself. + /// CL2.0 adds: + /// __generic is a superset of any address space except for __constant. + bool isAddressSpaceSupersetOf(Qualifiers other) const { + return + // Address spaces must match exactly. + getAddressSpace() == other.getAddressSpace() || + // Otherwise in OpenCLC v2.0 s6.5.5: every address space except + // for __constant can be used as __generic. + (getAddressSpace() == LangAS::opencl_generic && + other.getAddressSpace() != LangAS::opencl_constant); + } + /// \brief Determines if these qualifiers compatibly include another set. /// Generally this answers the question of whether an object with the other /// qualifiers can be safely used as an object with these qualifiers. bool compatiblyIncludes(Qualifiers other) const { - return - // Address spaces must match exactly. - getAddressSpace() == other.getAddressSpace() && - // ObjC GC qualifiers can match, be added, or be removed, but can't be - // changed. - (getObjCGCAttr() == other.getObjCGCAttr() || - !hasObjCGCAttr() || !other.hasObjCGCAttr()) && - // ObjC lifetime qualifiers must match exactly. - getObjCLifetime() == other.getObjCLifetime() && - // CVR qualifiers may subset. - (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); + return isAddressSpaceSupersetOf(other) && + // ObjC GC qualifiers can match, be added, or be removed, but can't + // be changed. + (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || + !other.hasObjCGCAttr()) && + // ObjC lifetime qualifiers must match exactly. + getObjCLifetime() == other.getObjCLifetime() && + // CVR qualifiers may subset. + (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); } /// \brief Determines if these qualifiers compatibly include another set of @@ -1245,6 +1261,7 @@ protected: class FunctionTypeBitfields { friend class FunctionType; + friend class FunctionProtoType; unsigned : NumTypeBits; @@ -1259,6 +1276,11 @@ protected: /// C++ 8.3.5p4: The return type, the parameter type list and the /// cv-qualifier-seq, [...], are part of the function type. unsigned TypeQuals : 3; + + /// \brief The ref-qualifier associated with a \c FunctionProtoType. + /// + /// This is a value of type \c RefQualifierKind. + unsigned RefQualifier : 2; }; class ObjCObjectTypeBitfields { @@ -1685,6 +1707,11 @@ public: /// type of a class template or class template partial specialization. CXXRecordDecl *getAsCXXRecordDecl() const; + /// \brief Retrieves the TagDecl that this type refers to, either + /// because the type is a TagType or because it is the injected-class-name + /// type of a class template or class template partial specialization. + TagDecl *getAsTagDecl() const; + /// If this is a pointer or reference to a RecordType, return the /// CXXRecordDecl that that type refers to. /// @@ -1982,6 +2009,22 @@ public: QualType getPointeeType() const { return PointeeType; } + /// \brief Returns true if address spaces of pointers overlap. + /// OpenCL v2.0 defines conversion rules for pointers to different + /// address spaces (OpenCLC v2.0 s6.5.5) and notion of overlapping + /// address spaces. + /// CL1.1 or CL1.2: + /// address spaces overlap iff they are they same. + /// CL2.0 adds: + /// __generic overlaps with any address space except for __constant. + bool isAddressSpaceOverlapping(const PointerType &other) const { + Qualifiers thisQuals = PointeeType.getQualifiers(); + Qualifiers otherQuals = other.getPointeeType().getQualifiers(); + // Address spaces overlap if at least one of them is a superset of another + return thisQuals.isAddressSpaceSupersetOf(otherQuals) || + otherQuals.isAddressSpaceSupersetOf(thisQuals); + } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2765,7 +2808,7 @@ class FunctionType : public Type { protected: FunctionType(TypeClass tc, QualType res, - unsigned typeQuals, QualType Canonical, bool Dependent, + QualType Canonical, bool Dependent, bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack, ExtInfo Info) @@ -2773,7 +2816,6 @@ protected: ContainsUnexpandedParameterPack), ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; - FunctionTypeBits.TypeQuals = typeQuals; } unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; } @@ -2810,7 +2852,7 @@ public: /// no information available about its arguments. class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) - : FunctionType(FunctionNoProto, Result, 0, Canonical, + : FunctionType(FunctionNoProto, Result, Canonical, /*Dependent=*/false, /*InstantiationDependent=*/false, Result->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false, Info) {} @@ -2844,33 +2886,51 @@ public: /// type. class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { public: + struct ExceptionSpecInfo { + ExceptionSpecInfo() + : Type(EST_None), NoexceptExpr(nullptr), + SourceDecl(nullptr), SourceTemplate(nullptr) {} + + ExceptionSpecInfo(ExceptionSpecificationType EST) + : Type(EST), NoexceptExpr(nullptr), SourceDecl(nullptr), + SourceTemplate(nullptr) {} + + /// The kind of exception specification this is. + ExceptionSpecificationType Type; + /// Explicitly-specified list of exception types. + ArrayRef<QualType> Exceptions; + /// Noexcept expression, if this is EST_ComputedNoexcept. + Expr *NoexceptExpr; + /// The function whose exception specification this is, for + /// EST_Unevaluated and EST_Uninstantiated. + FunctionDecl *SourceDecl; + /// The function template whose exception specification this is instantiated + /// from, for EST_Uninstantiated. + FunctionDecl *SourceTemplate; + }; + /// ExtProtoInfo - Extra information about a function prototype. struct ExtProtoInfo { ExtProtoInfo() : Variadic(false), HasTrailingReturn(false), TypeQuals(0), - ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0), - Exceptions(nullptr), NoexceptExpr(nullptr), - ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr), - ConsumedParameters(nullptr) {} + RefQualifier(RQ_None), ConsumedParameters(nullptr) {} ExtProtoInfo(CallingConv CC) : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0), - ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0), - Exceptions(nullptr), NoexceptExpr(nullptr), - ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr), - ConsumedParameters(nullptr) {} + RefQualifier(RQ_None), ConsumedParameters(nullptr) {} + + ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) { + ExtProtoInfo Result(*this); + Result.ExceptionSpec = O; + return Result; + } FunctionType::ExtInfo ExtInfo; bool Variadic : 1; bool HasTrailingReturn : 1; unsigned char TypeQuals; - ExceptionSpecificationType ExceptionSpecType; RefQualifierKind RefQualifier; - unsigned NumExceptions; - const QualType *Exceptions; - Expr *NoexceptExpr; - FunctionDecl *ExceptionSpecDecl; - FunctionDecl *ExceptionSpecTemplate; + ExceptionSpecInfo ExceptionSpec; const bool *ConsumedParameters; }; @@ -2896,7 +2956,7 @@ private: unsigned NumExceptions : 9; /// ExceptionSpecType - The type of exception specification this function has. - unsigned ExceptionSpecType : 3; + unsigned ExceptionSpecType : 4; /// HasAnyConsumedParams - Whether this function has any consumed parameters. unsigned HasAnyConsumedParams : 1; @@ -2907,11 +2967,6 @@ private: /// HasTrailingReturn - Whether this function has a trailing return type. unsigned HasTrailingReturn : 1; - /// \brief The ref-qualifier associated with a \c FunctionProtoType. - /// - /// This is a value of type \c RefQualifierKind. - unsigned RefQualifier : 2; - // ParamInfo - There is an variable size array after the class in memory that // holds the parameter types. @@ -2952,7 +3007,7 @@ public: return param_type_begin()[i]; } ArrayRef<QualType> getParamTypes() const { - return ArrayRef<QualType>(param_type_begin(), param_type_end()); + return llvm::makeArrayRef(param_type_begin(), param_type_end()); } ExtProtoInfo getExtProtoInfo() const { @@ -2960,19 +3015,18 @@ public: EPI.ExtInfo = getExtInfo(); EPI.Variadic = isVariadic(); EPI.HasTrailingReturn = hasTrailingReturn(); - EPI.ExceptionSpecType = getExceptionSpecType(); + EPI.ExceptionSpec.Type = getExceptionSpecType(); EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals()); EPI.RefQualifier = getRefQualifier(); - if (EPI.ExceptionSpecType == EST_Dynamic) { - EPI.NumExceptions = NumExceptions; - EPI.Exceptions = exception_begin(); - } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { - EPI.NoexceptExpr = getNoexceptExpr(); - } else if (EPI.ExceptionSpecType == EST_Uninstantiated) { - EPI.ExceptionSpecDecl = getExceptionSpecDecl(); - EPI.ExceptionSpecTemplate = getExceptionSpecTemplate(); - } else if (EPI.ExceptionSpecType == EST_Unevaluated) { - EPI.ExceptionSpecDecl = getExceptionSpecDecl(); + if (EPI.ExceptionSpec.Type == EST_Dynamic) { + EPI.ExceptionSpec.Exceptions = exceptions(); + } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) { + EPI.ExceptionSpec.NoexceptExpr = getNoexceptExpr(); + } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) { + EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl(); + EPI.ExceptionSpec.SourceTemplate = getExceptionSpecTemplate(); + } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) { + EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl(); } if (hasAnyConsumedParams()) EPI.ConsumedParameters = getConsumedParamsBuffer(); @@ -2995,6 +3049,8 @@ public: bool hasNoexceptExceptionSpec() const { return isNoexceptExceptionSpec(getExceptionSpecType()); } + /// \brief Return whether this function has a dependent exception spec. + bool hasDependentExceptionSpec() const; /// \brief Result type of getNoexceptSpec(). enum NoexceptResult { NR_NoNoexcept, ///< There is no noexcept specifier. @@ -3057,7 +3113,7 @@ public: /// \brief Retrieve the ref-qualifier associated with this function type. RefQualifierKind getRefQualifier() const { - return static_cast<RefQualifierKind>(RefQualifier); + return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); } typedef const QualType *param_type_iterator; @@ -3074,10 +3130,9 @@ public: } typedef const QualType *exception_iterator; - typedef llvm::iterator_range<exception_iterator> exception_range; - exception_range exceptions() const { - return exception_range(exception_begin(), exception_end()); + ArrayRef<QualType> exceptions() const { + return llvm::makeArrayRef(exception_begin(), exception_end()); } exception_iterator exception_begin() const { // exceptions begin where arguments end @@ -3416,6 +3471,7 @@ public: attr_stdcall, attr_thiscall, attr_pascal, + attr_vectorcall, attr_pnaclcall, attr_inteloclbicc, attr_ms_abi, @@ -5231,8 +5287,8 @@ template <typename T> const T *Type::castAs() const { ArrayType_cannot_be_used_with_getAs<T> at; (void) at; - assert(isa<T>(CanonicalType)); if (const T *ty = dyn_cast<T>(this)) return ty; + assert(isa<T>(CanonicalType)); return cast<T>(getUnqualifiedDesugaredType()); } |
