From: Richard Smith Date: Fri, 4 Oct 2019 01:25:59 +0000 (+0000) Subject: Properly handle instantiation-dependent array bounds. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=38c1f7c254e6e699d3e45e446fa4515418a00c9a;p=clang 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 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 66bd4aa1e3..5105b9c35c 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -185,7 +185,8 @@ private: mutable llvm::FoldingSet LValueReferenceTypes; mutable llvm::FoldingSet RValueReferenceTypes; mutable llvm::FoldingSet MemberPointerTypes; - mutable llvm::FoldingSet ConstantArrayTypes; + mutable llvm::ContextualFoldingSet + ConstantArrayTypes; mutable llvm::FoldingSet IncompleteArrayTypes; mutable std::vector VariableArrayTypes; mutable llvm::FoldingSet DependentSizedArrayTypes; @@ -1330,6 +1331,7 @@ public: /// Return the unique reference to the type for a constant array of /// the specified element type. QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, + const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const; diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 7d5faf2b8c..426c256b6a 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -959,8 +959,11 @@ DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); }) DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); }) -DEF_TRAVERSE_TYPE(ConstantArrayType, - { TRY_TO(TraverseType(T->getElementType())); }) +DEF_TRAVERSE_TYPE(ConstantArrayType, { + TRY_TO(TraverseType(T->getElementType())); + if (T->getSizeExpr()) + TRY_TO(TraverseStmt(const_cast(T->getSizeExpr()))); +}) DEF_TRAVERSE_TYPE(IncompleteArrayType, { TRY_TO(TraverseType(T->getElementType())); }) diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 2f00034c0e..ecbbd73e19 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1513,6 +1513,15 @@ protected: unsigned SizeModifier : 3; }; + class ConstantArrayTypeBitfields { + friend class ConstantArrayType; + + unsigned : NumTypeBits + 3 + 3; + + /// Whether we have a stored size expression. + unsigned HasStoredSizeExpr : 1; + }; + class BuiltinTypeBitfields { friend class BuiltinType; @@ -1734,6 +1743,7 @@ protected: union { TypeBitfields TypeBits; ArrayTypeBitfields ArrayTypeBits; + ConstantArrayTypeBitfields ConstantArrayTypeBits; AttributedTypeBitfields AttributedTypeBits; AutoTypeBitfields AutoTypeBits; BuiltinTypeBitfields BuiltinTypeBits; @@ -2864,22 +2874,8 @@ private: protected: friend class ASTContext; // ASTContext creates these. - // 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(TypeClass tc, QualType et, QualType can, - ArraySizeModifier sm, unsigned tq, - bool ContainsUnexpandedParameterPack) - : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, - et->isInstantiationDependentType() || tc == DependentSizedArray, - (tc == VariableArray || et->isVariablyModifiedType()), - ContainsUnexpandedParameterPack), - ElementType(et) { - ArrayTypeBits.IndexTypeQuals = tq; - ArrayTypeBits.SizeModifier = sm; - } + ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm, + unsigned tq, const Expr *sz = nullptr); public: QualType getElementType() const { return ElementType; } @@ -2907,25 +2903,35 @@ public: /// Represents the canonical version of C arrays with a specified constant size. /// For example, the canonical type for 'int A[4 + 4*100]' is a /// ConstantArrayType where the element type is 'int' and the size is 404. -class ConstantArrayType : public ArrayType { +class ConstantArrayType final + : public ArrayType, + private llvm::TrailingObjects { + friend class ASTContext; // ASTContext creates these. + friend TrailingObjects; + llvm::APInt Size; // Allows us to unique the type. ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, - ArraySizeModifier sm, unsigned tq) - : ArrayType(ConstantArray, et, can, sm, tq, - et->containsUnexpandedParameterPack()), - Size(size) {} - -protected: - friend class ASTContext; // ASTContext creates these. + const Expr *sz, ArraySizeModifier sm, unsigned tq) + : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) { + ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr; + if (ConstantArrayTypeBits.HasStoredSizeExpr) { + assert(!can.isNull() && "canonical constant array should not have size"); + *getTrailingObjects() = sz; + } + } - ConstantArrayType(TypeClass tc, QualType et, QualType can, - const llvm::APInt &size, ArraySizeModifier sm, unsigned tq) - : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()), - Size(size) {} + unsigned numTrailingObjects(OverloadToken) const { + return ConstantArrayTypeBits.HasStoredSizeExpr; + } public: const llvm::APInt &getSize() const { return Size; } + const Expr *getSizeExpr() const { + return ConstantArrayTypeBits.HasStoredSizeExpr + ? *getTrailingObjects() + : nullptr; + } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2939,19 +2945,15 @@ public: /// can require, which limits the maximum size of the array. static unsigned getMaxSizeBits(const ASTContext &Context); - void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getElementType(), getSize(), + void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { + Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(), getSizeModifier(), getIndexTypeCVRQualifiers()); } - static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, - const llvm::APInt &ArraySize, ArraySizeModifier SizeMod, - unsigned TypeQuals) { - ID.AddPointer(ET.getAsOpaquePtr()); - ID.AddInteger(ArraySize.getZExtValue()); - ID.AddInteger(SizeMod); - ID.AddInteger(TypeQuals); - } + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, + QualType ET, const llvm::APInt &ArraySize, + const Expr *SizeExpr, ArraySizeModifier SizeMod, + unsigned TypeQuals); static bool classof(const Type *T) { return T->getTypeClass() == ConstantArray; @@ -2966,8 +2968,7 @@ class IncompleteArrayType : public ArrayType { IncompleteArrayType(QualType et, QualType can, ArraySizeModifier sm, unsigned tq) - : ArrayType(IncompleteArray, et, can, sm, tq, - et->containsUnexpandedParameterPack()) {} + : ArrayType(IncompleteArray, et, can, sm, tq) {} public: friend class StmtIteratorBase; @@ -3019,8 +3020,7 @@ class VariableArrayType : public ArrayType { VariableArrayType(QualType et, QualType can, Expr *e, ArraySizeModifier sm, unsigned tq, SourceRange brackets) - : ArrayType(VariableArray, et, can, sm, tq, - et->containsUnexpandedParameterPack()), + : ArrayType(VariableArray, et, can, sm, tq, e), SizeExpr((Stmt*) e), Brackets(brackets) {} public: diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index fd84209463..a41b64ffcc 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -829,7 +829,8 @@ static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI, ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins) - : FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()), + : ConstantArrayTypes(this_()), FunctionProtoTypes(this_()), + TemplateSpecializationTypes(this_()), DependentTemplateSpecializationTypes(this_()), SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts), SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)), @@ -3165,31 +3166,38 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const { /// array of the specified element type. QualType ASTContext::getConstantArrayType(QualType EltTy, const llvm::APInt &ArySizeIn, + const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const { assert((EltTy->isDependentType() || EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && "Constant array of VLAs is illegal!"); + // We only need the size as part of the type if it's instantiation-dependent. + if (SizeExpr && !SizeExpr->isInstantiationDependent()) + SizeExpr = nullptr; + // Convert the array size into a canonical width matching the pointer size for // the target. llvm::APInt ArySize(ArySizeIn); ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth()); llvm::FoldingSetNodeID ID; - ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals); + ConstantArrayType::Profile(ID, *this, EltTy, ArySize, SizeExpr, ASM, + IndexTypeQuals); void *InsertPos = nullptr; if (ConstantArrayType *ATP = ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(ATP, 0); - // If the element type isn't canonical or has qualifiers, this won't - // be a canonical type either, so fill in the canonical type field. + // If the element type isn't canonical or has qualifiers, or the array bound + // is instantiation-dependent, this won't be a canonical type either, so fill + // in the canonical type field. QualType Canon; - if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) { + if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers() || SizeExpr) { SplitQualType canonSplit = getCanonicalType(EltTy).split(); - Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, + Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, nullptr, ASM, IndexTypeQuals); Canon = getQualifiedType(Canon, canonSplit.Quals); @@ -3199,8 +3207,11 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } - auto *New = new (*this,TypeAlignment) - ConstantArrayType(EltTy, Canon, ArySize, ASM, IndexTypeQuals); + void *Mem = Allocate( + ConstantArrayType::totalSizeToAlloc(SizeExpr ? 1 : 0), + TypeAlignment); + auto *New = new (Mem) + ConstantArrayType(EltTy, Canon, ArySize, SizeExpr, ASM, IndexTypeQuals); ConstantArrayTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, 0); @@ -3297,6 +3308,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { result = getConstantArrayType( getVariableArrayDecayedType(cat->getElementType()), cat->getSize(), + cat->getSizeExpr(), cat->getSizeModifier(), cat->getIndexTypeCVRQualifiers()); break; @@ -5192,7 +5204,7 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type, if (const auto *CAT = dyn_cast(AT)) { return getConstantArrayType(unqualElementType, CAT->getSize(), - CAT->getSizeModifier(), 0); + CAT->getSizeExpr(), CAT->getSizeModifier(), 0); } if (const auto *IAT = dyn_cast(AT)) { @@ -5565,6 +5577,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const { if (const auto *CAT = dyn_cast(ATy)) return cast(getConstantArrayType(NewEltTy, CAT->getSize(), + CAT->getSizeExpr(), CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers())); if (const auto *IAT = dyn_cast(ATy)) @@ -7471,7 +7484,7 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); QualType VaListTagArrayType = Context->getConstantArrayType(VaListTagTypedefType, - Size, ArrayType::Normal, 0); + Size, nullptr, ArrayType::Normal, 0); return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } @@ -7524,16 +7537,16 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { // typedef struct __va_list_tag __builtin_va_list[1]; llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); - QualType VaListTagArrayType = - Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0); + QualType VaListTagArrayType = Context->getConstantArrayType( + VaListTagType, Size, nullptr, ArrayType::Normal, 0); return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) { // typedef int __builtin_va_list[4]; llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 4); - QualType IntArrayType = - Context->getConstantArrayType(Context->IntTy, Size, ArrayType::Normal, 0); + QualType IntArrayType = Context->getConstantArrayType( + Context->IntTy, Size, nullptr, ArrayType::Normal, 0); return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list"); } @@ -7627,8 +7640,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { // typedef __va_list_tag __builtin_va_list[1]; llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1); - QualType VaListTagArrayType = - Context->getConstantArrayType(VaListTagType, Size, ArrayType::Normal, 0); + QualType VaListTagArrayType = Context->getConstantArrayType( + VaListTagType, Size, nullptr, ArrayType::Normal, 0); return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } @@ -9072,10 +9085,14 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, return LHS; if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) return RHS; - if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(), - ArrayType::ArraySizeModifier(), 0); - if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(), - ArrayType::ArraySizeModifier(), 0); + if (LCAT) + return getConstantArrayType(ResultType, LCAT->getSize(), + LCAT->getSizeExpr(), + ArrayType::ArraySizeModifier(), 0); + if (RCAT) + return getConstantArrayType(ResultType, RCAT->getSize(), + RCAT->getSizeExpr(), + ArrayType::ArraySizeModifier(), 0); if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType)) return LHS; if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType)) @@ -10317,7 +10334,7 @@ QualType ASTContext::getStringLiteralArrayType(QualType EltTy, // Get an array type for the string, according to C99 6.4.5. This includes // the null terminator character. - return getConstantArrayType(EltTy, llvm::APInt(32, Length + 1), + return getConstantArrayType(EltTy, llvm::APInt(32, Length + 1), nullptr, ArrayType::Normal, /*IndexTypeQuals*/ 0); } diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 057444ac99..e483216e8f 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -1098,14 +1098,16 @@ ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) { ExpectedType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) { - ExpectedType ToElementTypeOrErr = import(T->getElementType()); - if (!ToElementTypeOrErr) - return ToElementTypeOrErr.takeError(); + QualType ToElementType; + const Expr *ToSizeExpr; + if (auto Imp = importSeq(T->getElementType(), T->getSizeExpr())) + std::tie(ToElementType, ToSizeExpr) = *Imp; + else + return Imp.takeError(); - return Importer.getToContext().getConstantArrayType(*ToElementTypeOrErr, - T->getSize(), - T->getSizeModifier(), - T->getIndexTypeCVRQualifiers()); + return Importer.getToContext().getConstantArrayType( + ToElementType, T->getSize(), ToSizeExpr, T->getSizeModifier(), + T->getIndexTypeCVRQualifiers()); } ExpectedType diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 169e7ae1e1..8c56a3cc55 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -6004,8 +6004,8 @@ static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, return false; } - QualType AllocType = - Info.Ctx.getConstantArrayType(ElemType, Size, ArrayType::Normal, 0); + QualType AllocType = Info.Ctx.getConstantArrayType(ElemType, Size, nullptr, + ArrayType::Normal, 0); APValue *Val = Info.createHeapAlloc(E, AllocType, Result); *Val = APValue(APValue::UninitArray(), 0, Size.getZExtValue()); Result.addArray(Info, E, cast(AllocType)); @@ -8561,7 +8561,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { ResizedArrayILE = cast(Init); } - AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, + AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr, ArrayType::Normal, 0); } else { assert(!AllocType->isArrayType() && 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 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); diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp index f9915a1a8f..afddfb7660 100644 --- a/lib/CodeGen/CGAtomic.cpp +++ b/lib/CodeGen/CGAtomic.cpp @@ -102,8 +102,9 @@ namespace { llvm::APInt Size( /*numBits=*/32, C.toCharUnitsFromBits(AtomicSizeInBits).getQuantity()); - AtomicTy = C.getConstantArrayType(C.CharTy, Size, ArrayType::Normal, - /*IndexTypeQuals=*/0); + AtomicTy = + C.getConstantArrayType(C.CharTy, Size, nullptr, ArrayType::Normal, + /*IndexTypeQuals=*/0); } AtomicAlign = ValueAlign = lvalue.getAlignment(); } else if (lvalue.isVectorElt()) { diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 527e512e6a..905db49747 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -3791,7 +3791,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, -> std::tuple { llvm::APInt ArraySize(32, NumArgs - First); QualType SizeArrayTy = getContext().getConstantArrayType( - getContext().getSizeType(), ArraySize, ArrayType::Normal, + getContext().getSizeType(), ArraySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); auto Tmp = CreateMemTemp(SizeArrayTy, "block_sizes"); llvm::Value *TmpPtr = Tmp.getPointer(); diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 576d1b6331..ca91618f16 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -3276,8 +3276,8 @@ void CGDebugInfo::collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit, llvm::APInt ConstVal(32, 1); QualType ET = CGM.getContext().getAsArrayType(T)->getElementType(); - T = CGM.getContext().getConstantArrayType(ET, ConstVal, ArrayType::Normal, - 0); + T = CGM.getContext().getConstantArrayType(ET, ConstVal, nullptr, + ArrayType::Normal, 0); } Name = VD->getName(); @@ -3873,8 +3873,8 @@ CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, if (NumPaddingBytes.isPositive()) { llvm::APInt pad(32, NumPaddingBytes.getQuantity()); - FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy, - pad, ArrayType::Normal, 0); + FType = CGM.getContext().getConstantArrayType( + CGM.getContext().CharTy, pad, nullptr, ArrayType::Normal, 0); EltTys.push_back(CreateMemberType(Unit, FType, "", &FieldOffset)); } } diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 1dd7ec5223..1fa7267808 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -143,7 +143,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, NumElements); QualType ElementType = Context.getObjCIdType().withConst(); QualType ElementArrayType - = Context.getConstantArrayType(ElementType, APNumElements, + = Context.getConstantArrayType(ElementType, APNumElements, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); // Allocate the temporary array(s). @@ -1661,7 +1661,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ QualType ItemsTy = getContext().getConstantArrayType(getContext().getObjCIdType(), - llvm::APInt(32, NumItems), + llvm::APInt(32, NumItems), nullptr, ArrayType::Normal, 0); Address ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr"); diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index bd74367b2e..e9cf692888 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3376,9 +3376,9 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, // , did_it); if (DidIt.isValid()) { llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size()); - QualType CopyprivateArrayTy = - C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal, - /*IndexTypeQuals=*/0); + QualType CopyprivateArrayTy = C.getConstantArrayType( + C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal, + /*IndexTypeQuals=*/0); // Create a list of all private variables for copyprivate. Address CopyprivateList = CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list"); @@ -5362,7 +5362,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, // Define type kmp_depend_info[]; QualType KmpDependInfoArrayTy = C.getConstantArrayType( KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies), - ArrayType::Normal, /*IndexTypeQuals=*/0); + nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); // kmp_depend_info[] deps; DependenciesArray = CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr"); @@ -5883,7 +5883,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, } llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size); QualType ReductionArrayTy = - C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal, + C.getConstantArrayType(C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); Address ReductionList = CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list"); @@ -6355,7 +6355,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit( unsigned Size = Data.ReductionVars.size(); llvm::APInt ArraySize(/*numBits=*/64, Size); QualType ArrayRDType = C.getConstantArrayType( - RDType, ArraySize, ArrayType::Normal, /*IndexTypeQuals=*/0); + RDType, ArraySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); // kmp_task_red_input_t .rd_input.[Size]; Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input."); ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionCopies, @@ -8711,9 +8711,9 @@ emitOffloadingArrays(CodeGenFunction &CGF, } llvm::APInt PointerNumAP(32, Info.NumberOfPtrs, /*isSigned=*/true); - QualType PointerArrayType = - Ctx.getConstantArrayType(Ctx.VoidPtrTy, PointerNumAP, ArrayType::Normal, - /*IndexTypeQuals=*/0); + QualType PointerArrayType = Ctx.getConstantArrayType( + Ctx.VoidPtrTy, PointerNumAP, nullptr, ArrayType::Normal, + /*IndexTypeQuals=*/0); Info.BasePointersArray = CGF.CreateMemTemp(PointerArrayType, ".offload_baseptrs").getPointer(); @@ -8726,9 +8726,9 @@ emitOffloadingArrays(CodeGenFunction &CGF, QualType Int64Ty = Ctx.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); if (hasRuntimeEvaluationCaptureSize) { - QualType SizeArrayType = - Ctx.getConstantArrayType(Int64Ty, PointerNumAP, ArrayType::Normal, - /*IndexTypeQuals=*/0); + QualType SizeArrayType = Ctx.getConstantArrayType( + Int64Ty, PointerNumAP, nullptr, ArrayType::Normal, + /*IndexTypeQuals=*/0); Info.SizesArray = CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer(); } else { @@ -10967,7 +10967,7 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF, } llvm::APInt Size(/*numBits=*/32, NumIterations.size()); QualType ArrayTy = - C.getConstantArrayType(KmpDimTy, Size, ArrayType::Normal, 0); + C.getConstantArrayType(KmpDimTy, Size, nullptr, ArrayType::Normal, 0); Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims"); CGF.EmitNullInitialization(DimsAddr, ArrayTy); @@ -11018,7 +11018,7 @@ void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF, CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); llvm::APInt Size(/*numBits=*/32, C->getNumLoops()); QualType ArrayTy = CGM.getContext().getConstantArrayType( - Int64Ty, Size, ArrayType::Normal, 0); + Int64Ty, Size, nullptr, ArrayType::Normal, 0); Address CntAddr = CGF.CreateMemTemp(ArrayTy, ".cnt.addr"); for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) { const Expr *CounterVal = C->getLoopData(I); diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index 746852485b..9e70a5a9bc 100644 --- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -280,7 +280,8 @@ static RecordDecl *buildRecordForGlobalizedVars( } } else { llvm::APInt ArraySize(32, BufSize); - Type = C.getConstantArrayType(Type, ArraySize, ArrayType::Normal, 0); + Type = C.getConstantArrayType(Type, ArraySize, nullptr, ArrayType::Normal, + 0); Field = FieldDecl::Create( C, GlobalizedRD, Loc, Loc, VD->getIdentifier(), Type, C.getTrivialTypeSourceInfo(Type, SourceLocation()), @@ -4269,7 +4270,7 @@ void CGOpenMPRuntimeNVPTX::emitReduction( } llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size); QualType ReductionArrayTy = - C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal, + C.getConstantArrayType(C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); Address ReductionList = CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list"); @@ -5056,7 +5057,7 @@ void CGOpenMPRuntimeNVPTX::clear() { Size = llvm::alignTo(Size, RecAlignment); llvm::APInt ArySize(/*numBits=*/64, Size); QualType SubTy = C.getConstantArrayType( - C.CharTy, ArySize, ArrayType::Normal, /*IndexTypeQuals=*/0); + C.CharTy, ArySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); const bool UseSharedMemory = Size <= SharedMemorySize; auto *Field = FieldDecl::Create(C, UseSharedMemory ? SharedStaticRD : StaticRD, @@ -5083,7 +5084,7 @@ void CGOpenMPRuntimeNVPTX::clear() { if (!SharedStaticRD->field_empty()) { llvm::APInt ArySize(/*numBits=*/64, SharedMemorySize); QualType SubTy = C.getConstantArrayType( - C.CharTy, ArySize, ArrayType::Normal, /*IndexTypeQuals=*/0); + C.CharTy, ArySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); auto *Field = FieldDecl::Create( C, SharedStaticRD, SourceLocation(), SourceLocation(), nullptr, SubTy, C.getTrivialTypeSourceInfo(SubTy, SourceLocation()), @@ -5116,11 +5117,12 @@ void CGOpenMPRuntimeNVPTX::clear() { std::pair SMsBlockPerSM = getSMsBlocksPerSM(CGM); llvm::APInt Size1(32, SMsBlockPerSM.second); QualType Arr1Ty = - C.getConstantArrayType(StaticTy, Size1, ArrayType::Normal, + C.getConstantArrayType(StaticTy, Size1, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); llvm::APInt Size2(32, SMsBlockPerSM.first); - QualType Arr2Ty = C.getConstantArrayType(Arr1Ty, Size2, ArrayType::Normal, - /*IndexTypeQuals=*/0); + QualType Arr2Ty = + C.getConstantArrayType(Arr1Ty, Size2, nullptr, ArrayType::Normal, + /*IndexTypeQuals=*/0); llvm::Type *LLVMArr2Ty = CGM.getTypes().ConvertTypeForMem(Arr2Ty); // FIXME: nvlink does not handle weak linkage correctly (object with the // different size are reported as erroneous). diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index bb6323e118..1ab6a8d963 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -3158,7 +3158,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( getContext(), getContext().getTranslationUnitDecl(), /*NumParams=*/0); llvm::APInt ArrSize(/*numBits=*/32, InputInfo.NumberOfTargetItems); QualType BaseAndPointersType = getContext().getConstantArrayType( - getContext().VoidPtrTy, ArrSize, ArrayType::Normal, + getContext().VoidPtrTy, ArrSize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); BPVD = createImplicitFirstprivateForType( getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc()); @@ -3166,7 +3166,7 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective( getContext(), Data, BaseAndPointersType, CD, S.getBeginLoc()); QualType SizesType = getContext().getConstantArrayType( getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1), - ArrSize, ArrayType::Normal, + ArrSize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD, S.getBeginLoc()); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index f8b4ffa024..140f8c38cf 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -4771,7 +4771,7 @@ QualType CodeGenModule::getObjCFastEnumerationStateType() { Context.getPointerType(Context.getObjCIdType()), Context.getPointerType(Context.UnsignedLongTy), Context.getConstantArrayType(Context.UnsignedLongTy, - llvm::APInt(32, 5), ArrayType::Normal, 0) + llvm::APInt(32, 5), nullptr, ArrayType::Normal, 0) }; for (size_t i = 0; i < 4; ++i) { diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp index a11fed56fc..0c2ab7a453 100644 --- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -597,8 +597,8 @@ namespace { StringLiteral *getStringLiteral(StringRef Str) { QualType StrType = Context->getConstantArrayType( - Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal, - 0); + Context->CharTy, llvm::APInt(32, Str.size() + 1), nullptr, + ArrayType::Normal, 0); return StringLiteral::Create(*Context, Str, StringLiteral::Ascii, /*Pascal=*/false, StrType, SourceLocation()); } diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp index 0fd0c7f503..dd57976df7 100644 --- a/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -497,8 +497,8 @@ namespace { StringLiteral *getStringLiteral(StringRef Str) { QualType StrType = Context->getConstantArrayType( - Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal, - 0); + Context->CharTy, llvm::APInt(32, Str.size() + 1), nullptr, + ArrayType::Normal, 0); return StringLiteral::Create(*Context, Str, StringLiteral::Ascii, /*Pascal=*/false, StrType, SourceLocation()); } diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index c2070995f3..d1b8e958e6 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -1111,8 +1111,8 @@ void Sema::ActOnEndOfTranslationUnit() { // Set the length of the array to 1 (C99 6.9.2p5). Diag(VD->getLocation(), diag::warn_tentative_incomplete_array); llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true); - QualType T = Context.getConstantArrayType(ArrayT->getElementType(), - One, ArrayType::Normal, 0); + QualType T = Context.getConstantArrayType(ArrayT->getElementType(), One, + nullptr, ArrayType::Normal, 0); VD->setType(T); } else if (RequireCompleteType(VD->getLocation(), VD->getType(), diag::err_tentative_def_incomplete_type)) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9a0fb20353..7a169ba51a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5758,8 +5758,8 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, return QualType(); } - return Context.getConstantArrayType(VLATy->getElementType(), - Res, ArrayType::Normal, 0); + return Context.getConstantArrayType( + VLATy->getElementType(), Res, VLATy->getSizeExpr(), ArrayType::Normal, 0); } static void diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index d75c8240a1..667441cbaa 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3207,13 +3207,15 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, SmallString<32> RawChars; ConvertUTF8ToWideString(Context.getTypeSizeInChars(ResTy).getQuantity(), Str, RawChars); - ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, + ResTy = Context.getConstantArrayType(ResTy, LengthI, nullptr, + ArrayType::Normal, /*IndexTypeQuals*/ 0); SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide, /*Pascal*/ false, ResTy, Loc); } else { ResTy = Context.adjustStringLiteralBaseType(Context.CharTy.withConst()); - ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, + ResTy = Context.getConstantArrayType(ResTy, LengthI, nullptr, + ArrayType::Normal, /*IndexTypeQuals*/ 0); SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii, /*Pascal*/ false, ResTy, Loc); @@ -3453,7 +3455,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { unsigned Length = Literal.getUDSuffixOffset(); QualType StrTy = Context.getConstantArrayType( Context.adjustStringLiteralBaseType(Context.CharTy.withConst()), - llvm::APInt(32, Length + 1), ArrayType::Normal, 0); + llvm::APInt(32, Length + 1), nullptr, ArrayType::Normal, 0); Expr *Lit = StringLiteral::Create( Context, StringRef(TokSpelling.data(), Length), StringLiteral::Ascii, /*Pascal*/false, StrTy, &TokLoc, 1); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index a25e86b95c..476afce01e 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2111,9 +2111,10 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, QualType InitType; if (KnownArraySize) InitType = Context.getConstantArrayType( - AllocType, llvm::APInt(Context.getTypeSize(Context.getSizeType()), - *KnownArraySize), - ArrayType::Normal, 0); + AllocType, + llvm::APInt(Context.getTypeSize(Context.getSizeType()), + *KnownArraySize), + *ArraySize, ArrayType::Normal, 0); else if (ArraySize) InitType = Context.getIncompleteArrayType(AllocType, ArrayType::Normal, 0); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index fb91f0b769..e18621e42a 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -67,7 +67,7 @@ ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType()); assert(CAT && "String literal not of constant array type!"); QualType StrTy = Context.getConstantArrayType( - CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), + CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr, CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers()); S = StringLiteral::Create(Context, StrBuf, StringLiteral::Ascii, /*Pascal=*/false, StrTy, &StrLocs[0], diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 00b7e9b1c0..6255e1bf0c 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -198,7 +198,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT, llvm::APInt ConstVal(32, StrLength); // Return a new array type (C99 6.7.8p22). DeclT = S.Context.getConstantArrayType(IAT->getElementType(), - ConstVal, + ConstVal, nullptr, ArrayType::Normal, 0); updateStringLiteralType(Str, DeclT); return; @@ -1935,8 +1935,8 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, SemaRef.Diag(IList->getBeginLoc(), diag::ext_typecheck_zero_array_size); } - DeclType = SemaRef.Context.getConstantArrayType(elementType, maxElements, - ArrayType::Normal, 0); + DeclType = SemaRef.Context.getConstantArrayType( + elementType, maxElements, nullptr, ArrayType::Normal, 0); } if (!hadError) { // If there are any members of the array that get value-initialized, check @@ -3827,9 +3827,10 @@ static bool TryInitializerListConstruction(Sema &S, // Try initializing a temporary array from the init list. QualType ArrayType = S.Context.getConstantArrayType( - E.withConst(), llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()), - List->getNumInits()), - clang::ArrayType::Normal, 0); + E.withConst(), + llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()), + List->getNumInits()), + nullptr, clang::ArrayType::Normal, 0); InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary(ArrayType); InitializationKind Kind = InitializationKind::CreateDirectList( @@ -8407,6 +8408,7 @@ ExprResult InitializationSequence::Perform(Sema &S, *ResultType = S.Context.getConstantArrayType( IncompleteDest->getElementType(), ConstantSource->getSize(), + ConstantSource->getSizeExpr(), ArrayType::Normal, 0); } } @@ -8649,7 +8651,7 @@ static void diagnoseListInit(Sema &S, const InitializedEntity &Entity, E.withConst(), llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()), InitList->getNumInits()), - clang::ArrayType::Normal, 0); + nullptr, clang::ArrayType::Normal, 0); InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary(ArrayType); return diagnoseListInit(S, HiddenArray, InitList); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 2b659f7f11..7ec5ba335f 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -13015,8 +13015,9 @@ static bool actOnOMPReductionKindClause( // If we don't have a single element, we must emit a constant array type. if (ConstantLengthOASE && !SingleElement) { for (llvm::APSInt &Size : ArraySizes) - PrivateTy = Context.getConstantArrayType( - PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); + PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, + ArrayType::Normal, + /*IndexTypeQuals=*/0); } } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 3029e148dc..87a672c537 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -2290,7 +2290,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, } } - T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); + T = Context.getConstantArrayType(T, ConstVal, ArraySize, ASM, Quals); } // OpenCL v1.2 s6.9.d: variable length arrays are not supported. diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 84e38c6d78..5ccd8cc889 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -795,6 +795,7 @@ public: QualType RebuildConstantArrayType(QualType ElementType, ArrayType::ArraySizeModifier SizeMod, const llvm::APInt &Size, + Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange); @@ -4726,12 +4727,25 @@ TreeTransform::TransformConstantArrayType(TypeLocBuilder &TLB, if (ElementType.isNull()) return QualType(); + // Prefer the expression from the TypeLoc; the other may have been uniqued. + Expr *OldSize = TL.getSizeExpr(); + if (!OldSize) + OldSize = const_cast(T->getSizeExpr()); + Expr *NewSize = nullptr; + if (OldSize) { + EnterExpressionEvaluationContext Unevaluated( + SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); + NewSize = getDerived().TransformExpr(OldSize).template getAs(); + NewSize = SemaRef.ActOnConstantExpression(NewSize).get(); + } + QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType()) { + ElementType != T->getElementType() || + (T->getSizeExpr() && NewSize != OldSize)) { Result = getDerived().RebuildConstantArrayType(ElementType, T->getSizeModifier(), - T->getSize(), + T->getSize(), NewSize, T->getIndexTypeCVRQualifiers(), TL.getBracketsRange()); if (Result.isNull()) @@ -4745,15 +4759,7 @@ TreeTransform::TransformConstantArrayType(TypeLocBuilder &TLB, ArrayTypeLoc NewTL = TLB.push(Result); NewTL.setLBracketLoc(TL.getLBracketLoc()); NewTL.setRBracketLoc(TL.getRBracketLoc()); - - Expr *Size = TL.getSizeExpr(); - if (Size) { - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - Size = getDerived().TransformExpr(Size).template getAs(); - Size = SemaRef.ActOnConstantExpression(Size).get(); - } - NewTL.setSizeExpr(Size); + NewTL.setSizeExpr(NewSize); return Result; } @@ -12802,9 +12808,10 @@ QualType TreeTransform::RebuildConstantArrayType(QualType ElementType, ArrayType::ArraySizeModifier SizeMod, const llvm::APInt &Size, + Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) { - return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, nullptr, + return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr, IndexTypeQuals, BracketsRange); } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index fcb437e0cb..55bec61693 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -6379,7 +6379,8 @@ QualType ASTReader::readTypeRecord(unsigned Index) { unsigned IndexTypeQuals = Record[2]; unsigned Idx = 3; llvm::APInt Size = ReadAPInt(Record, Idx); - return Context.getConstantArrayType(ElementType, Size, + Expr *SizeExpr = ReadExpr(*Loc.F); + return Context.getConstantArrayType(ElementType, Size, SizeExpr, ASM, IndexTypeQuals); } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index e1f3d50456..2d0a643877 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -238,6 +238,7 @@ void ASTTypeWriter::VisitArrayType(const ArrayType *T) { void ASTTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) { VisitArrayType(T); Record.AddAPInt(T->getSize()); + Record.AddStmt(const_cast(T->getSizeExpr())); Code = TYPE_CONSTANT_ARRAY; } diff --git a/test/CodeGenCXX/microsoft-uuidof-mangling.cpp b/test/CodeGenCXX/microsoft-uuidof-mangling.cpp index 9019aa8c92..10b19ddf56 100644 --- a/test/CodeGenCXX/microsoft-uuidof-mangling.cpp +++ b/test/CodeGenCXX/microsoft-uuidof-mangling.cpp @@ -24,7 +24,7 @@ struct __declspec(uuid("EAFA1952-66F8-438B-8FBA-AF1BBAE42191")) TestStruct template void test_uuidofType(void *arg[sizeof(__uuidof(T))] = 0) {} -template void test_uuidofExpr(void *arg[sizeof(__uuidof(T::member))] = 0) {} +template void test_uuidofExpr(void *arg[sizeof(__uuidof(typename T::member))] = 0) {} struct HasMember { typedef TestStruct member; }; diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp index 3249d0dc19..06eb5e0d78 100644 --- a/test/SemaTemplate/temp_arg_nontype.cpp +++ b/test/SemaTemplate/temp_arg_nontype.cpp @@ -488,9 +488,8 @@ namespace instantiation_dependent { template int &f(...); int &rf = f(0); - // FIXME: This fails because we mishandle instantiation-dependent array bounds :( int arr[sizeof(sizeof(int))]; template void g(int); template int &g(...); - int &rg = g(0); // expected-error {{cannot bind}} + int &rg = g(0); }