aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r--lib/AST/Type.cpp113
1 files changed, 93 insertions, 20 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index ed75a0b5bcd8..4d54ea1061ed 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -50,6 +50,7 @@
#include <cassert>
#include <cstdint>
#include <cstring>
+#include <type_traits>
using namespace clang;
@@ -74,11 +75,11 @@ const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
if (ty->isPointerType() || ty->isReferenceType())
return ty->getPointeeType().getBaseTypeIdentifier();
else if (ty->isRecordType())
- ND = ty->getAs<RecordType>()->getDecl();
+ ND = ty->castAs<RecordType>()->getDecl();
else if (ty->isEnumeralType())
- ND = ty->getAs<EnumType>()->getDecl();
+ ND = ty->castAs<EnumType>()->getDecl();
else if (ty->getTypeClass() == Type::Typedef)
- ND = ty->getAs<TypedefType>()->getDecl();
+ ND = ty->castAs<TypedefType>()->getDecl();
else if (ty->isArrayType())
return ty->castAsArrayTypeUnsafe()->
getElementType().getBaseTypeIdentifier();
@@ -108,6 +109,33 @@ bool QualType::isConstant(QualType T, const ASTContext &Ctx) {
return T.getAddressSpace() == LangAS::opencl_constant;
}
+// C++ [temp.dep.type]p1:
+// A type is dependent if it is...
+// - an array type constructed from any dependent type or whose
+// size is specified by a constant expression that is
+// value-dependent,
+ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,
+ ArraySizeModifier sm, unsigned tq, const Expr *sz)
+ // Note, we need to check for DependentSizedArrayType explicitly here
+ // because we use a DependentSizedArrayType with no size expression as the
+ // type of a dependent array of unknown bound with a dependent braced
+ // initializer:
+ //
+ // template<int ...N> int arr[] = {N...};
+ : Type(tc, can,
+ et->isDependentType() || (sz && sz->isValueDependent()) ||
+ tc == DependentSizedArray,
+ et->isInstantiationDependentType() ||
+ (sz && sz->isInstantiationDependent()) ||
+ tc == DependentSizedArray,
+ (tc == VariableArray || et->isVariablyModifiedType()),
+ et->containsUnexpandedParameterPack() ||
+ (sz && sz->containsUnexpandedParameterPack())),
+ ElementType(et) {
+ ArrayTypeBits.IndexTypeQuals = tq;
+ ArrayTypeBits.SizeModifier = sm;
+}
+
unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
QualType ElementType,
const llvm::APInt &NumElements) {
@@ -155,14 +183,26 @@ unsigned ConstantArrayType::getMaxSizeBits(const ASTContext &Context) {
return Bits;
}
+void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID,
+ const ASTContext &Context, QualType ET,
+ const llvm::APInt &ArraySize,
+ const Expr *SizeExpr, ArraySizeModifier SizeMod,
+ unsigned TypeQuals) {
+ ID.AddPointer(ET.getAsOpaquePtr());
+ ID.AddInteger(ArraySize.getZExtValue());
+ ID.AddInteger(SizeMod);
+ ID.AddInteger(TypeQuals);
+ ID.AddBoolean(SizeExpr != 0);
+ if (SizeExpr)
+ SizeExpr->Profile(ID, Context, true);
+}
+
DependentSizedArrayType::DependentSizedArrayType(const ASTContext &Context,
QualType et, QualType can,
Expr *e, ArraySizeModifier sm,
unsigned tq,
SourceRange brackets)
- : ArrayType(DependentSizedArray, et, can, sm, tq,
- (et->containsUnexpandedParameterPack() ||
- (e && e->containsUnexpandedParameterPack()))),
+ : ArrayType(DependentSizedArray, et, can, sm, tq, e),
Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
@@ -297,7 +337,19 @@ QualType QualType::getSingleStepDesugaredTypeImpl(QualType type,
#define TYPE(CLASS, BASE) \
static_assert(!std::is_polymorphic<CLASS##Type>::value, \
#CLASS "Type should not be polymorphic!");
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
+
+// Check that no type class has a non-trival destructor. Types are
+// allocated with the BumpPtrAllocator from ASTContext and therefore
+// their destructor is not executed.
+//
+// FIXME: ConstantArrayType is not trivially destructible because of its
+// APInt member. It should be replaced in favor of ASTContext allocation.
+#define TYPE(CLASS, BASE) \
+ static_assert(std::is_trivially_destructible<CLASS##Type>::value || \
+ std::is_same<CLASS##Type, ConstantArrayType>::value, \
+ #CLASS "Type should be trivially destructible!");
+#include "clang/AST/TypeNodes.inc"
QualType Type::getLocallyUnqualifiedSingleStepDesugaredType() const {
switch (getTypeClass()) {
@@ -308,7 +360,7 @@ QualType Type::getLocallyUnqualifiedSingleStepDesugaredType() const {
if (!ty->isSugared()) return QualType(ty, 0); \
return ty->desugar(); \
}
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
llvm_unreachable("bad type kind!");
}
@@ -329,7 +381,7 @@ SplitQualType QualType::getSplitDesugaredType(QualType T) {
Cur = Ty->desugar(); \
break; \
}
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
}
}
@@ -357,7 +409,7 @@ SplitQualType QualType::getSplitUnqualifiedTypeImpl(QualType type) {
next = ty->desugar(); \
break; \
}
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
// Otherwise, split the underlying type. If that yields qualifiers,
@@ -396,7 +448,7 @@ template<typename T> static const T *getAsSugar(const Type *Cur) {
Cur = Ty->desugar().getTypePtr(); \
break; \
}
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
}
}
@@ -429,7 +481,7 @@ const Type *Type::getUnqualifiedDesugaredType() const {
Cur = Ty->desugar().getTypePtr(); \
break; \
}
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
}
}
@@ -611,6 +663,10 @@ ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D,
initialize(protocols);
}
+QualType ObjCTypeParamType::desugar() const {
+ return getDecl()->getUnderlyingType();
+}
+
ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
@@ -753,7 +809,7 @@ public:
#define TYPE(Class, Base)
#define DEPENDENT_TYPE(Class, Base) \
QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
#define TRIVIAL_TYPE_CLASS(Class) \
QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
@@ -847,7 +903,7 @@ public:
if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
return QualType(T, 0);
- return Ctx.getConstantArrayType(elementType, T->getSize(),
+ return Ctx.getConstantArrayType(elementType, T->getSize(), T->getSizeExpr(),
T->getSizeModifier(),
T->getIndexTypeCVRQualifiers());
}
@@ -2477,6 +2533,15 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const {
return false;
}
+bool Type::isNothrowT() const {
+ if (const auto *RD = getAsCXXRecordDecl()) {
+ IdentifierInfo *II = RD->getIdentifier();
+ if (II && II->isStr("nothrow_t") && RD->isInStdNamespace())
+ return true;
+ }
+ return false;
+}
+
bool Type::isAlignValT() const {
if (const auto *ET = getAs<EnumType>()) {
IdentifierInfo *II = ET->getDecl()->getIdentifier();
@@ -2690,7 +2755,7 @@ const char *Type::getTypeClassName() const {
switch (TypeBits.TC) {
#define ABSTRACT_TYPE(Derived, Base)
#define TYPE(Derived, Base) case Derived: return #Derived;
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
}
llvm_unreachable("Invalid type class.");
@@ -2841,6 +2906,10 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
case Id: \
return #ExtType;
#include "clang/Basic/OpenCLExtensionTypes.def"
+#define SVE_TYPE(Name, Id, SingletonId) \
+ case Id: \
+ return Name;
+#include "clang/Basic/AArch64SVEACLETypes.def"
}
llvm_unreachable("Invalid builtin type.");
@@ -3556,14 +3625,15 @@ static CachedProperties computeCachedProperties(const Type *T) {
switch (T->getTypeClass()) {
#define TYPE(Class,Base)
#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
llvm_unreachable("didn't expect a non-canonical type here");
#define TYPE(Class,Base)
#define DEPENDENT_TYPE(Class,Base) case Type::Class:
#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
// Treat instantiation-dependent types as external.
+ if (!T->isInstantiationDependentType()) T->dump();
assert(T->isInstantiationDependentType());
return CachedProperties(ExternalLinkage, false);
@@ -3659,13 +3729,13 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
switch (T->getTypeClass()) {
#define TYPE(Class,Base)
#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
llvm_unreachable("didn't expect a non-canonical type here");
#define TYPE(Class,Base)
#define DEPENDENT_TYPE(Class,Base) case Type::Class:
#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
// Treat instantiation-dependent types as external.
assert(T->isInstantiationDependentType());
return LinkageInfo::external();
@@ -3774,7 +3844,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::Class: \
llvm_unreachable("non-canonical type");
#define TYPE(Class, Parent)
-#include "clang/AST/TypeNodes.def"
+#include "clang/AST/TypeNodes.inc"
// Pointer types.
case Type::Pointer:
@@ -3842,6 +3912,9 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case BuiltinType::OCLClkEvent:
case BuiltinType::OCLQueue:
case BuiltinType::OCLReserveID:
+#define SVE_TYPE(Name, Id, SingletonId) \
+ case BuiltinType::Id:
+#include "clang/Basic/AArch64SVEACLETypes.def"
case BuiltinType::BuiltinFn:
case BuiltinType::NullPtr:
case BuiltinType::OMPArraySection: