aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST/Type.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Type.h')
-rw-r--r--include/clang/AST/Type.h160
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());
}