|
@@ -829,7 +829,8 @@ static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI,
|
|
ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
|
|
ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
|
|
IdentifierTable &idents, SelectorTable &sels,
|
|
IdentifierTable &idents, SelectorTable &sels,
|
|
Builtin::Context &builtins)
|
|
Builtin::Context &builtins)
|
|
- : FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()),
|
|
|
|
|
|
+ : ConstantArrayTypes(this_()), FunctionProtoTypes(this_()),
|
|
|
|
+ TemplateSpecializationTypes(this_()),
|
|
DependentTemplateSpecializationTypes(this_()),
|
|
DependentTemplateSpecializationTypes(this_()),
|
|
SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts),
|
|
SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts),
|
|
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
|
|
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.
|
|
/// array of the specified element type.
|
|
QualType ASTContext::getConstantArrayType(QualType EltTy,
|
|
QualType ASTContext::getConstantArrayType(QualType EltTy,
|
|
const llvm::APInt &ArySizeIn,
|
|
const llvm::APInt &ArySizeIn,
|
|
|
|
+ const Expr *SizeExpr,
|
|
ArrayType::ArraySizeModifier ASM,
|
|
ArrayType::ArraySizeModifier ASM,
|
|
unsigned IndexTypeQuals) const {
|
|
unsigned IndexTypeQuals) const {
|
|
assert((EltTy->isDependentType() ||
|
|
assert((EltTy->isDependentType() ||
|
|
EltTy->isIncompleteType() || EltTy->isConstantSizeType()) &&
|
|
EltTy->isIncompleteType() || EltTy->isConstantSizeType()) &&
|
|
"Constant array of VLAs is illegal!");
|
|
"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
|
|
// Convert the array size into a canonical width matching the pointer size for
|
|
// the target.
|
|
// the target.
|
|
llvm::APInt ArySize(ArySizeIn);
|
|
llvm::APInt ArySize(ArySizeIn);
|
|
ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth());
|
|
ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth());
|
|
|
|
|
|
llvm::FoldingSetNodeID ID;
|
|
llvm::FoldingSetNodeID ID;
|
|
- ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals);
|
|
|
|
|
|
+ ConstantArrayType::Profile(ID, *this, EltTy, ArySize, SizeExpr, ASM,
|
|
|
|
+ IndexTypeQuals);
|
|
|
|
|
|
void *InsertPos = nullptr;
|
|
void *InsertPos = nullptr;
|
|
if (ConstantArrayType *ATP =
|
|
if (ConstantArrayType *ATP =
|
|
ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
|
|
ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
|
|
return QualType(ATP, 0);
|
|
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;
|
|
QualType Canon;
|
|
- if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {
|
|
|
|
|
|
+ if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers() || SizeExpr) {
|
|
SplitQualType canonSplit = getCanonicalType(EltTy).split();
|
|
SplitQualType canonSplit = getCanonicalType(EltTy).split();
|
|
- Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize,
|
|
|
|
|
|
+ Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize, nullptr,
|
|
ASM, IndexTypeQuals);
|
|
ASM, IndexTypeQuals);
|
|
Canon = getQualifiedType(Canon, canonSplit.Quals);
|
|
Canon = getQualifiedType(Canon, canonSplit.Quals);
|
|
|
|
|
|
@@ -3199,8 +3207,11 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
|
|
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
|
|
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);
|
|
ConstantArrayTypes.InsertNode(New, InsertPos);
|
|
Types.push_back(New);
|
|
Types.push_back(New);
|
|
return QualType(New, 0);
|
|
return QualType(New, 0);
|
|
@@ -3297,6 +3308,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
|
|
result = getConstantArrayType(
|
|
result = getConstantArrayType(
|
|
getVariableArrayDecayedType(cat->getElementType()),
|
|
getVariableArrayDecayedType(cat->getElementType()),
|
|
cat->getSize(),
|
|
cat->getSize(),
|
|
|
|
+ cat->getSizeExpr(),
|
|
cat->getSizeModifier(),
|
|
cat->getSizeModifier(),
|
|
cat->getIndexTypeCVRQualifiers());
|
|
cat->getIndexTypeCVRQualifiers());
|
|
break;
|
|
break;
|
|
@@ -5192,7 +5204,7 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type,
|
|
|
|
|
|
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
|
|
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
|
|
return getConstantArrayType(unqualElementType, CAT->getSize(),
|
|
return getConstantArrayType(unqualElementType, CAT->getSize(),
|
|
- CAT->getSizeModifier(), 0);
|
|
|
|
|
|
+ CAT->getSizeExpr(), CAT->getSizeModifier(), 0);
|
|
}
|
|
}
|
|
|
|
|
|
if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) {
|
|
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))
|
|
if (const auto *CAT = dyn_cast<ConstantArrayType>(ATy))
|
|
return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
|
|
return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
|
|
|
|
+ CAT->getSizeExpr(),
|
|
CAT->getSizeModifier(),
|
|
CAT->getSizeModifier(),
|
|
CAT->getIndexTypeCVRQualifiers()));
|
|
CAT->getIndexTypeCVRQualifiers()));
|
|
if (const auto *IAT = dyn_cast<IncompleteArrayType>(ATy))
|
|
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);
|
|
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
|
|
QualType VaListTagArrayType
|
|
QualType VaListTagArrayType
|
|
= Context->getConstantArrayType(VaListTagTypedefType,
|
|
= Context->getConstantArrayType(VaListTagTypedefType,
|
|
- Size, ArrayType::Normal, 0);
|
|
|
|
|
|
+ Size, nullptr, ArrayType::Normal, 0);
|
|
return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
|
|
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];
|
|
// typedef struct __va_list_tag __builtin_va_list[1];
|
|
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 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");
|
|
return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
|
|
}
|
|
}
|
|
|
|
|
|
static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
|
|
static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
|
|
// typedef int __builtin_va_list[4];
|
|
// typedef int __builtin_va_list[4];
|
|
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 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");
|
|
return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list");
|
|
}
|
|
}
|
|
|
|
|
|
@@ -7627,8 +7640,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
|
|
|
|
|
|
// typedef __va_list_tag __builtin_va_list[1];
|
|
// typedef __va_list_tag __builtin_va_list[1];
|
|
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 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");
|
|
return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
|
|
}
|
|
}
|
|
@@ -9072,10 +9085,14 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
|
|
return LHS;
|
|
return LHS;
|
|
if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
|
|
if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
|
|
return RHS;
|
|
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))
|
|
if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
|
|
return LHS;
|
|
return LHS;
|
|
if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
|
|
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
|
|
// Get an array type for the string, according to C99 6.4.5. This includes
|
|
// the null terminator character.
|
|
// 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);
|
|
ArrayType::Normal, /*IndexTypeQuals*/ 0);
|
|
}
|
|
}
|
|
|
|
|