forked from OSchip/llvm-project
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. llvm-svn: 373685
This commit is contained in:
parent
053391fa86
commit
772e266fbf
|
@ -185,7 +185,8 @@ private:
|
|||
mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
|
||||
mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
|
||||
mutable llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
|
||||
mutable llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
|
||||
mutable llvm::ContextualFoldingSet<ConstantArrayType, ASTContext &>
|
||||
ConstantArrayTypes;
|
||||
mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
|
||||
mutable std::vector<VariableArrayType*> VariableArrayTypes;
|
||||
mutable llvm::FoldingSet<DependentSizedArrayType> 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;
|
||||
|
||||
|
|
|
@ -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<Expr*>(T->getSizeExpr())));
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_TYPE(IncompleteArrayType,
|
||||
{ TRY_TO(TraverseType(T->getElementType())); })
|
||||
|
|
|
@ -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<ConstantArrayType, const Expr *> {
|
||||
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) {}
|
||||
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<const Expr*>() = sz;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
||||
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 Expr*>) const {
|
||||
return ConstantArrayTypeBits.HasStoredSizeExpr;
|
||||
}
|
||||
|
||||
public:
|
||||
const llvm::APInt &getSize() const { return Size; }
|
||||
const Expr *getSizeExpr() const {
|
||||
return ConstantArrayTypeBits.HasStoredSizeExpr
|
||||
? *getTrailingObjects<const Expr *>()
|
||||
: 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:
|
||||
|
|
|
@ -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<const Expr *>(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<ConstantArrayType>(AT)) {
|
||||
return getConstantArrayType(unqualElementType, CAT->getSize(),
|
||||
CAT->getSizeModifier(), 0);
|
||||
CAT->getSizeExpr(), CAT->getSizeModifier(), 0);
|
||||
}
|
||||
|
||||
if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) {
|
||||
|
@ -5565,6 +5577,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
|
|||
|
||||
if (const auto *CAT = dyn_cast<ConstantArrayType>(ATy))
|
||||
return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
|
||||
CAT->getSizeExpr(),
|
||||
CAT->getSizeModifier(),
|
||||
CAT->getIndexTypeCVRQualifiers()));
|
||||
if (const auto *IAT = dyn_cast<IncompleteArrayType>(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,9 +9085,13 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
|
|||
return LHS;
|
||||
if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
|
||||
return RHS;
|
||||
if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(),
|
||||
if (LCAT)
|
||||
return getConstantArrayType(ResultType, LCAT->getSize(),
|
||||
LCAT->getSizeExpr(),
|
||||
ArrayType::ArraySizeModifier(), 0);
|
||||
if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(),
|
||||
if (RCAT)
|
||||
return getConstantArrayType(ResultType, RCAT->getSize(),
|
||||
RCAT->getSizeExpr(),
|
||||
ArrayType::ArraySizeModifier(), 0);
|
||||
if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
|
||||
return LHS;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1098,13 +1098,15 @@ 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(),
|
||||
return Importer.getToContext().getConstantArrayType(
|
||||
ToElementType, T->getSize(), ToSizeExpr, T->getSizeModifier(),
|
||||
T->getIndexTypeCVRQualifiers());
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ConstantArrayType>(AllocType));
|
||||
|
@ -8561,7 +8561,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
|
|||
ResizedArrayILE = cast<InitListExpr>(Init);
|
||||
}
|
||||
|
||||
AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
|
||||
AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
|
||||
ArrayType::Normal, 0);
|
||||
} else {
|
||||
assert(!AllocType->isArrayType() &&
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -102,7 +102,8 @@ namespace {
|
|||
llvm::APInt Size(
|
||||
/*numBits=*/32,
|
||||
C.toCharUnitsFromBits(AtomicSizeInBits).getQuantity());
|
||||
AtomicTy = C.getConstantArrayType(C.CharTy, Size, ArrayType::Normal,
|
||||
AtomicTy =
|
||||
C.getConstantArrayType(C.CharTy, Size, nullptr, ArrayType::Normal,
|
||||
/*IndexTypeQuals=*/0);
|
||||
}
|
||||
AtomicAlign = ValueAlign = lvalue.getAlignment();
|
||||
|
|
|
@ -3791,7 +3791,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
|||
-> std::tuple<llvm::Value *, llvm::Value *, llvm::Value *> {
|
||||
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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -3376,8 +3376,8 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
|
|||
// <copy_func>, did_it);
|
||||
if (DidIt.isValid()) {
|
||||
llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size());
|
||||
QualType CopyprivateArrayTy =
|
||||
C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
|
||||
QualType CopyprivateArrayTy = C.getConstantArrayType(
|
||||
C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal,
|
||||
/*IndexTypeQuals=*/0);
|
||||
// Create a list of all private variables for copyprivate.
|
||||
Address CopyprivateList =
|
||||
|
@ -5362,7 +5362,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
|
|||
// Define type kmp_depend_info[<Dependences.size()>];
|
||||
QualType KmpDependInfoArrayTy = C.getConstantArrayType(
|
||||
KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies),
|
||||
ArrayType::Normal, /*IndexTypeQuals=*/0);
|
||||
nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0);
|
||||
// kmp_depend_info[<Dependences.size()>] 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,8 +8711,8 @@ emitOffloadingArrays(CodeGenFunction &CGF,
|
|||
}
|
||||
|
||||
llvm::APInt PointerNumAP(32, Info.NumberOfPtrs, /*isSigned=*/true);
|
||||
QualType PointerArrayType =
|
||||
Ctx.getConstantArrayType(Ctx.VoidPtrTy, PointerNumAP, ArrayType::Normal,
|
||||
QualType PointerArrayType = Ctx.getConstantArrayType(
|
||||
Ctx.VoidPtrTy, PointerNumAP, nullptr, ArrayType::Normal,
|
||||
/*IndexTypeQuals=*/0);
|
||||
|
||||
Info.BasePointersArray =
|
||||
|
@ -8726,8 +8726,8 @@ emitOffloadingArrays(CodeGenFunction &CGF,
|
|||
QualType Int64Ty =
|
||||
Ctx.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
|
||||
if (hasRuntimeEvaluationCaptureSize) {
|
||||
QualType SizeArrayType =
|
||||
Ctx.getConstantArrayType(Int64Ty, PointerNumAP, ArrayType::Normal,
|
||||
QualType SizeArrayType = Ctx.getConstantArrayType(
|
||||
Int64Ty, PointerNumAP, nullptr, ArrayType::Normal,
|
||||
/*IndexTypeQuals=*/0);
|
||||
Info.SizesArray =
|
||||
CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer();
|
||||
|
@ -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);
|
||||
|
|
|
@ -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,10 +5117,11 @@ void CGOpenMPRuntimeNVPTX::clear() {
|
|||
std::pair<unsigned, unsigned> 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,
|
||||
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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -2111,9 +2111,10 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
|||
QualType InitType;
|
||||
if (KnownArraySize)
|
||||
InitType = Context.getConstantArrayType(
|
||||
AllocType, llvm::APInt(Context.getTypeSize(Context.getSizeType()),
|
||||
AllocType,
|
||||
llvm::APInt(Context.getTypeSize(Context.getSizeType()),
|
||||
*KnownArraySize),
|
||||
ArrayType::Normal, 0);
|
||||
*ArraySize, ArrayType::Normal, 0);
|
||||
else if (ArraySize)
|
||||
InitType =
|
||||
Context.getIncompleteArrayType(AllocType, ArrayType::Normal, 0);
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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()),
|
||||
E.withConst(),
|
||||
llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
|
||||
List->getNumInits()),
|
||||
clang::ArrayType::Normal, 0);
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<Derived>::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<Expr*>(T->getSizeExpr());
|
||||
Expr *NewSize = nullptr;
|
||||
if (OldSize) {
|
||||
EnterExpressionEvaluationContext Unevaluated(
|
||||
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
|
||||
NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
|
||||
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<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
|
|||
ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(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<Expr>();
|
||||
Size = SemaRef.ActOnConstantExpression(Size).get();
|
||||
}
|
||||
NewTL.setSizeExpr(Size);
|
||||
NewTL.setSizeExpr(NewSize);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
@ -12802,9 +12808,10 @@ QualType
|
|||
TreeTransform<Derived>::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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Expr*>(T->getSizeExpr()));
|
||||
Code = TYPE_CONSTANT_ARRAY;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ struct __declspec(uuid("EAFA1952-66F8-438B-8FBA-AF1BBAE42191")) TestStruct
|
|||
|
||||
template <class T> void test_uuidofType(void *arg[sizeof(__uuidof(T))] = 0) {}
|
||||
|
||||
template <class T> void test_uuidofExpr(void *arg[sizeof(__uuidof(T::member))] = 0) {}
|
||||
template <class T> void test_uuidofExpr(void *arg[sizeof(__uuidof(typename T::member))] = 0) {}
|
||||
|
||||
struct HasMember { typedef TestStruct member; };
|
||||
|
||||
|
|
|
@ -488,9 +488,8 @@ namespace instantiation_dependent {
|
|||
template<typename T, __typeof(sizeof(0))> int &f(...);
|
||||
int &rf = f<struct incomplete, 0>(0);
|
||||
|
||||
// FIXME: This fails because we mishandle instantiation-dependent array bounds :(
|
||||
int arr[sizeof(sizeof(int))];
|
||||
template<typename T, int (*)[sizeof(sizeof(T))]> void g(int);
|
||||
template<typename T, int (*)[sizeof(sizeof(int))]> int &g(...);
|
||||
int &rg = g<struct incomplete, &arr>(0); // expected-error {{cannot bind}}
|
||||
int &rg = g<struct incomplete, &arr>(0);
|
||||
}
|
||||
|
|
|
@ -2180,7 +2180,7 @@ CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type,
|
|||
} else {
|
||||
return CompilerType(this, ast->getConstantArrayType(
|
||||
ClangUtil::GetQualType(element_type),
|
||||
ap_element_count,
|
||||
ap_element_count, nullptr,
|
||||
clang::ArrayType::Normal, 0)
|
||||
.getAsOpaquePtr());
|
||||
}
|
||||
|
@ -4469,7 +4469,7 @@ CompilerType ClangASTContext::GetArrayType(lldb::opaque_compiler_type_t type,
|
|||
return CompilerType(
|
||||
this, ast_ctx
|
||||
->getConstantArrayType(
|
||||
qual_type, llvm::APInt(64, size),
|
||||
qual_type, llvm::APInt(64, size), nullptr,
|
||||
clang::ArrayType::ArraySizeModifier::Normal, 0)
|
||||
.getAsOpaquePtr());
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue