diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-04 01:25:59 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-04 01:25:59 +0000 |
commit | 38c1f7c254e6e699d3e45e446fa4515418a00c9a (patch) | |
tree | 6b2f0f3d09ec6870dfb652c484c6df9c4a3fc1aa /lib/AST/Type.cpp | |
parent | 572ddc2d7c229fd9f44c13466b772e005409730f (diff) | |
download | clang-38c1f7c254e6e699d3e45e446fa4515418a00c9a.tar.gz |
Properly handle instantiation-dependent array bounds.
We previously failed to treat an array with an instantiation-dependent
but not value-dependent bound as being an instantiation-dependent type.
We now track the array bound expression as part of a constant array type
if it's an instantiation-dependent expression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@373685 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 8ab2f1e271..4fed5b410b 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -109,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) { @@ -156,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, @@ -860,7 +899,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()); } @@ -3590,6 +3629,7 @@ static CachedProperties computeCachedProperties(const Type *T) { #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class: #include "clang/AST/TypeNodes.inc" // Treat instantiation-dependent types as external. + if (!T->isInstantiationDependentType()) T->dump(); assert(T->isInstantiationDependentType()); return CachedProperties(ExternalLinkage, false); |