summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
committerpatrick <patrick@openbsd.org>2019-01-27 16:42:12 +0000
commitb773203fb58f3ef282fb69c832d8710cab5bc82d (patch)
treee75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/AST/ASTContext.cpp
parenttweak errno in previous (diff)
downloadwireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz
wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/AST/ASTContext.cpp')
-rw-r--r--gnu/llvm/tools/clang/lib/AST/ASTContext.cpp1657
1 files changed, 1063 insertions, 594 deletions
diff --git a/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp b/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp
index c73ae9efe17..648fa9f0fbc 100644
--- a/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp
+++ b/gnu/llvm/tools/clang/lib/AST/ASTContext.cpp
@@ -47,6 +47,7 @@
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
@@ -130,35 +131,34 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
return nullptr;
// User can not attach documentation to implicit instantiations.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (VD->isStaticDataMember() &&
VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
+ if (const auto *CRD = dyn_cast<CXXRecordDecl>(D)) {
if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const ClassTemplateSpecializationDecl *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
TemplateSpecializationKind TSK = CTSD->getSpecializationKind();
if (TSK == TSK_ImplicitInstantiation ||
TSK == TSK_Undeclared)
return nullptr;
}
- if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
+ if (const auto *ED = dyn_cast<EnumDecl>(D)) {
if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ if (const auto *TD = dyn_cast<TagDecl>(D)) {
// When tag declaration (but not definition!) is part of the
// decl-specifier-seq of some other declaration, it doesn't get comment
if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition())
@@ -201,7 +201,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// declared via a macro. Try using declaration's starting location as
// the "declaration location".
DeclLoc = D->getLocStart();
- } else if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ } else if (const auto *TD = dyn_cast<TagDecl>(D)) {
// If location of the tag decl is inside a macro, but the spelling of
// the tag name comes from a macro argument, it looks like a special
// macro like NS_ENUM is being used to define the tag decl. In that
@@ -226,8 +226,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// for is usually among the last two comments we parsed -- check them
// first.
RawComment CommentAtDeclLoc(
- SourceMgr, SourceRange(DeclLoc), false,
- LangOpts.CommentOpts.ParseAllComments);
+ SourceMgr, SourceRange(DeclLoc), LangOpts.CommentOpts, false);
BeforeThanCompare<RawComment> Compare(SourceMgr);
ArrayRef<RawComment *>::iterator MaybeBeforeDecl = RawComments.end() - 1;
bool Found = Compare(*MaybeBeforeDecl, &CommentAtDeclLoc);
@@ -253,7 +252,8 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// First check whether we have a trailing comment.
if (Comment != RawComments.end() &&
- (*Comment)->isDocumentation() && (*Comment)->isTrailingComment() &&
+ ((*Comment)->isDocumentation() || LangOpts.CommentOpts.ParseAllComments)
+ && (*Comment)->isTrailingComment() &&
(isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D) ||
isa<ObjCMethodDecl>(D) || isa<ObjCPropertyDecl>(D))) {
std::pair<FileID, unsigned> CommentBeginDecomp
@@ -275,7 +275,9 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
--Comment;
// Check that we actually have a non-member Doxygen comment.
- if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment())
+ if (!((*Comment)->isDocumentation() ||
+ LangOpts.CommentOpts.ParseAllComments) ||
+ (*Comment)->isTrailingComment())
return nullptr;
// Decompose the end of the comment.
@@ -310,7 +312,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
/// refer to the actual template.
/// If we have an implicit instantiation, adjust 'D' to refer to template.
static const Decl *adjustDeclToTemplate(const Decl *D) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// Is this function declaration part of a function template?
if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
return FTD;
@@ -330,7 +332,7 @@ static const Decl *adjustDeclToTemplate(const Decl *D) {
return D;
}
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
// Static data member is instantiated from a member definition of a class
// template?
if (VD->isStaticDataMember())
@@ -339,15 +341,14 @@ static const Decl *adjustDeclToTemplate(const Decl *D) {
return D;
}
- if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
+ if (const auto *CRD = dyn_cast<CXXRecordDecl>(D)) {
// Is this class declaration part of a class template?
if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
return CTD;
// Class is an implicit instantiation of a class template or partial
// specialization?
- if (const ClassTemplateSpecializationDecl *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
+ if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
return D;
llvm::PointerUnion<ClassTemplateDecl *,
@@ -366,7 +367,7 @@ static const Decl *adjustDeclToTemplate(const Decl *D) {
return D;
}
- if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
+ if (const auto *ED = dyn_cast<EnumDecl>(D)) {
// Enum is instantiated from a member definition of a class template?
if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
return MemberDecl;
@@ -428,7 +429,7 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
}
// If we found a comment, it should be a documentation comment.
- assert(!RC || RC->isDocumentation());
+ assert(!RC || RC->isDocumentation() || LangOpts.CommentOpts.ParseAllComments);
if (OriginalDecl)
*OriginalDecl = OriginalDeclForRC;
@@ -451,7 +452,7 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
SmallVectorImpl<const NamedDecl *> &Redeclared) {
const DeclContext *DC = ObjCMethod->getDeclContext();
- if (const ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(DC)) {
+ if (const auto *IMD = dyn_cast<ObjCImplDecl>(DC)) {
const ObjCInterfaceDecl *ID = IMD->getClassInterface();
if (!ID)
return;
@@ -467,7 +468,7 @@ static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
const Decl *D) const {
- comments::DeclInfo *ThisDeclInfo = new (*this) comments::DeclInfo;
+ auto *ThisDeclInfo = new (*this) comments::DeclInfo;
ThisDeclInfo->CommentDecl = D;
ThisDeclInfo->IsFilled = false;
ThisDeclInfo->fill();
@@ -491,11 +492,11 @@ comments::FullComment *ASTContext::getCommentForDecl(
if (D->isInvalidDecl())
return nullptr;
D = adjustDeclToTemplate(D);
-
+
const Decl *Canonical = D->getCanonicalDecl();
llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos =
ParsedComments.find(Canonical);
-
+
if (Pos != ParsedComments.end()) {
if (Canonical != D) {
comments::FullComment *FC = Pos->second;
@@ -504,14 +505,14 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
return Pos->second;
}
-
+
const Decl *OriginalDecl;
-
+
const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl);
if (!RC) {
if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
SmallVector<const NamedDecl*, 8> Overridden;
- const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D);
+ const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
if (OMD && OMD->isPropertyAccessor())
if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl())
if (comments::FullComment *FC = getCommentForDecl(PDecl, PP))
@@ -523,28 +524,28 @@ comments::FullComment *ASTContext::getCommentForDecl(
if (comments::FullComment *FC = getCommentForDecl(Overridden[i], PP))
return cloneFullComment(FC, D);
}
- else if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+ else if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
// Attach any tag type's documentation to its typedef if latter
// does not have one of its own.
QualType QT = TD->getUnderlyingType();
- if (const TagType *TT = QT->getAs<TagType>())
+ if (const auto *TT = QT->getAs<TagType>())
if (const Decl *TD = TT->getDecl())
if (comments::FullComment *FC = getCommentForDecl(TD, PP))
return cloneFullComment(FC, D);
}
- else if (const ObjCInterfaceDecl *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
+ else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
while (IC->getSuperClass()) {
IC = IC->getSuperClass();
if (comments::FullComment *FC = getCommentForDecl(IC, PP))
return cloneFullComment(FC, D);
}
}
- else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+ else if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
if (const ObjCInterfaceDecl *IC = CD->getClassInterface())
if (comments::FullComment *FC = getCommentForDecl(IC, PP))
return cloneFullComment(FC, D);
}
- else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+ else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
if (!(RD = RD->getDefinition()))
return nullptr;
// Check non-virtual bases.
@@ -557,7 +558,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) {
if (!(NonVirtualBase= NonVirtualBase->getDefinition()))
continue;
-
+
if (comments::FullComment *FC = getCommentForDecl((NonVirtualBase), PP))
return cloneFullComment(FC, D);
}
@@ -579,7 +580,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
return nullptr;
}
-
+
// If the RawComment was attached to other redeclaration of this Decl, we
// should parse the comment in context of that other Decl. This is important
// because comments can contain references to parameter names which can be
@@ -592,8 +593,8 @@ comments::FullComment *ASTContext::getCommentForDecl(
return FC;
}
-void
-ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
+void
+ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
TemplateTemplateParmDecl *Parm) {
ID.AddInteger(Parm->getDepth());
ID.AddInteger(Parm->getPosition());
@@ -601,16 +602,16 @@ ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
TemplateParameterList *Params = Parm->getTemplateParameters();
ID.AddInteger(Params->size());
- for (TemplateParameterList::const_iterator P = Params->begin(),
+ for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
ID.AddInteger(0);
ID.AddBoolean(TTP->isParameterPack());
continue;
}
-
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+
+ if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
ID.AddInteger(1);
ID.AddBoolean(NTTP->isParameterPack());
ID.AddPointer(NTTP->getType().getCanonicalType().getAsOpaquePtr());
@@ -621,12 +622,12 @@ ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
QualType T = NTTP->getExpansionType(I);
ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
}
- } else
+ } else
ID.AddBoolean(false);
continue;
}
-
- TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+
+ auto *TTP = cast<TemplateTemplateParmDecl>(*P);
ID.AddInteger(2);
Profile(ID, TTP);
}
@@ -643,24 +644,23 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
= CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
if (Canonical)
return Canonical->getParam();
-
+
// Build a canonical template parameter list.
TemplateParameterList *Params = TTP->getTemplateParameters();
SmallVector<NamedDecl *, 4> CanonParams;
CanonParams.reserve(Params->size());
- for (TemplateParameterList::const_iterator P = Params->begin(),
+ for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P))
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P))
CanonParams.push_back(
- TemplateTypeParmDecl::Create(*this, getTranslationUnitDecl(),
+ TemplateTypeParmDecl::Create(*this, getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(),
TTP->getDepth(),
TTP->getIndex(), nullptr, false,
TTP->isParameterPack()));
- else if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+ else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
QualType T = getCanonicalType(NTTP->getType());
TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);
NonTypeTemplateParmDecl *Param;
@@ -672,7 +672,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
ExpandedTInfos.push_back(
getTrivialTypeSourceInfo(ExpandedTypes.back()));
}
-
+
Param = NonTypeTemplateParmDecl::Create(*this, getTranslationUnitDecl(),
SourceLocation(),
SourceLocation(),
@@ -704,9 +704,9 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
Expr *const CanonRequiresClause = nullptr;
TemplateTemplateParmDecl *CanonTTP
- = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(),
+ = TemplateTemplateParmDecl::Create(*this, getTranslationUnitDecl(),
SourceLocation(), TTP->getDepth(),
- TTP->getPosition(),
+ TTP->getPosition(),
TTP->isParameterPack(),
nullptr,
TemplateParameterList::Create(*this, SourceLocation(),
@@ -788,10 +788,12 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts),
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
- LangOpts.XRayNeverInstrumentFiles, SM)),
+ LangOpts.XRayNeverInstrumentFiles,
+ LangOpts.XRayAttrListFiles, SM)),
PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
BuiltinInfo(builtins), DeclarationNames(*this), Comments(SM),
- CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), LastSDM(nullptr, 0) {
+ CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
+ CompCategories(this_()), LastSDM(nullptr, 0) {
TUDecl = TranslationUnitDecl::Create(*this);
}
@@ -812,16 +814,16 @@ ASTContext::~ASTContext() {
const ASTRecordLayout*>::iterator
I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; )
// Increment in loop to prevent using deallocated memory.
- if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))
R->Destroy(*this);
for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
// Increment in loop to prevent using deallocated memory.
- if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))
R->Destroy(*this);
}
-
+
for (llvm::DenseMap<const Decl*, AttrVec*>::iterator A = DeclAttrs.begin(),
AEnd = DeclAttrs.end();
A != AEnd; ++A)
@@ -966,7 +968,7 @@ void ASTContext::PerModuleInitializers::resolve(ASTContext &Ctx) {
void ASTContext::addModuleInitializer(Module *M, Decl *D) {
// One special case: if we add a module initializer that imports another
// module, and that module's only initializer is an ImportDecl, simplify.
- if (auto *ID = dyn_cast<ImportDecl>(D)) {
+ if (const auto *ID = dyn_cast<ImportDecl>(D)) {
auto It = ModuleInitializers.find(ID->getImportedModule());
// Maybe the ImportDecl does nothing at all. (Common case.)
@@ -997,9 +999,9 @@ void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs) {
IDs.begin(), IDs.end());
}
-ArrayRef<Decl*> ASTContext::getModuleInitializers(Module *M) {
+ArrayRef<Decl *> ASTContext::getModuleInitializers(Module *M) {
auto It = ModuleInitializers.find(M);
- if (It == ModuleInitializers.end())
+ if (It == ModuleInitializers.end())
return None;
auto *Inits = It->second;
@@ -1079,7 +1081,7 @@ TypedefDecl *ASTContext::getUInt128Decl() const {
}
void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
- BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K);
+ auto *Ty = new (*this, TypeAlignment) BuiltinType(K);
R = CanQualType::CreateUnsafe(QualType(Ty, 0));
Types.push_back(Ty);
}
@@ -1096,7 +1098,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
ABI.reset(createCXXABI(Target));
AddrSpaceMap = getAddressSpaceMap(Target, LangOpts);
AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts);
-
+
// C99 6.2.5p19.
InitBuiltinType(VoidTy, BuiltinType::Void);
@@ -1132,6 +1134,32 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// C11 extension ISO/IEC TS 18661-3
InitBuiltinType(Float16Ty, BuiltinType::Float16);
+ // ISO/IEC JTC1 SC22 WG14 N1169 Extension
+ InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum);
+ InitBuiltinType(AccumTy, BuiltinType::Accum);
+ InitBuiltinType(LongAccumTy, BuiltinType::LongAccum);
+ InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum);
+ InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum);
+ InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum);
+ InitBuiltinType(ShortFractTy, BuiltinType::ShortFract);
+ InitBuiltinType(FractTy, BuiltinType::Fract);
+ InitBuiltinType(LongFractTy, BuiltinType::LongFract);
+ InitBuiltinType(UnsignedShortFractTy, BuiltinType::UShortFract);
+ InitBuiltinType(UnsignedFractTy, BuiltinType::UFract);
+ InitBuiltinType(UnsignedLongFractTy, BuiltinType::ULongFract);
+ InitBuiltinType(SatShortAccumTy, BuiltinType::SatShortAccum);
+ InitBuiltinType(SatAccumTy, BuiltinType::SatAccum);
+ InitBuiltinType(SatLongAccumTy, BuiltinType::SatLongAccum);
+ InitBuiltinType(SatUnsignedShortAccumTy, BuiltinType::SatUShortAccum);
+ InitBuiltinType(SatUnsignedAccumTy, BuiltinType::SatUAccum);
+ InitBuiltinType(SatUnsignedLongAccumTy, BuiltinType::SatULongAccum);
+ InitBuiltinType(SatShortFractTy, BuiltinType::SatShortFract);
+ InitBuiltinType(SatFractTy, BuiltinType::SatFract);
+ InitBuiltinType(SatLongFractTy, BuiltinType::SatLongFract);
+ InitBuiltinType(SatUnsignedShortFractTy, BuiltinType::SatUShortFract);
+ InitBuiltinType(SatUnsignedFractTy, BuiltinType::SatUFract);
+ InitBuiltinType(SatUnsignedLongFractTy, BuiltinType::SatULongFract);
+
// GNU extension, 128-bit integers.
InitBuiltinType(Int128Ty, BuiltinType::Int128);
InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
@@ -1150,6 +1178,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
WIntTy = getFromTargetType(Target.getWIntType());
+ // C++20 (proposed)
+ InitBuiltinType(Char8Ty, BuiltinType::Char8);
+
if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
InitBuiltinType(Char16Ty, BuiltinType::Char16);
else // C99
@@ -1211,13 +1242,13 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
}
-
+
// Builtin type for __objc_yes and __objc_no
ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ?
SignedCharTy : BoolTy);
-
+
ObjCConstantStringType = QualType();
-
+
ObjCSuperType = QualType();
// void * type
@@ -1250,11 +1281,11 @@ AttrVec& ASTContext::getDeclAttrs(const Decl *D) {
void *Mem = Allocate(sizeof(AttrVec));
Result = new (Mem) AttrVec;
}
-
+
return *Result;
}
-/// \brief Erase the attributes corresponding to the given declaration.
+/// Erase the attributes corresponding to the given declaration.
void ASTContext::eraseDeclAttrs(const Decl *D) {
llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D);
if (Pos != DeclAttrs.end()) {
@@ -1276,7 +1307,7 @@ ASTContext::getTemplateOrSpecializationInfo(const VarDecl *Var) {
llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>::iterator Pos =
TemplateOrInstantiation.find(Var);
if (Pos == TemplateOrInstantiation.end())
- return TemplateOrSpecializationInfo();
+ return {};
return Pos->second;
}
@@ -1330,11 +1361,11 @@ void
ASTContext::setInstantiatedFromUsingDecl(NamedDecl *Inst, NamedDecl *Pattern) {
assert((isa<UsingDecl>(Pattern) ||
isa<UnresolvedUsingValueDecl>(Pattern) ||
- isa<UnresolvedUsingTypenameDecl>(Pattern)) &&
+ isa<UnresolvedUsingTypenameDecl>(Pattern)) &&
"pattern decl is not a using decl");
assert((isa<UsingDecl>(Inst) ||
isa<UnresolvedUsingValueDecl>(Inst) ||
- isa<UnresolvedUsingTypenameDecl>(Inst)) &&
+ isa<UnresolvedUsingTypenameDecl>(Inst)) &&
"instantiation did not produce a using decl");
assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists");
InstantiatedFromUsingDecl[Inst] = Pattern;
@@ -1401,7 +1432,7 @@ ASTContext::overridden_methods(const CXXMethodDecl *Method) const {
return overridden_method_range(Pos->second.begin(), Pos->second.end());
}
-void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,
+void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,
const CXXMethodDecl *Overridden) {
assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl());
OverriddenMethods[Method].push_back(Overridden);
@@ -1412,13 +1443,13 @@ void ASTContext::getOverriddenMethods(
SmallVectorImpl<const NamedDecl *> &Overridden) const {
assert(D);
- if (const CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
+ if (const auto *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
Overridden.append(overridden_methods_begin(CXXMethod),
overridden_methods_end(CXXMethod));
return;
}
- const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
+ const auto *Method = dyn_cast<ObjCMethodDecl>(D);
if (!Method)
return;
@@ -1435,7 +1466,7 @@ void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
LastLocalImport = Import;
return;
}
-
+
LastLocalImport->NextLocalImport = Import;
LastLocalImport = Import;
}
@@ -1447,7 +1478,7 @@ void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
/// scalar floating point type.
const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
- const BuiltinType *BT = T->getAs<BuiltinType>();
+ const auto *BT = T->getAs<BuiltinType>();
assert(BT && "Not a floating point type!");
switch (BT->getKind()) {
default: llvm_unreachable("Not a floating point type!");
@@ -1482,7 +1513,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
}
}
else if (isa<FieldDecl>(D))
- UseAlignAttrOnly =
+ UseAlignAttrOnly =
D->hasAttr<PackedAttr>() ||
cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>();
@@ -1490,9 +1521,9 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
// else about the declaration and its type.
if (UseAlignAttrOnly) {
// do nothing
- } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+ } else if (const auto *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
- if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
+ if (const auto *RT = T->getAs<ReferenceType>()) {
if (ForAlignof)
T = RT->getPointeeType();
else
@@ -1517,7 +1548,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (BaseT.getQualifiers().hasUnaligned())
Align = Target->getCharWidth();
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasGlobalStorage() && !ForAlignof)
Align = std::max(Align, getTargetInfo().getMinGlobalAlign());
}
@@ -1528,7 +1559,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
// a max-field-alignment constraint (#pragma pack). So calculate
// the actual alignment of the field within the struct, and then
// (as we're expected to) constrain that by the alignment of the type.
- if (const FieldDecl *Field = dyn_cast<FieldDecl>(VD)) {
+ if (const auto *Field = dyn_cast<FieldDecl>(VD)) {
const RecordDecl *Parent = Field->getParent();
// We can only produce a sensible answer if the record is valid.
if (!Parent->isInvalidDecl()) {
@@ -1567,7 +1598,7 @@ ASTContext::getTypeInfoDataSizeInChars(QualType T) const {
// of a base-class subobject. We decide whether that's possible
// during class layout, so here we can just trust the layout results.
if (getLangOpts().CPlusPlus) {
- if (const RecordType *RT = T->getAs<RecordType>()) {
+ if (const auto *RT = T->getAs<RecordType>()) {
const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl());
sizeAndAlign.first = layout.getDataSize();
}
@@ -1598,7 +1629,7 @@ static getConstantArrayInfoInChars(const ASTContext &Context,
std::pair<CharUnits, CharUnits>
ASTContext::getTypeInfoInChars(const Type *T) const {
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T))
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(T))
return getConstantArrayInfoInChars(*this, CAT);
TypeInfo Info = getTypeInfo(T);
return std::make_pair(toCharUnitsFromBits(Info.Width),
@@ -1620,7 +1651,7 @@ bool ASTContext::isAlignmentRequired(QualType T) const {
unsigned ASTContext::getTypeAlignIfKnown(QualType T) const {
// An alignment on a typedef overrides anything else.
- if (auto *TT = T->getAs<TypedefType>())
+ if (const auto *TT = T->getAs<TypedefType>())
if (unsigned Align = TT->getDecl()->getMaxAlignment())
return Align;
@@ -1631,12 +1662,12 @@ unsigned ASTContext::getTypeAlignIfKnown(QualType T) const {
// If we had an array type, its element type might be a typedef
// type with an alignment attribute.
- if (auto *TT = T->getAs<TypedefType>())
+ if (const auto *TT = T->getAs<TypedefType>())
if (unsigned Align = TT->getDecl()->getMaxAlignment())
return Align;
// Otherwise, see if the declaration of the type had an attribute.
- if (auto *TT = T->getAs<TagType>())
+ if (const auto *TT = T->getAs<TagType>())
return TT->getDecl()->getMaxAlignment();
return 0;
@@ -1690,7 +1721,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
case Type::ConstantArray: {
- const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
+ const auto *CAT = cast<ConstantArrayType>(T);
TypeInfo EltInfo = getTypeInfo(CAT->getElementType());
uint64_t Size = CAT->getSize().getZExtValue();
@@ -1705,7 +1736,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::ExtVector:
case Type::Vector: {
- const VectorType *VT = cast<VectorType>(T);
+ const auto *VT = cast<VectorType>(T);
TypeInfo EltInfo = getTypeInfo(VT->getElementType());
Width = EltInfo.Width * VT->getNumElements();
Align = Width;
@@ -1738,6 +1769,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case BuiltinType::Char_U:
case BuiltinType::UChar:
case BuiltinType::SChar:
+ case BuiltinType::Char8:
Width = Target->getCharWidth();
Align = Target->getCharAlign();
break;
@@ -1779,6 +1811,48 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = 128;
Align = 128; // int128_t is 128-bit aligned on all targets.
break;
+ case BuiltinType::ShortAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatUShortAccum:
+ Width = Target->getShortAccumWidth();
+ Align = Target->getShortAccumAlign();
+ break;
+ case BuiltinType::Accum:
+ case BuiltinType::UAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatUAccum:
+ Width = Target->getAccumWidth();
+ Align = Target->getAccumAlign();
+ break;
+ case BuiltinType::LongAccum:
+ case BuiltinType::ULongAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatULongAccum:
+ Width = Target->getLongAccumWidth();
+ Align = Target->getLongAccumAlign();
+ break;
+ case BuiltinType::ShortFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatUShortFract:
+ Width = Target->getShortFractWidth();
+ Align = Target->getShortFractAlign();
+ break;
+ case BuiltinType::Fract:
+ case BuiltinType::UFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatUFract:
+ Width = Target->getFractWidth();
+ Align = Target->getFractAlign();
+ break;
+ case BuiltinType::LongFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatULongFract:
+ Width = Target->getLongFractWidth();
+ Align = Target->getLongFractAlign();
+ break;
case BuiltinType::Float16:
case BuiltinType::Half:
Width = Target->getHalfWidth();
@@ -1807,7 +1881,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case BuiltinType::ObjCId:
case BuiltinType::ObjCClass:
case BuiltinType::ObjCSel:
- Width = Target->getPointerWidth(0);
+ Width = Target->getPointerWidth(0);
Align = Target->getPointerAlign(0);
break;
case BuiltinType::OCLSampler:
@@ -1848,7 +1922,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = Target->getPointerAlign(AS);
break;
case Type::MemberPointer: {
- const MemberPointerType *MPT = cast<MemberPointerType>(T);
+ const auto *MPT = cast<MemberPointerType>(T);
CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT);
Width = MPI.Width;
Align = MPI.Align;
@@ -1868,7 +1942,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Decayed:
return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
case Type::ObjCInterface: {
- const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
+ const auto *ObjCI = cast<ObjCInterfaceType>(T);
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
Width = toBits(Layout.getSize());
Align = toBits(Layout.getAlignment());
@@ -1876,7 +1950,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::Record:
case Type::Enum: {
- const TagType *TT = cast<TagType>(T);
+ const auto *TT = cast<TagType>(T);
if (TT->getDecl()->isInvalidDecl()) {
Width = 8;
@@ -1884,7 +1958,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
}
- if (const EnumType *ET = dyn_cast<EnumType>(TT)) {
+ if (const auto *ET = dyn_cast<EnumType>(TT)) {
const EnumDecl *ED = ET->getDecl();
TypeInfo Info =
getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType());
@@ -1895,7 +1969,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
return Info;
}
- const RecordType *RT = cast<RecordType>(TT);
+ const auto *RT = cast<RecordType>(TT);
const RecordDecl *RD = RT->getDecl();
const ASTRecordLayout &Layout = getASTRecordLayout(RD);
Width = toBits(Layout.getSize());
@@ -1910,7 +1984,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Auto:
case Type::DeducedTemplateSpecialization: {
- const DeducedType *A = cast<DeducedType>(T);
+ const auto *A = cast<DeducedType>(T);
assert(!A->getDeducedType().isNull() &&
"cannot request the size of an undeduced or dependent auto type");
return getTypeInfo(A->getDeducedType().getTypePtr());
@@ -1952,10 +2026,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Info.Width;
Align = Info.Align;
- // If the size of the type doesn't exceed the platform's max
- // atomic promotion width, make the size and alignment more
- // favorable to atomic operations:
- if (Width != 0 && Width <= Target->getMaxAtomicPromoteWidth()) {
+ if (!Width) {
+ // An otherwise zero-sized type should still generate an
+ // atomic operation.
+ Width = Target->getCharWidth();
+ assert(Align);
+ } else if (Width <= Target->getMaxAtomicPromoteWidth()) {
+ // If the size of the type doesn't exceed the platform's max
+ // atomic promotion width, make the size and alignment more
+ // favorable to atomic operations:
+
// Round the size up to a power of 2.
if (!llvm::isPowerOf2_64(Width))
Width = llvm::NextPowerOf2(Width);
@@ -1976,6 +2056,27 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
return TypeInfo(Width, Align, AlignIsRequired);
}
+unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {
+ UnadjustedAlignMap::iterator I = MemoizedUnadjustedAlign.find(T);
+ if (I != MemoizedUnadjustedAlign.end())
+ return I->second;
+
+ unsigned UnadjustedAlign;
+ if (const auto *RT = T->getAs<RecordType>()) {
+ const RecordDecl *RD = RT->getDecl();
+ const ASTRecordLayout &Layout = getASTRecordLayout(RD);
+ UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
+ } else if (const auto *ObjCI = T->getAs<ObjCInterfaceType>()) {
+ const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
+ UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
+ } else {
+ UnadjustedAlign = getTypeAlign(T);
+ }
+
+ MemoizedUnadjustedAlign[T] = UnadjustedAlign;
+ return UnadjustedAlign;
+}
+
unsigned ASTContext::getOpenMPDefaultSimdAlign(QualType T) const {
unsigned SimdAlign = getTargetInfo().getSimdDefaultAlign();
// Target ppc64 with QPX: simd default alignment for pointer to double is 32.
@@ -2006,7 +2107,7 @@ CharUnits ASTContext::getTypeSizeInChars(const Type *T) const {
return getTypeInfoInChars(T).first;
}
-/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
+/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
/// characters. This method does not work on incomplete types.
CharUnits ASTContext::getTypeAlignInChars(QualType T) const {
return toCharUnitsFromBits(getTypeAlign(T));
@@ -2015,6 +2116,16 @@ CharUnits ASTContext::getTypeAlignInChars(const Type *T) const {
return toCharUnitsFromBits(getTypeAlign(T));
}
+/// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a
+/// type, in characters, before alignment adustments. This method does
+/// not work on incomplete types.
+CharUnits ASTContext::getTypeUnadjustedAlignInChars(QualType T) const {
+ return toCharUnitsFromBits(getTypeUnadjustedAlign(T));
+}
+CharUnits ASTContext::getTypeUnadjustedAlignInChars(const Type *T) const {
+ return toCharUnitsFromBits(getTypeUnadjustedAlign(T));
+}
+
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance to overalign
@@ -2033,9 +2144,9 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
return ABIAlign;
// Double and long long should be naturally aligned if possible.
- if (const ComplexType *CT = T->getAs<ComplexType>())
+ if (const auto *CT = T->getAs<ComplexType>())
T = CT->getElementType().getTypePtr();
- if (const EnumType *ET = T->getAs<EnumType>())
+ if (const auto *ET = T->getAs<EnumType>())
T = ET->getDecl()->getIntegerType().getTypePtr();
if (T->isSpecificBuiltinType(BuiltinType::Double) ||
T->isSpecificBuiltinType(BuiltinType::LongLong) ||
@@ -2091,8 +2202,8 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
for (const auto *I : OI->ivars())
Ivars.push_back(I);
} else {
- ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
- for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
+ auto *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
+ for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
Iv= Iv->getNextIvar())
Ivars.push_back(Iv);
}
@@ -2102,13 +2213,13 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
/// those inherited by it.
void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) {
- if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+ if (const auto *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
// We can use protocol_iterator here instead of
- // all_referenced_protocol_iterator since we are walking all categories.
+ // all_referenced_protocol_iterator since we are walking all categories.
for (auto *Proto : OI->all_referenced_protocols()) {
CollectInheritedProtocols(Proto, Protocols);
}
-
+
// Categories of this Interface.
for (const auto *Cat : OI->visible_categories())
CollectInheritedProtocols(Cat, Protocols);
@@ -2118,11 +2229,11 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
CollectInheritedProtocols(SD, Protocols);
SD = SD->getSuperClass();
}
- } else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+ } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
for (auto *Proto : OC->protocols()) {
CollectInheritedProtocols(Proto, Protocols);
}
- } else if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
+ } else if (const auto *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
// Insert the protocol.
if (!Protocols.insert(
const_cast<ObjCProtocolDecl *>(OP->getCanonicalDecl())).second)
@@ -2184,7 +2295,7 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
}
}
- std::sort(
+ llvm::sort(
Bases.begin(), Bases.end(), [&](const std::pair<QualType, int64_t> &L,
const std::pair<QualType, int64_t> &R) {
return Layout.getBaseClassOffset(L.first->getAsCXXRecordDecl()) <
@@ -2264,7 +2375,7 @@ bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const {
return true;
if (Ty->isMemberPointerType()) {
- const MemberPointerType *MPT = Ty->getAs<MemberPointerType>();
+ const auto *MPT = Ty->getAs<MemberPointerType>();
return !ABI->getMemberPointerInfo(MPT).HasPadding;
}
@@ -2299,11 +2410,11 @@ bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const {
}
unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {
- unsigned count = 0;
+ unsigned count = 0;
// Count ivars declared in class extension.
for (const auto *Ext : OI->known_extensions())
count += Ext->ivar_size();
-
+
// Count ivar defined in this class's implementation. This
// includes synthesized ivars.
if (ObjCImplementationDecl *ImplDecl = OI->getImplementation())
@@ -2330,7 +2441,7 @@ bool ASTContext::isSentinelNullExpr(const Expr *E) {
return false;
}
-/// \brief Get the implementation of ObjCInterfaceDecl, or nullptr if none
+/// Get the implementation of ObjCInterfaceDecl, or nullptr if none
/// exists.
ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
@@ -2340,7 +2451,7 @@ ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D)
return nullptr;
}
-/// \brief Get the implementation of ObjCCategoryDecl, or nullptr if none
+/// Get the implementation of ObjCCategoryDecl, or nullptr if none
/// exists.
ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
@@ -2350,14 +2461,14 @@ ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
return nullptr;
}
-/// \brief Set the implementation of ObjCInterfaceDecl.
+/// Set the implementation of ObjCInterfaceDecl.
void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,
ObjCImplementationDecl *ImplD) {
assert(IFaceD && ImplD && "Passed null params");
ObjCImpls[IFaceD] = ImplD;
}
-/// \brief Set the implementation of ObjCCategoryDecl.
+/// Set the implementation of ObjCCategoryDecl.
void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCCategoryImplDecl *ImplD) {
assert(CatD && ImplD && "Passed null params");
@@ -2377,34 +2488,31 @@ void ASTContext::setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
const NamedDecl *ND) const {
- if (const ObjCInterfaceDecl *ID =
- dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext()))
+ if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext()))
return ID;
- if (const ObjCCategoryDecl *CD =
- dyn_cast<ObjCCategoryDecl>(ND->getDeclContext()))
+ if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND->getDeclContext()))
return CD->getClassInterface();
- if (const ObjCImplDecl *IMD =
- dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
+ if (const auto *IMD = dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
return IMD->getClassInterface();
return nullptr;
}
-/// \brief Get the copy initialization expression of VarDecl, or nullptr if
+/// Get the copy initialization expression of VarDecl, or nullptr if
/// none exists.
Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
assert(VD && "Passed null params");
- assert(VD->hasAttr<BlocksAttr>() &&
+ assert(VD->hasAttr<BlocksAttr>() &&
"getBlockVarCopyInits - not __block var");
llvm::DenseMap<const VarDecl*, Expr*>::iterator
I = BlockVarCopyInits.find(VD);
- return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : nullptr;
+ return (I != BlockVarCopyInits.end()) ? I->second : nullptr;
}
-/// \brief Set the copy inialization expression of a block var decl.
+/// Set the copy inialization expression of a block var decl.
void ASTContext::setBlockVarCopyInits(VarDecl*VD, Expr* Init) {
assert(VD && Init && "Passed null params");
- assert(VD->hasAttr<BlocksAttr>() &&
+ assert(VD->hasAttr<BlocksAttr>() &&
"setBlockVarCopyInits - not __block var");
BlockVarCopyInits[VD] = Init;
}
@@ -2417,7 +2525,7 @@ TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&
"incorrect data size provided to CreateTypeSourceInfo!");
- TypeSourceInfo *TInfo =
+ auto *TInfo =
(TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8);
new (TInfo) TypeSourceInfo(T);
return TInfo;
@@ -2470,7 +2578,7 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {
(void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos);
}
- ExtQuals *eq = new (*this, TypeAlignment) ExtQuals(baseType, canon, quals);
+ auto *eq = new (*this, TypeAlignment) ExtQuals(baseType, canon, quals);
ExtQualNodes.InsertNode(eq, insertPos);
return QualType(eq, fastQuals);
}
@@ -2522,7 +2630,7 @@ QualType ASTContext::getObjCGCQualType(QualType T,
if (CanT.getObjCGCAttr() == GCAttr)
return T;
- if (const PointerType *ptr = T->getAs<PointerType>()) {
+ if (const auto *ptr = T->getAs<PointerType>()) {
QualType Pointee = ptr->getPointeeType();
if (Pointee->isAnyPointerType()) {
QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
@@ -2550,10 +2658,10 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,
return T;
QualType Result;
- if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
+ if (const auto *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
Result = getFunctionNoProtoType(FNPT->getReturnType(), Info);
} else {
- const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
+ const auto *FPT = cast<FunctionProtoType>(T);
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = Info;
Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI);
@@ -2566,7 +2674,7 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,
QualType ResultType) {
FD = FD->getMostRecentDecl();
while (true) {
- const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
+ const auto *FPT = FD->getType()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI));
if (FunctionDecl *Next = FD->getPreviousDecl())
@@ -2582,26 +2690,24 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,
/// specified exception specification. Type sugar that can be present on a
/// declaration of a function with an exception specification is permitted
/// and preserved. Other type sugar (for instance, typedefs) is not.
-static QualType getFunctionTypeWithExceptionSpec(
- ASTContext &Context, QualType Orig,
- const FunctionProtoType::ExceptionSpecInfo &ESI) {
+QualType ASTContext::getFunctionTypeWithExceptionSpec(
+ QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) {
// Might have some parens.
- if (auto *PT = dyn_cast<ParenType>(Orig))
- return Context.getParenType(
- getFunctionTypeWithExceptionSpec(Context, PT->getInnerType(), ESI));
+ if (const auto *PT = dyn_cast<ParenType>(Orig))
+ return getParenType(
+ getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI));
// Might have a calling-convention attribute.
- if (auto *AT = dyn_cast<AttributedType>(Orig))
- return Context.getAttributedType(
+ if (const auto *AT = dyn_cast<AttributedType>(Orig))
+ return getAttributedType(
AT->getAttrKind(),
- getFunctionTypeWithExceptionSpec(Context, AT->getModifiedType(), ESI),
- getFunctionTypeWithExceptionSpec(Context, AT->getEquivalentType(),
- ESI));
+ getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
+ getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
// Anything else must be a function type. Rebuild it with the new exception
// specification.
- const FunctionProtoType *Proto = cast<FunctionProtoType>(Orig);
- return Context.getFunctionType(
+ const auto *Proto = cast<FunctionProtoType>(Orig);
+ return getFunctionType(
Proto->getReturnType(), Proto->getParamTypes(),
Proto->getExtProtoInfo().withExceptionSpec(ESI));
}
@@ -2610,8 +2716,8 @@ bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,
QualType U) {
return hasSameType(T, U) ||
(getLangOpts().CPlusPlus17 &&
- hasSameType(getFunctionTypeWithExceptionSpec(*this, T, EST_None),
- getFunctionTypeWithExceptionSpec(*this, U, EST_None)));
+ hasSameType(getFunctionTypeWithExceptionSpec(T, EST_None),
+ getFunctionTypeWithExceptionSpec(U, EST_None)));
}
void ASTContext::adjustExceptionSpec(
@@ -2619,7 +2725,7 @@ void ASTContext::adjustExceptionSpec(
bool AsWritten) {
// Update the type.
QualType Updated =
- getFunctionTypeWithExceptionSpec(*this, FD->getType(), ESI);
+ getFunctionTypeWithExceptionSpec(FD->getType(), ESI);
FD->setType(Updated);
if (!AsWritten)
@@ -2630,7 +2736,7 @@ void ASTContext::adjustExceptionSpec(
// If the type and the type-as-written differ, we may need to update
// the type-as-written too.
if (TSInfo->getType() != FD->getType())
- Updated = getFunctionTypeWithExceptionSpec(*this, TSInfo->getType(), ESI);
+ Updated = getFunctionTypeWithExceptionSpec(TSInfo->getType(), ESI);
// FIXME: When we get proper type location information for exceptions,
// we'll also have to rebuild the TypeSourceInfo. For now, we just patch
@@ -2664,7 +2770,7 @@ QualType ASTContext::getComplexType(QualType T) const {
ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
Types.push_back(New);
ComplexTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2692,7 +2798,7 @@ QualType ASTContext::getPointerType(QualType T) const {
PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) PointerType(T, Canonical);
Types.push_back(New);
PointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2783,8 +2889,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- BlockPointerType *New
- = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
Types.push_back(New);
BlockPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2794,9 +2899,9 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
/// lvalue reference to the specified type.
QualType
ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
- assert(getCanonicalType(T) != OverloadTy &&
+ assert(getCanonicalType(T) != OverloadTy &&
"Unresolved overloaded function type");
-
+
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
llvm::FoldingSetNodeID ID;
@@ -2807,7 +2912,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
- const ReferenceType *InnerRef = T->getAs<ReferenceType>();
+ const auto *InnerRef = T->getAs<ReferenceType>();
// If the referencee type isn't canonical, this won't be a canonical type
// either, so fill in the canonical type field.
@@ -2822,9 +2927,8 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- LValueReferenceType *New
- = new (*this, TypeAlignment) LValueReferenceType(T, Canonical,
- SpelledAsLValue);
+ auto *New = new (*this, TypeAlignment) LValueReferenceType(T, Canonical,
+ SpelledAsLValue);
Types.push_back(New);
LValueReferenceTypes.InsertNode(New, InsertPos);
@@ -2844,7 +2948,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
- const ReferenceType *InnerRef = T->getAs<ReferenceType>();
+ const auto *InnerRef = T->getAs<ReferenceType>();
// If the referencee type isn't canonical, this won't be a canonical type
// either, so fill in the canonical type field.
@@ -2859,8 +2963,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- RValueReferenceType *New
- = new (*this, TypeAlignment) RValueReferenceType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) RValueReferenceType(T, Canonical);
Types.push_back(New);
RValueReferenceTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2890,8 +2993,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- MemberPointerType *New
- = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
+ auto *New = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
Types.push_back(New);
MemberPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2935,7 +3037,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- ConstantArrayType *New = new(*this,TypeAlignment)
+ auto *New = new (*this,TypeAlignment)
ConstantArrayType(EltTy, Canon, ArySize, ASM, IndexTypeQuals);
ConstantArrayTypes.InsertNode(New, InsertPos);
Types.push_back(New);
@@ -2964,6 +3066,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::Builtin:
case Type::Complex:
case Type::Vector:
+ case Type::DependentVector:
case Type::ExtVector:
case Type::DependentSizedExtVector:
case Type::DependentAddressSpace:
@@ -3007,7 +3110,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
break;
case Type::LValueReference: {
- const LValueReferenceType *lv = cast<LValueReferenceType>(ty);
+ const auto *lv = cast<LValueReferenceType>(ty);
result = getLValueReferenceType(
getVariableArrayDecayedType(lv->getPointeeType()),
lv->isSpelledAsLValue());
@@ -3015,20 +3118,20 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
}
case Type::RValueReference: {
- const RValueReferenceType *lv = cast<RValueReferenceType>(ty);
+ const auto *lv = cast<RValueReferenceType>(ty);
result = getRValueReferenceType(
getVariableArrayDecayedType(lv->getPointeeType()));
break;
}
case Type::Atomic: {
- const AtomicType *at = cast<AtomicType>(ty);
+ const auto *at = cast<AtomicType>(ty);
result = getAtomicType(getVariableArrayDecayedType(at->getValueType()));
break;
}
case Type::ConstantArray: {
- const ConstantArrayType *cat = cast<ConstantArrayType>(ty);
+ const auto *cat = cast<ConstantArrayType>(ty);
result = getConstantArrayType(
getVariableArrayDecayedType(cat->getElementType()),
cat->getSize(),
@@ -3038,7 +3141,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
}
case Type::DependentSizedArray: {
- const DependentSizedArrayType *dat = cast<DependentSizedArrayType>(ty);
+ const auto *dat = cast<DependentSizedArrayType>(ty);
result = getDependentSizedArrayType(
getVariableArrayDecayedType(dat->getElementType()),
dat->getSizeExpr(),
@@ -3050,7 +3153,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
// Turn incomplete types into [*] types.
case Type::IncompleteArray: {
- const IncompleteArrayType *iat = cast<IncompleteArrayType>(ty);
+ const auto *iat = cast<IncompleteArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(iat->getElementType()),
/*size*/ nullptr,
@@ -3062,7 +3165,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
// Turn VLA types into [*] types.
case Type::VariableArray: {
- const VariableArrayType *vat = cast<VariableArrayType>(ty);
+ const auto *vat = cast<VariableArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(vat->getElementType()),
/*size*/ nullptr,
@@ -3087,7 +3190,7 @@ QualType ASTContext::getVariableArrayType(QualType EltTy,
// Since we don't unique expressions, it isn't possible to unique VLA's
// that have an expression provided for their size.
QualType Canon;
-
+
// Be sure to pull qualifiers off the element type.
if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {
SplitQualType canonSplit = getCanonicalType(EltTy).split();
@@ -3095,8 +3198,8 @@ QualType ASTContext::getVariableArrayType(QualType EltTy,
IndexTypeQuals, Brackets);
Canon = getQualifiedType(Canon, canonSplit.Quals);
}
-
- VariableArrayType *New = new(*this, TypeAlignment)
+
+ auto *New = new (*this, TypeAlignment)
VariableArrayType(EltTy, Canon, NumElts, ASM, IndexTypeQuals, Brackets);
VariableArrayTypes.push_back(New);
@@ -3112,7 +3215,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
ArrayType::ArraySizeModifier ASM,
unsigned elementTypeQuals,
SourceRange brackets) const {
- assert((!numElements || numElements->isTypeDependent() ||
+ assert((!numElements || numElements->isTypeDependent() ||
numElements->isValueDependent()) &&
"Size must be type- or value-dependent!");
@@ -3121,7 +3224,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
// initializer. We do no canonicalization here at all, which is okay
// because they can't be used in most locations.
if (!numElements) {
- DependentSizedArrayType *newType
+ auto *newType
= new (*this, TypeAlignment)
DependentSizedArrayType(*this, elementType, QualType(),
numElements, ASM, elementTypeQuals,
@@ -3167,7 +3270,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
// Otherwise, we need to build a type which follows the spelling
// of the element type.
- DependentSizedArrayType *sugaredType
+ auto *sugaredType
= new (*this, TypeAlignment)
DependentSizedArrayType(*this, elementType, canon, numElements,
ASM, elementTypeQuals, brackets);
@@ -3203,7 +3306,7 @@ QualType ASTContext::getIncompleteArrayType(QualType elementType,
assert(!existing && "Shouldn't be in the map!"); (void) existing;
}
- IncompleteArrayType *newType = new (*this, TypeAlignment)
+ auto *newType = new (*this, TypeAlignment)
IncompleteArrayType(elementType, canon, ASM, elementTypeQuals);
IncompleteArrayTypes.InsertNode(newType, insertPos);
@@ -3235,13 +3338,52 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- VectorType *New = new (*this, TypeAlignment)
+ auto *New = new (*this, TypeAlignment)
VectorType(vecType, NumElts, Canonical, VecKind);
VectorTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
}
+QualType
+ASTContext::getDependentVectorType(QualType VecType, Expr *SizeExpr,
+ SourceLocation AttrLoc,
+ VectorType::VectorKind VecKind) const {
+ llvm::FoldingSetNodeID ID;
+ DependentVectorType::Profile(ID, *this, getCanonicalType(VecType), SizeExpr,
+ VecKind);
+ void *InsertPos = nullptr;
+ DependentVectorType *Canon =
+ DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+ DependentVectorType *New;
+
+ if (Canon) {
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, QualType(Canon, 0), SizeExpr, AttrLoc, VecKind);
+ } else {
+ QualType CanonVecTy = getCanonicalType(VecType);
+ if (CanonVecTy == VecType) {
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, QualType(), SizeExpr, AttrLoc, VecKind);
+
+ DependentVectorType *CanonCheck =
+ DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!CanonCheck &&
+ "Dependent-sized vector_size canonical type broken");
+ (void)CanonCheck;
+ DependentVectorTypes.InsertNode(New, InsertPos);
+ } else {
+ QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
+ SourceLocation());
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, Canon, SizeExpr, AttrLoc, VecKind);
+ }
+ }
+
+ Types.push_back(New);
+ return QualType(New, 0);
+}
+
/// getExtVectorType - Return the unique reference to an extended vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType
@@ -3266,7 +3408,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const {
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- ExtVectorType *New = new (*this, TypeAlignment)
+ auto *New = new (*this, TypeAlignment)
ExtVectorType(vecType, NumElts, Canonical);
VectorTypes.InsertNode(New, InsertPos);
Types.push_back(New);
@@ -3306,7 +3448,7 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,
} else {
QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
SourceLocation());
- New = new (*this, TypeAlignment)
+ New = new (*this, TypeAlignment)
DependentSizedExtVectorType(*this, vecType, Canon, SizeExpr, AttrLoc);
}
}
@@ -3315,10 +3457,10 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,
return QualType(New, 0);
}
-QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
- Expr *AddrSpaceExpr,
+QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
+ Expr *AddrSpaceExpr,
SourceLocation AttrLoc) const {
- assert(AddrSpaceExpr->isInstantiationDependent());
+ assert(AddrSpaceExpr->isInstantiationDependent());
QualType canonPointeeType = getCanonicalType(PointeeType);
@@ -3332,25 +3474,25 @@ QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
if (!canonTy) {
canonTy = new (*this, TypeAlignment)
- DependentAddressSpaceType(*this, canonPointeeType,
+ DependentAddressSpaceType(*this, canonPointeeType,
QualType(), AddrSpaceExpr, AttrLoc);
DependentAddressSpaceTypes.InsertNode(canonTy, insertPos);
Types.push_back(canonTy);
}
-
+
if (canonPointeeType == PointeeType &&
canonTy->getAddrSpaceExpr() == AddrSpaceExpr)
- return QualType(canonTy, 0);
+ return QualType(canonTy, 0);
- DependentAddressSpaceType *sugaredType
+ auto *sugaredType
= new (*this, TypeAlignment)
- DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),
+ DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),
AddrSpaceExpr, AttrLoc);
Types.push_back(sugaredType);
- return QualType(sugaredType, 0);
+ return QualType(sugaredType, 0);
}
-/// \brief Determine whether \p T is canonical as the result type of a function.
+/// Determine whether \p T is canonical as the result type of a function.
static bool isCanonicalResultType(QualType T) {
return T.isCanonical() &&
(T.getObjCLifetime() == Qualifiers::OCL_None ||
@@ -3382,7 +3524,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy,
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- FunctionNoProtoType *New = new (*this, TypeAlignment)
+ auto *New = new (*this, TypeAlignment)
FunctionNoProtoType(ResultTy, Canonical, Info);
Types.push_back(New);
FunctionNoProtoTypes.InsertNode(New, InsertPos);
@@ -3416,6 +3558,11 @@ static bool isCanonicalExceptionSpecification(
if (ESI.Type == EST_BasicNoexcept)
return true;
+ // A noexcept(expr) specification is (possibly) canonical if expr is
+ // value-dependent.
+ if (ESI.Type == EST_DependentNoexcept)
+ return true;
+
// A dynamic exception specification is canonical if it only contains pack
// expansions (so we can't tell whether it's non-throwing) and all its
// contained types are canonical.
@@ -3430,11 +3577,6 @@ static bool isCanonicalExceptionSpecification(
return AnyPackExpansions;
}
- // A noexcept(expr) specification is (possibly) canonical if expr is
- // value-dependent.
- if (ESI.Type == EST_ComputedNoexcept)
- return ESI.NoexceptExpr && ESI.NoexceptExpr->isValueDependent();
-
return false;
}
@@ -3462,7 +3604,7 @@ QualType ASTContext::getFunctionTypeInternal(
// noexcept expression, or we're just looking for a canonical type.
// Otherwise, we're going to need to create a type
// sugar node to hold the concrete expression.
- if (OnlyWantCanonical || EPI.ExceptionSpec.Type != EST_ComputedNoexcept ||
+ if (OnlyWantCanonical || !isComputedNoexcept(EPI.ExceptionSpec.Type) ||
EPI.ExceptionSpec.NoexceptExpr == FPT->getNoexceptExpr())
return Existing;
@@ -3509,7 +3651,7 @@ QualType ASTContext::getFunctionTypeInternal(
// We don't know yet. It shouldn't matter what we pick here; no-one
// should ever look at this.
LLVM_FALLTHROUGH;
- case EST_None: case EST_MSAny:
+ case EST_None: case EST_MSAny: case EST_NoexceptFalse:
CanonicalEPI.ExceptionSpec.Type = EST_None;
break;
@@ -3531,24 +3673,12 @@ QualType ASTContext::getFunctionTypeInternal(
break;
}
- case EST_DynamicNone: case EST_BasicNoexcept:
+ case EST_DynamicNone: case EST_BasicNoexcept: case EST_NoexceptTrue:
CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept;
break;
- case EST_ComputedNoexcept:
- llvm::APSInt Value(1);
- auto *E = CanonicalEPI.ExceptionSpec.NoexceptExpr;
- if (!E || !E->isIntegerConstantExpr(Value, *this, nullptr,
- /*IsEvaluated*/false)) {
- // This noexcept specification is invalid.
- // FIXME: Should this be able to happen?
- CanonicalEPI.ExceptionSpec.Type = EST_None;
- break;
- }
-
- CanonicalEPI.ExceptionSpec.Type =
- Value.getBoolValue() ? EST_BasicNoexcept : EST_None;
- break;
+ case EST_DependentNoexcept:
+ llvm_unreachable("dependent noexcept is already canonical");
}
} else {
CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();
@@ -3573,18 +3703,10 @@ QualType ASTContext::getFunctionTypeInternal(
// Instead of the exception types, there could be a noexcept
// expression, or information used to resolve the exception
// specification.
- size_t Size = sizeof(FunctionProtoType) +
- NumArgs * sizeof(QualType);
-
- if (EPI.ExceptionSpec.Type == EST_Dynamic) {
- Size += EPI.ExceptionSpec.Exceptions.size() * sizeof(QualType);
- } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) {
- Size += sizeof(Expr*);
- } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
- Size += 2 * sizeof(FunctionDecl*);
- } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
- Size += sizeof(FunctionDecl*);
- }
+ size_t Size =
+ sizeof(FunctionProtoType) + NumArgs * sizeof(QualType) +
+ FunctionProtoType::getExceptionSpecSize(
+ EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size());
// Put the ExtParameterInfos last. If all were equal, it would make
// more sense to put these before the exception specification, because
@@ -3596,7 +3718,7 @@ QualType ASTContext::getFunctionTypeInternal(
Size += NumArgs * sizeof(FunctionProtoType::ExtParameterInfo);
}
- FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment);
+ auto *FTP = (FunctionProtoType *) Allocate(Size, TypeAlignment);
FunctionProtoType::ExtProtoInfo newEPI = EPI;
new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI);
Types.push_back(FTP);
@@ -3624,12 +3746,18 @@ QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const {
assert(!NewIP && "Shouldn't be in the map!");
(void)NewIP;
}
- PipeType *New = new (*this, TypeAlignment) PipeType(T, Canonical, ReadOnly);
+ auto *New = new (*this, TypeAlignment) PipeType(T, Canonical, ReadOnly);
Types.push_back(New);
PipeTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
}
+QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const {
+ // OpenCL v1.1 s6.5.3: a string literal is in the constant address space.
+ return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant)
+ : Ty;
+}
+
QualType ASTContext::getReadPipeType(QualType T) const {
return getPipeType(T, true);
}
@@ -3641,7 +3769,7 @@ QualType ASTContext::getWritePipeType(QualType T) const {
#ifndef NDEBUG
static bool NeedsInjectedClassNameType(const RecordDecl *D) {
if (!isa<CXXRecordDecl>(D)) return false;
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
+ const auto *RD = cast<CXXRecordDecl>(D);
if (isa<ClassTemplatePartialSpecializationDecl>(RD))
return true;
if (RD->getDescribedClassTemplate() &&
@@ -3677,21 +3805,20 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
assert(Decl && "Passed null for Decl param");
assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");
- if (const TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Decl))
+ if (const auto *Typedef = dyn_cast<TypedefNameDecl>(Decl))
return getTypedefType(Typedef);
assert(!isa<TemplateTypeParmDecl>(Decl) &&
"Template type parameter types are always available.");
- if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) {
+ if (const auto *Record = dyn_cast<RecordDecl>(Decl)) {
assert(Record->isFirstDecl() && "struct/union has previous declaration");
assert(!NeedsInjectedClassNameType(Record));
return getRecordType(Record);
- } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) {
+ } else if (const auto *Enum = dyn_cast<EnumDecl>(Decl)) {
assert(Enum->isFirstDecl() && "enum has previous declaration");
return getEnumType(Enum);
- } else if (const UnresolvedUsingTypenameDecl *Using =
- dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
+ } else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Using);
Decl->TypeForDecl = newType;
Types.push_back(newType);
@@ -3710,7 +3837,7 @@ ASTContext::getTypedefType(const TypedefNameDecl *Decl,
if (Canonical.isNull())
Canonical = getCanonicalType(Decl->getUnderlyingType());
- TypedefType *newType = new(*this, TypeAlignment)
+ auto *newType = new (*this, TypeAlignment)
TypedefType(Type::Typedef, Decl, Canonical);
Decl->TypeForDecl = newType;
Types.push_back(newType);
@@ -3722,9 +3849,9 @@ QualType ASTContext::getRecordType(const RecordDecl *Decl) const {
if (const RecordDecl *PrevDecl = Decl->getPreviousDecl())
if (PrevDecl->TypeForDecl)
- return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
+ return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
- RecordType *newType = new (*this, TypeAlignment) RecordType(Decl);
+ auto *newType = new (*this, TypeAlignment) RecordType(Decl);
Decl->TypeForDecl = newType;
Types.push_back(newType);
return QualType(newType, 0);
@@ -3735,9 +3862,9 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
if (const EnumDecl *PrevDecl = Decl->getPreviousDecl())
if (PrevDecl->TypeForDecl)
- return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
+ return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
- EnumType *newType = new (*this, TypeAlignment) EnumType(Decl);
+ auto *newType = new (*this, TypeAlignment) EnumType(Decl);
Decl->TypeForDecl = newType;
Types.push_back(newType);
return QualType(newType, 0);
@@ -3763,7 +3890,7 @@ QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
return QualType(type, 0);
}
-/// \brief Retrieve a substitution-result type.
+/// Retrieve a substitution-result type.
QualType
ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
QualType Replacement) const {
@@ -3786,7 +3913,7 @@ ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
return QualType(SubstParm, 0);
}
-/// \brief Retrieve a
+/// Retrieve a
QualType ASTContext::getSubstTemplateTypeParmPackType(
const TemplateTypeParmType *Parm,
const TemplateArgument &ArgPack) {
@@ -3796,14 +3923,14 @@ QualType ASTContext::getSubstTemplateTypeParmPackType(
assert(P.getAsType().isCanonical() && "Pack contains non-canonical type");
}
#endif
-
+
llvm::FoldingSetNodeID ID;
SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack);
void *InsertPos = nullptr;
if (SubstTemplateTypeParmPackType *SubstParm
= SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(SubstParm, 0);
-
+
QualType Canon;
if (!Parm->isCanonicalUnqualified()) {
Canon = getCanonicalType(QualType(Parm, 0));
@@ -3812,15 +3939,15 @@ QualType ASTContext::getSubstTemplateTypeParmPackType(
SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos);
}
- SubstTemplateTypeParmPackType *SubstParm
+ auto *SubstParm
= new (*this, TypeAlignment) SubstTemplateTypeParmPackType(Parm, Canon,
ArgPack);
Types.push_back(SubstParm);
SubstTemplateTypeParmPackTypes.InsertNode(SubstParm, InsertPos);
- return QualType(SubstParm, 0);
+ return QualType(SubstParm, 0);
}
-/// \brief Retrieve the template type parameter type for a template
+/// Retrieve the template type parameter type for a template
/// parameter or parameter pack with the given depth, index, and (optionally)
/// name.
QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
@@ -3839,7 +3966,7 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
TypeParm = new (*this, TypeAlignment) TemplateTypeParmType(TTPDecl, Canon);
- TemplateTypeParmType *TypeCheck
+ TemplateTypeParmType *TypeCheck
= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!TypeCheck && "Template type parameter canonical type broken");
(void)TypeCheck;
@@ -3858,7 +3985,7 @@ ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
SourceLocation NameLoc,
const TemplateArgumentListInfo &Args,
QualType Underlying) const {
- assert(!Name.getAsDependentTemplateName() &&
+ assert(!Name.getAsDependentTemplateName() &&
"No dependent template names here!");
QualType TST = getTemplateSpecializationType(Name, Args, Underlying);
@@ -3878,7 +4005,7 @@ QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
const TemplateArgumentListInfo &Args,
QualType Underlying) const {
- assert(!Template.getAsDependentTemplateName() &&
+ assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
SmallVector<TemplateArgument, 4> ArgVec;
@@ -3894,7 +4021,7 @@ static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) {
for (const TemplateArgument &Arg : Args)
if (Arg.isPackExpansion())
return true;
-
+
return true;
}
#endif
@@ -3903,13 +4030,13 @@ QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
ArrayRef<TemplateArgument> Args,
QualType Underlying) const {
- assert(!Template.getAsDependentTemplateName() &&
+ assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
// Look through qualified template names.
if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
Template = TemplateName(QTN->getTemplateDecl());
-
- bool IsTypeAlias =
+
+ bool IsTypeAlias =
Template.getAsTemplateDecl() &&
isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
QualType CanonType;
@@ -3931,7 +4058,7 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
sizeof(TemplateArgument) * Args.size() +
(IsTypeAlias? sizeof(QualType) : 0),
TypeAlignment);
- TemplateSpecializationType *Spec
+ auto *Spec
= new (Mem) TemplateSpecializationType(Template, Args, CanonType,
IsTypeAlias ? Underlying : QualType());
@@ -3941,13 +4068,13 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
QualType ASTContext::getCanonicalTemplateSpecializationType(
TemplateName Template, ArrayRef<TemplateArgument> Args) const {
- assert(!Template.getAsDependentTemplateName() &&
+ assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
// Look through qualified template names.
if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
Template = TemplateName(QTN->getTemplateDecl());
-
+
// Build the canonical template specialization type.
TemplateName CanonTemplate = getCanonicalTemplateName(Template);
SmallVector<TemplateArgument, 4> CanonArgs;
@@ -3983,12 +4110,12 @@ QualType ASTContext::getCanonicalTemplateSpecializationType(
return QualType(Spec, 0);
}
-QualType
-ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- QualType NamedType) const {
+QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ QualType NamedType,
+ TagDecl *OwnedTagDecl) const {
llvm::FoldingSetNodeID ID;
- ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
+ ElaboratedType::Profile(ID, Keyword, NNS, NamedType, OwnedTagDecl);
void *InsertPos = nullptr;
ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -4003,7 +4130,8 @@ ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
(void)CheckT;
}
- T = new (*this, TypeAlignment) ElaboratedType(Keyword, NNS, NamedType, Canon);
+ T = new (*this, TypeAlignment)
+ ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
Types.push_back(T);
ElaboratedTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
@@ -4077,7 +4205,7 @@ ASTContext::getDependentTemplateSpecializationType(
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
ArrayRef<TemplateArgument> Args) const {
- assert((!NNS || NNS->isDependent()) &&
+ assert((!NNS || NNS->isDependent()) &&
"nested-name-specifier must be dependent");
llvm::FoldingSetNodeID ID;
@@ -4126,7 +4254,7 @@ ASTContext::getDependentTemplateSpecializationType(
TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
TemplateArgument Arg;
- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
QualType ArgType = getTypeDeclType(TTP);
if (TTP->isParameterPack())
ArgType = getPackExpansionType(ArgType, None);
@@ -4212,7 +4340,7 @@ static bool areSortedAndUniqued(ArrayRef<ObjCProtocolDecl *> Protocols) {
if (Protocols[0]->getCanonicalDecl() != Protocols[0])
return false;
-
+
for (unsigned i = 1; i != Protocols.size(); ++i)
if (CmpProtocolNames(&Protocols[i - 1], &Protocols[i]) >= 0 ||
Protocols[i]->getCanonicalDecl() != Protocols[i])
@@ -4265,7 +4393,7 @@ QualType ASTContext::getObjCObjectType(
// type.
ArrayRef<QualType> effectiveTypeArgs = typeArgs;
if (effectiveTypeArgs.empty()) {
- if (auto baseObject = baseType->getAs<ObjCObjectType>())
+ if (const auto *baseObject = baseType->getAs<ObjCObjectType>())
effectiveTypeArgs = baseObject->getTypeArgs();
}
@@ -4313,7 +4441,7 @@ QualType ASTContext::getObjCObjectType(
size += typeArgs.size() * sizeof(QualType);
size += protocols.size() * sizeof(ObjCProtocolDecl *);
void *mem = Allocate(size, TypeAlignment);
- ObjCObjectTypeImpl *T =
+ auto *T =
new (mem) ObjCObjectTypeImpl(canonical, baseType, typeArgs, protocols,
isKindOf);
@@ -4331,15 +4459,14 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
bool allowOnPointerType) const {
hasError = false;
- if (const ObjCTypeParamType *objT =
- dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {
+ if (const auto *objT = dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {
return getObjCTypeParamType(objT->getDecl(), protocols);
}
// Apply protocol qualifiers to ObjCObjectPointerType.
if (allowOnPointerType) {
- if (const ObjCObjectPointerType *objPtr =
- dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) {
+ if (const auto *objPtr =
+ dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) {
const ObjCObjectType *objT = objPtr->getObjectType();
// Merge protocol lists and construct ObjCObjectType.
SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
@@ -4357,7 +4484,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
}
// Apply protocol qualifiers to ObjCObjectType.
- if (const ObjCObjectType *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){
+ if (const auto *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){
// FIXME: Check for protocols to which the class type is already
// known to conform.
@@ -4379,7 +4506,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
// id<protocol-list>
if (type->isObjCIdType()) {
- const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
+ const auto *objPtr = type->castAs<ObjCObjectPointerType>();
type = getObjCObjectType(ObjCBuiltinIdTy, {}, protocols,
objPtr->isKindOfType());
return getObjCObjectPointerType(type);
@@ -4387,7 +4514,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
// Class<protocol-list>
if (type->isObjCClassType()) {
- const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
+ const auto *objPtr = type->castAs<ObjCObjectPointerType>();
type = getObjCObjectType(ObjCBuiltinClassTy, {}, protocols,
objPtr->isKindOfType());
return getObjCObjectPointerType(type);
@@ -4424,8 +4551,7 @@ ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
unsigned size = sizeof(ObjCTypeParamType);
size += protocols.size() * sizeof(ObjCProtocolDecl *);
void *mem = Allocate(size, TypeAlignment);
- ObjCTypeParamType *newType = new (mem)
- ObjCTypeParamType(Decl, Canonical, protocols);
+ auto *newType = new (mem) ObjCTypeParamType(Decl, Canonical, protocols);
Types.push_back(newType);
ObjCTypeParamTypes.InsertNode(newType, InsertPos);
@@ -4439,8 +4565,8 @@ bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT,
ObjCInterfaceDecl *IC) {
if (!QT->isObjCQualifiedIdType())
return false;
-
- if (const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>()) {
+
+ if (const auto *OPT = QT->getAs<ObjCObjectPointerType>()) {
// If both the right and left sides have qualifiers.
for (auto *Proto : OPT->quals()) {
if (!IC->ClassImplementsProtocol(Proto, false))
@@ -4458,7 +4584,7 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
ObjCInterfaceDecl *IDecl) {
if (!QT->isObjCQualifiedIdType())
return false;
- const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+ const auto *OPT = QT->getAs<ObjCObjectPointerType>();
if (!OPT)
return false;
if (!IDecl->hasDefinition())
@@ -4467,7 +4593,7 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
CollectInheritedProtocols(IDecl, InheritedProtocols);
if (InheritedProtocols.empty())
return false;
- // Check that if every protocol in list of id<plist> conforms to a protcol
+ // Check that if every protocol in list of id<plist> conforms to a protocol
// of IDecl's, then bridge casting is ok.
bool Conforms = false;
for (auto *Proto : OPT->quals()) {
@@ -4483,7 +4609,7 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
}
if (Conforms)
return true;
-
+
for (auto *PI : InheritedProtocols) {
// If both the right and left sides have qualifiers.
bool Adopts = false;
@@ -4520,7 +4646,7 @@ QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {
// No match.
void *Mem = Allocate(sizeof(ObjCObjectPointerType), TypeAlignment);
- ObjCObjectPointerType *QType =
+ auto *QType =
new (Mem) ObjCObjectPointerType(Canonical, ObjectT);
Types.push_back(QType);
@@ -4544,9 +4670,9 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
// Prefer the definition, if there is one.
if (const ObjCInterfaceDecl *Def = Decl->getDefinition())
Decl = Def;
-
+
void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
- ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
+ auto *T = new (Mem) ObjCInterfaceType(Decl);
Decl->TypeForDecl = T;
Types.push_back(T);
return QualType(T, 0);
@@ -4593,12 +4719,12 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const {
/// on canonical types (which are always unique).
QualType ASTContext::getTypeOfType(QualType tofType) const {
QualType Canonical = getCanonicalType(tofType);
- TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
+ auto *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
Types.push_back(tot);
return QualType(tot, 0);
}
-/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
+/// Unlike many "get<Type>" functions, we don't unique DecltypeType
/// nodes. This would never be helpful, since each such type has its own
/// expression, and would not give a significant memory saving, since there
/// is an Expr tree under each such type.
@@ -4683,9 +4809,8 @@ QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(AT, 0);
- AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType,
- Keyword,
- IsDependent);
+ auto *AT = new (*this, TypeAlignment)
+ AutoType(DeducedType, Keyword, IsDependent);
Types.push_back(AT);
if (InsertPos)
AutoTypes.InsertNode(AT, InsertPos);
@@ -4706,7 +4831,7 @@ QualType ASTContext::getDeducedTemplateSpecializationType(
DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(DTST, 0);
- DeducedTemplateSpecializationType *DTST = new (*this, TypeAlignment)
+ auto *DTST = new (*this, TypeAlignment)
DeducedTemplateSpecializationType(Template, DeducedType, IsDependent);
Types.push_back(DTST);
if (InsertPos)
@@ -4736,7 +4861,7 @@ QualType ASTContext::getAtomicType(QualType T) const {
AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
Types.push_back(New);
AtomicTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -4776,7 +4901,7 @@ CanQualType ASTContext::getSizeType() const {
return getFromTargetType(Target->getSizeType());
}
-/// Return the unique signed counterpart of the integer type
+/// Return the unique signed counterpart of the integer type
/// corresponding to size_t.
CanQualType ASTContext::getSignedSizeType() const {
return getFromTargetType(Target->getSignedSizeType());
@@ -4820,14 +4945,14 @@ QualType ASTContext::getPointerDiffType() const {
return getFromTargetType(Target->getPtrDiffType(0));
}
-/// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+/// Return the unique unsigned counterpart of "ptrdiff_t"
/// integer type. The standard (C11 7.21.6.1p7) refers to this type
/// in the definition of %tu format specifier.
QualType ASTContext::getUnsignedPointerDiffType() const {
return getFromTargetType(Target->getUnsignedPtrDiffType(0));
}
-/// \brief Return the unique type for "pid_t" defined in
+/// Return the unique type for "pid_t" defined in
/// <sys/types.h>. We need this to compute the correct type for vfork().
QualType ASTContext::getProcessIDType() const {
return getFromTargetType(Target->getProcessIDType());
@@ -4863,8 +4988,8 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type,
// the unqualified desugared type and then drops it on the floor.
// We then have to strip that sugar back off with
// getUnqualifiedDesugaredType(), which is silly.
- const ArrayType *AT =
- dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType());
+ const auto *AT =
+ dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType());
// If we don't have an array, just use the results in splitType.
if (!AT) {
@@ -4888,16 +5013,16 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type,
// build the type back up.
quals.addConsistentQualifiers(splitType.Quals);
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
return getConstantArrayType(unqualElementType, CAT->getSize(),
CAT->getSizeModifier(), 0);
}
- if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
+ if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) {
return getIncompleteArrayType(unqualElementType, IAT->getSizeModifier(), 0);
}
- if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(AT)) {
+ if (const auto *VAT = dyn_cast<VariableArrayType>(AT)) {
return getVariableArrayType(unqualElementType,
VAT->getSizeExpr(),
VAT->getSizeModifier(),
@@ -4905,54 +5030,120 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type,
VAT->getBracketsRange());
}
- const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(AT);
+ const auto *DSAT = cast<DependentSizedArrayType>(AT);
return getDependentSizedArrayType(unqualElementType, DSAT->getSizeExpr(),
DSAT->getSizeModifier(), 0,
SourceRange());
}
-/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types that
-/// may be similar (C++ 4.4), replaces T1 and T2 with the type that
-/// they point to and return true. If T1 and T2 aren't pointer types
-/// or pointer-to-member types, or if they are not similar at this
-/// level, returns false and leaves T1 and T2 unchanged. Top-level
-/// qualifiers on T1 and T2 are ignored. This function will typically
-/// be called in a loop that successively "unwraps" pointer and
-/// pointer-to-member types to compare them at each level.
-bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) {
- const PointerType *T1PtrType = T1->getAs<PointerType>(),
- *T2PtrType = T2->getAs<PointerType>();
+/// Attempt to unwrap two types that may both be array types with the same bound
+/// (or both be array types of unknown bound) for the purpose of comparing the
+/// cv-decomposition of two types per C++ [conv.qual].
+bool ASTContext::UnwrapSimilarArrayTypes(QualType &T1, QualType &T2) {
+ bool UnwrappedAny = false;
+ while (true) {
+ auto *AT1 = getAsArrayType(T1);
+ if (!AT1) return UnwrappedAny;
+
+ auto *AT2 = getAsArrayType(T2);
+ if (!AT2) return UnwrappedAny;
+
+ // If we don't have two array types with the same constant bound nor two
+ // incomplete array types, we've unwrapped everything we can.
+ if (auto *CAT1 = dyn_cast<ConstantArrayType>(AT1)) {
+ auto *CAT2 = dyn_cast<ConstantArrayType>(AT2);
+ if (!CAT2 || CAT1->getSize() != CAT2->getSize())
+ return UnwrappedAny;
+ } else if (!isa<IncompleteArrayType>(AT1) ||
+ !isa<IncompleteArrayType>(AT2)) {
+ return UnwrappedAny;
+ }
+
+ T1 = AT1->getElementType();
+ T2 = AT2->getElementType();
+ UnwrappedAny = true;
+ }
+}
+
+/// Attempt to unwrap two types that may be similar (C++ [conv.qual]).
+///
+/// If T1 and T2 are both pointer types of the same kind, or both array types
+/// with the same bound, unwraps layers from T1 and T2 until a pointer type is
+/// unwrapped. Top-level qualifiers on T1 and T2 are ignored.
+///
+/// This function will typically be called in a loop that successively
+/// "unwraps" pointer and pointer-to-member types to compare them at each
+/// level.
+///
+/// \return \c true if a pointer type was unwrapped, \c false if we reached a
+/// pair of types that can't be unwrapped further.
+bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2) {
+ UnwrapSimilarArrayTypes(T1, T2);
+
+ const auto *T1PtrType = T1->getAs<PointerType>();
+ const auto *T2PtrType = T2->getAs<PointerType>();
if (T1PtrType && T2PtrType) {
T1 = T1PtrType->getPointeeType();
T2 = T2PtrType->getPointeeType();
return true;
}
-
- const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
- *T2MPType = T2->getAs<MemberPointerType>();
- if (T1MPType && T2MPType &&
- hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
+
+ const auto *T1MPType = T1->getAs<MemberPointerType>();
+ const auto *T2MPType = T2->getAs<MemberPointerType>();
+ if (T1MPType && T2MPType &&
+ hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
QualType(T2MPType->getClass(), 0))) {
T1 = T1MPType->getPointeeType();
T2 = T2MPType->getPointeeType();
return true;
}
-
+
if (getLangOpts().ObjC1) {
- const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(),
- *T2OPType = T2->getAs<ObjCObjectPointerType>();
+ const auto *T1OPType = T1->getAs<ObjCObjectPointerType>();
+ const auto *T2OPType = T2->getAs<ObjCObjectPointerType>();
if (T1OPType && T2OPType) {
T1 = T1OPType->getPointeeType();
T2 = T2OPType->getPointeeType();
return true;
}
}
-
+
// FIXME: Block pointers, too?
-
+
return false;
}
+bool ASTContext::hasSimilarType(QualType T1, QualType T2) {
+ while (true) {
+ Qualifiers Quals;
+ T1 = getUnqualifiedArrayType(T1, Quals);
+ T2 = getUnqualifiedArrayType(T2, Quals);
+ if (hasSameType(T1, T2))
+ return true;
+ if (!UnwrapSimilarTypes(T1, T2))
+ return false;
+ }
+}
+
+bool ASTContext::hasCvrSimilarType(QualType T1, QualType T2) {
+ while (true) {
+ Qualifiers Quals1, Quals2;
+ T1 = getUnqualifiedArrayType(T1, Quals1);
+ T2 = getUnqualifiedArrayType(T2, Quals2);
+
+ Quals1.removeCVRQualifiers();
+ Quals2.removeCVRQualifiers();
+ if (Quals1 != Quals2)
+ return false;
+
+ if (hasSameType(T1, T2))
+ return true;
+
+ if (!UnwrapSimilarTypes(T1, T2))
+ return false;
+ }
+}
+
DeclarationNameInfo
ASTContext::getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const {
@@ -5008,10 +5199,9 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {
case TemplateName::QualifiedTemplate:
case TemplateName::Template: {
TemplateDecl *Template = Name.getAsTemplateDecl();
- if (TemplateTemplateParmDecl *TTP
- = dyn_cast<TemplateTemplateParmDecl>(Template))
+ if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template))
Template = getCanonicalTemplateTemplateParmDecl(TTP);
-
+
// The canonical template name is the canonical template declaration.
return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));
}
@@ -5061,7 +5251,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
return Arg;
case TemplateArgument::Declaration: {
- ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
+ auto *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
return TemplateArgument(D, Arg.getParamTypeForDecl());
}
@@ -5086,9 +5276,8 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
case TemplateArgument::Pack: {
if (Arg.pack_size() == 0)
return Arg;
-
- TemplateArgument *CanonArgs
- = new (*this) TemplateArgument[Arg.pack_size()];
+
+ auto *CanonArgs = new (*this) TemplateArgument[Arg.pack_size()];
unsigned Idx = 0;
for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
AEnd = Arg.pack_end();
@@ -5131,7 +5320,7 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
QualType T = getCanonicalType(QualType(NNS->getAsType(), 0));
-
+
// If we have some kind of dependent-named type (e.g., "typename T::type"),
// break it apart into its prefix and identifier, then reconsititute those
// as the canonical nested-name-specifier. This is required to canonicalize
@@ -5139,8 +5328,8 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
// types, e.g.,
// typedef typename T::type T1;
// typedef typename T1::type T2;
- if (const DependentNameType *DNT = T->getAs<DependentNameType>())
- return NestedNameSpecifier::Create(*this, DNT->getQualifier(),
+ if (const auto *DNT = T->getAs<DependentNameType>())
+ return NestedNameSpecifier::Create(*this, DNT->getQualifier(),
const_cast<IdentifierInfo *>(DNT->getIdentifier()));
// Otherwise, just canonicalize the type, and force it to be a TypeSpec.
@@ -5163,7 +5352,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// Handle the non-qualified case efficiently.
if (!T.hasLocalQualifiers()) {
// Handle the common positive case fast.
- if (const ArrayType *AT = dyn_cast<ArrayType>(T))
+ if (const auto *AT = dyn_cast<ArrayType>(T))
return AT;
}
@@ -5183,7 +5372,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
Qualifiers qs = split.Quals;
// If we have a simple case, just return now.
- const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty);
+ const auto *ATy = dyn_cast<ArrayType>(split.Ty);
if (!ATy || qs.empty())
return ATy;
@@ -5191,17 +5380,16 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// qualifiers into the array element type and return a new array type.
QualType NewEltTy = getQualifiedType(ATy->getElementType(), qs);
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(ATy))
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(ATy))
return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
CAT->getSizeModifier(),
CAT->getIndexTypeCVRQualifiers()));
- if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy))
+ if (const auto *IAT = dyn_cast<IncompleteArrayType>(ATy))
return cast<ArrayType>(getIncompleteArrayType(NewEltTy,
IAT->getSizeModifier(),
IAT->getIndexTypeCVRQualifiers()));
- if (const DependentSizedArrayType *DSAT
- = dyn_cast<DependentSizedArrayType>(ATy))
+ if (const auto *DSAT = dyn_cast<DependentSizedArrayType>(ATy))
return cast<ArrayType>(
getDependentSizedArrayType(NewEltTy,
DSAT->getSizeExpr(),
@@ -5209,7 +5397,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
DSAT->getIndexTypeCVRQualifiers(),
DSAT->getBracketsRange()));
- const VariableArrayType *VAT = cast<VariableArrayType>(ATy);
+ const auto *VAT = cast<VariableArrayType>(ATy);
return cast<ArrayType>(getVariableArrayType(NewEltTy,
VAT->getSizeExpr(),
VAT->getSizeModifier(),
@@ -5303,7 +5491,7 @@ ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const {
/// getFloatingRank - Return a relative rank for floating point types.
/// This routine will assert if passed a built-in type that isn't a float.
static FloatingRank getFloatingRank(QualType T) {
- if (const ComplexType *CT = T->getAs<ComplexType>())
+ if (const auto *CT = T->getAs<ComplexType>())
return getFloatingRank(CT->getElementType());
assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type");
@@ -5396,14 +5584,20 @@ unsigned ASTContext::getIntegerRank(const Type *T) const {
}
}
-/// \brief Whether this is a promotable bitfield reference according
+/// Whether this is a promotable bitfield reference according
/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
///
/// \returns the type this bit-field will promote to, or NULL if no
/// promotion occurs.
QualType ASTContext::isPromotableBitField(Expr *E) const {
if (E->isTypeDependent() || E->isValueDependent())
- return QualType();
+ return {};
+
+ // C++ [conv.prom]p5:
+ // If the bit-field has an enumerated type, it is treated as any other
+ // value of that type for promotion purposes.
+ if (getLangOpts().CPlusPlus && E->getType()->isEnumeralType())
+ return {};
// FIXME: We should not do this unless E->refersToBitField() is true. This
// matters in C where getSourceBitField() will find bit-fields for various
@@ -5411,7 +5605,7 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
FieldDecl *Field = E->getSourceBitField(); // FIXME: conditional bit-fields?
if (!Field)
- return QualType();
+ return {};
QualType FT = Field->getType();
@@ -5431,18 +5625,20 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
//
// FIXME: C does not permit promotion of a 'long : 3' bitfield to int.
// We perform that promotion here to match GCC and C++.
+ // FIXME: C does not permit promotion of an enum bit-field whose rank is
+ // greater than that of 'int'. We perform that promotion to match GCC.
if (BitWidth < IntSize)
return IntTy;
if (BitWidth == IntSize)
return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy;
- // Types bigger than int are not subject to promotions, and therefore act
+ // Bit-fields wider than int are not subject to promotions, and therefore act
// like the base type. GCC has some weird bugs in this area that we
// deliberately do not follow (GCC follows a pre-standard resolution to
// C's DR315 which treats bit-width as being part of the type, and this leaks
// into their semantics in some cases).
- return QualType();
+ return {};
}
/// getPromotedIntegerType - Returns the type that Promotable will
@@ -5451,10 +5647,10 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
assert(!Promotable.isNull());
assert(Promotable->isPromotableIntegerType());
- if (const EnumType *ET = Promotable->getAs<EnumType>())
+ if (const auto *ET = Promotable->getAs<EnumType>())
return ET->getDecl()->getPromotionType();
- if (const BuiltinType *BT = Promotable->getAs<BuiltinType>()) {
+ if (const auto *BT = Promotable->getAs<BuiltinType>()) {
// C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t
// (3.9.1) can be converted to a prvalue of the first of the following
// types that can represent all the values of its underlying type:
@@ -5463,6 +5659,7 @@ QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
// FIXME: Is there some better way to compute this?
if (BT->getKind() == BuiltinType::WChar_S ||
BT->getKind() == BuiltinType::WChar_U ||
+ BT->getKind() == BuiltinType::Char8 ||
BT->getKind() == BuiltinType::Char16 ||
BT->getKind() == BuiltinType::Char32) {
bool FromIsSigned = BT->getKind() == BuiltinType::WChar_S;
@@ -5489,7 +5686,7 @@ QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy;
}
-/// \brief Recurses in pointer/array types until it finds an objc retainable
+/// Recurses in pointer/array types until it finds an objc retainable
/// type and returns its ownership.
Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
while (!T.isNull()) {
@@ -5497,9 +5694,9 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
return T.getObjCLifetime();
if (T->isArrayType())
T = getBaseElementType(T);
- else if (const PointerType *PT = T->getAs<PointerType>())
+ else if (const auto *PT = T->getAs<PointerType>())
T = PT->getPointeeType();
- else if (const ReferenceType *RT = T->getAs<ReferenceType>())
+ else if (const auto *RT = T->getAs<ReferenceType>())
T = RT->getPointeeType();
else
break;
@@ -5524,9 +5721,9 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
const Type *RHSC = getCanonicalType(RHS).getTypePtr();
// Unwrap enums to their underlying type.
- if (const EnumType *ET = dyn_cast<EnumType>(LHSC))
+ if (const auto *ET = dyn_cast<EnumType>(LHSC))
LHSC = getIntegerTypeForEnum(ET);
- if (const EnumType *ET = dyn_cast<EnumType>(RHSC))
+ if (const auto *ET = dyn_cast<EnumType>(RHSC))
RHSC = getIntegerTypeForEnum(ET);
if (LHSC == RHSC) return 0;
@@ -5633,10 +5830,10 @@ QualType ASTContext::getObjCSuperType() const {
}
void ASTContext::setCFConstantStringType(QualType T) {
- const TypedefType *TD = T->getAs<TypedefType>();
+ const auto *TD = T->getAs<TypedefType>();
assert(TD && "Invalid CFConstantStringType");
CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl());
- auto TagType =
+ const auto *TagType =
CFConstantStringTypeDecl->getUnderlyingType()->getAs<RecordType>();
assert(TagType && "Invalid CFConstantStringType");
CFConstantStringTagDecl = TagType->getDecl();
@@ -5717,7 +5914,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
}
TargetInfo::OpenCLTypeKind ASTContext::getOpenCLTypeKind(const Type *T) const {
- auto BT = dyn_cast<BuiltinType>(T);
+ const auto *BT = dyn_cast<BuiltinType>(T);
if (!BT) {
if (isa<PipeType>(T))
@@ -5764,30 +5961,34 @@ bool ASTContext::BlockRequiresCopying(QualType Ty,
if (const CXXRecordDecl *record = Ty->getAsCXXRecordDecl()) {
const Expr *copyExpr = getBlockVarCopyInits(D);
if (!copyExpr && record->hasTrivialDestructor()) return false;
-
+
return true;
}
-
+
+ // The block needs copy/destroy helpers if Ty is non-trivial to destructively
+ // move or destroy.
+ if (Ty.isNonTrivialToPrimitiveDestructiveMove() || Ty.isDestructedType())
+ return true;
+
if (!Ty->isObjCRetainableType()) return false;
-
+
Qualifiers qs = Ty.getQualifiers();
-
+
// If we have lifetime, that dominates.
if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {
switch (lifetime) {
case Qualifiers::OCL_None: llvm_unreachable("impossible");
-
+
// These are just bits as far as the runtime is concerned.
case Qualifiers::OCL_ExplicitNone:
case Qualifiers::OCL_Autoreleasing:
return false;
-
- // Tell the runtime that this is ARC __weak, called by the
- // byref routines.
+
+ // These cases should have been taken care of when checking the type's
+ // non-triviality.
case Qualifiers::OCL_Weak:
- // ARC __strong __block variables need to be retained.
case Qualifiers::OCL_Strong:
- return true;
+ llvm_unreachable("impossible");
}
llvm_unreachable("fell out of lifetime switch!");
}
@@ -5801,7 +6002,7 @@ bool ASTContext::getByrefLifetime(QualType Ty,
if (!getLangOpts().ObjC1 ||
getLangOpts().getGC() != LangOptions::NonGC)
return false;
-
+
HasByrefExtendedLayout = false;
if (Ty->isRecordType()) {
HasByrefExtendedLayout = true;
@@ -5827,7 +6028,7 @@ TypedefDecl *ASTContext::getObjCInstanceTypeDecl() {
// This returns true if a type has been typedefed to BOOL:
// typedef <type> BOOL;
static bool isTypeTypedefedAsBOOL(QualType T) {
- if (const TypedefType *TT = dyn_cast<TypedefType>(T))
+ if (const auto *TT = dyn_cast<TypedefType>(T))
if (IdentifierInfo *II = TT->getDecl()->getIdentifier())
return II->isStr("BOOL");
@@ -5839,7 +6040,7 @@ static bool isTypeTypedefedAsBOOL(QualType T) {
CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const {
if (!type->isIncompleteArrayType() && type->isIncompleteType())
return CharUnits::Zero();
-
+
CharUnits sz = getTypeSizeInChars(type);
// Make all integer and enum types at least as large as an int
@@ -5879,8 +6080,7 @@ ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const {
return InlineVariableDefinitionKind::WeakUnknown;
}
-static inline
-std::string charUnitsToString(const CharUnits &CU) {
+static std::string charUnitsToString(const CharUnits &CU) {
return llvm::itostr(CU.getQuantity());
}
@@ -5916,13 +6116,13 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
S += charUnitsToString(ParmOffset);
// Block pointer and offset.
S += "@?0";
-
+
// Argument types.
ParmOffset = PtrSize;
for (auto PVDecl : Decl->parameters()) {
- QualType PType = PVDecl->getOriginalType();
- if (const ArrayType *AT =
- dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+ QualType PType = PVDecl->getOriginalType();
+ if (const auto *AT =
+ dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
// Use array's original type only if it has known number of
// elements.
if (!isa<ConstantArrayType>(AT))
@@ -5953,8 +6153,8 @@ ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const {
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
continue;
-
- assert(sz.isPositive() &&
+
+ assert(sz.isPositive() &&
"getObjCEncodingForFunctionDecl - Incomplete param type");
ParmOffset += sz;
}
@@ -5964,8 +6164,8 @@ ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const {
// Argument types.
for (auto PVDecl : Decl->parameters()) {
QualType PType = PVDecl->getOriginalType();
- if (const ArrayType *AT =
- dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+ if (const auto *AT =
+ dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
// Use array's original type only if it has known number of
// elements.
if (!isa<ConstantArrayType>(AT))
@@ -5976,12 +6176,12 @@ ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const {
S += charUnitsToString(ParmOffset);
ParmOffset += getObjCEncodingTypeSize(PType);
}
-
+
return S;
}
/// getObjCEncodingForMethodParameter - Return the encoded type for a single
-/// method parameter or return type. If Extended, include class names and
+/// method parameter or return type. If Extended, include class names and
/// block object types.
void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
QualType T, std::string& S,
@@ -5991,9 +6191,9 @@ void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
// Encode parameter type.
getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
true /*OutermostType*/,
- false /*EncodingProperty*/,
- false /*StructField*/,
- Extended /*EncodeBlockParameters*/,
+ false /*EncodingProperty*/,
+ false /*StructField*/,
+ Extended /*EncodeBlockParameters*/,
Extended /*EncodeClassNames*/);
}
@@ -6019,8 +6219,8 @@ std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
continue;
-
- assert(sz.isPositive() &&
+
+ assert(sz.isPositive() &&
"getObjCEncodingForMethodDecl - Incomplete param type");
ParmOffset += sz;
}
@@ -6034,20 +6234,20 @@ std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
E = Decl->sel_param_end(); PI != E; ++PI) {
const ParmVarDecl *PVDecl = *PI;
QualType PType = PVDecl->getOriginalType();
- if (const ArrayType *AT =
- dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+ if (const auto *AT =
+ dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
// Use array's original type only if it has known number of
// elements.
if (!isa<ConstantArrayType>(AT))
PType = PVDecl->getType();
} else if (PType->isFunctionType())
PType = PVDecl->getType();
- getObjCEncodingForMethodParameter(PVDecl->getObjCDeclQualifier(),
+ getObjCEncodingForMethodParameter(PVDecl->getObjCDeclQualifier(),
PType, S, Extended);
S += charUnitsToString(ParmOffset);
ParmOffset += getObjCEncodingTypeSize(PType);
}
-
+
return S;
}
@@ -6057,13 +6257,12 @@ ASTContext::getObjCPropertyImplDeclForPropertyDecl(
const Decl *Container) const {
if (!Container)
return nullptr;
- if (const ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(Container)) {
+ if (const auto *CID = dyn_cast<ObjCCategoryImplDecl>(Container)) {
for (auto *PID : CID->property_impls())
if (PID->getPropertyDecl() == PD)
return PID;
} else {
- const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
+ const auto *OID = cast<ObjCImplementationDecl>(Container);
for (auto *PID : OID->property_impls())
if (PID->getPropertyDecl() == PD)
return PID;
@@ -6170,7 +6369,7 @@ ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
/// 'i' or 'I' instead if encoding a struct field, or a pointer!
void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const {
if (isa<TypedefType>(PointeeTy.getTypePtr())) {
- if (const BuiltinType *BT = PointeeTy->getAs<BuiltinType>()) {
+ if (const auto *BT = PointeeTy->getAs<BuiltinType>()) {
if (BT->getKind() == BuiltinType::ULong && getIntWidth(PointeeTy) == 32)
PointeeTy = UnsignedIntTy;
else
@@ -6207,6 +6406,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
switch (kind) {
case BuiltinType::Void: return 'v';
case BuiltinType::Bool: return 'B';
+ case BuiltinType::Char8:
case BuiltinType::Char_U:
case BuiltinType::UChar: return 'C';
case BuiltinType::Char16:
@@ -6235,6 +6435,30 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Half:
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
// FIXME: potentially need @encodes for these!
return ' ';
@@ -6264,13 +6488,13 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) {
EnumDecl *Enum = ET->getDecl();
-
+
// The encoding of an non-fixed enum type is always 'i', regardless of size.
if (!Enum->isFixed())
return 'i';
-
+
// The encoding of a fixed enum type matches its fixed underlying type.
- const BuiltinType *BT = Enum->getIntegerType()->castAs<BuiltinType>();
+ const auto *BT = Enum->getIntegerType()->castAs<BuiltinType>();
return getObjCEncodingForPrimitiveKind(C, BT->getKind());
}
@@ -6307,10 +6531,10 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
S += llvm::utostr(Offset);
- if (const EnumType *ET = T->getAs<EnumType>())
+ if (const auto *ET = T->getAs<EnumType>())
S += ObjCEncodingForEnumType(Ctx, ET);
else {
- const BuiltinType *BT = T->castAs<BuiltinType>();
+ const auto *BT = T->castAs<BuiltinType>();
S += getObjCEncodingForPrimitiveKind(Ctx, BT->getKind());
}
}
@@ -6335,21 +6559,21 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::Enum:
if (FD && FD->isBitField())
return EncodeBitField(this, S, T, FD);
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CT))
+ if (const auto *BT = dyn_cast<BuiltinType>(CT))
S += getObjCEncodingForPrimitiveKind(this, BT->getKind());
else
S += ObjCEncodingForEnumType(this, cast<EnumType>(CT));
return;
case Type::Complex: {
- const ComplexType *CT = T->castAs<ComplexType>();
+ const auto *CT = T->castAs<ComplexType>();
S += 'j';
getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr);
return;
}
case Type::Atomic: {
- const AtomicType *AT = T->castAs<AtomicType>();
+ const auto *AT = T->castAs<AtomicType>();
S += 'A';
getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr);
return;
@@ -6361,7 +6585,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::RValueReference: {
QualType PointeeTy;
if (isa<PointerType>(CT)) {
- const PointerType *PT = T->castAs<PointerType>();
+ const auto *PT = T->castAs<PointerType>();
if (PT->isObjCSelType()) {
S += ':';
return;
@@ -6405,7 +6629,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '*';
return;
}
- } else if (const RecordType *RTy = PointeeTy->getAs<RecordType>()) {
+ } else if (const auto *RTy = PointeeTy->getAs<RecordType>()) {
// GCC binary compat: Need to convert "struct objc_class *" to "#".
if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) {
S += '#';
@@ -6430,7 +6654,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray: {
- const ArrayType *AT = cast<ArrayType>(CT);
+ const auto *AT = cast<ArrayType>(CT);
if (isa<IncompleteArrayType>(AT) && !StructField) {
// Incomplete arrays are encoded as a pointer to the array element.
@@ -6441,7 +6665,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
} else {
S += '[';
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
S += llvm::utostr(CAT->getSize().getZExtValue());
else {
//Variable length arrays are encoded as a regular array with 0 elements.
@@ -6470,8 +6694,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Anonymous structures print as '?'
if (const IdentifierInfo *II = RDecl->getIdentifier()) {
S += II->getName();
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
+ if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
llvm::raw_string_ostream OS(S);
printTemplateArgumentList(OS, TemplateArgs.asArray(),
@@ -6513,11 +6736,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
case Type::BlockPointer: {
- const BlockPointerType *BT = T->castAs<BlockPointerType>();
+ const auto *BT = T->castAs<BlockPointerType>();
S += "@?"; // Unlike a pointer-to-function, which is "^?".
if (EncodeBlockParameters) {
- const FunctionType *FT = BT->getPointeeType()->castAs<FunctionType>();
-
+ const auto *FT = BT->getPointeeType()->castAs<FunctionType>();
+
S += '<';
// Block return type
getObjCEncodingForTypeImpl(
@@ -6528,7 +6751,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Block self
S += "@?";
// Block parameters
- if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
+ if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) {
for (const auto &I : FPT->param_types())
getObjCEncodingForTypeImpl(
I, S, ExpandPointedToStructures, ExpandStructures, FD,
@@ -6552,10 +6775,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += "{objc_class=}";
return;
}
- // TODO: Double check to make sure this intentially falls through.
+ // TODO: Double check to make sure this intentionally falls through.
LLVM_FALLTHROUGH;
}
-
+
case Type::ObjCInterface: {
// Ignore protocol qualifiers when mangling at this level.
// @encode(class_name)
@@ -6567,7 +6790,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
- const FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
+ const FieldDecl *Field = Ivars[i];
if (Field->isBitField())
getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
else
@@ -6582,7 +6805,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
case Type::ObjCObjectPointer: {
- const ObjCObjectPointerType *OPT = T->castAs<ObjCObjectPointerType>();
+ const auto *OPT = T->castAs<ObjCObjectPointerType>();
if (OPT->isObjCIdType()) {
S += '@';
return;
@@ -6591,7 +6814,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
// FIXME: Consider if we need to output qualifiers for 'Class<p>'.
// Since this is a binary compatibility issue, need to consult with runtime
- // folks. Fortunately, this is a *very* obsure construct.
+ // folks. Fortunately, this is a *very* obscure construct.
S += '#';
return;
}
@@ -6628,7 +6851,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
- if (cast<FieldDecl>(Ivars[i]) == FD) {
+ if (Ivars[i] == FD) {
S += '{';
S += OI->getObjCRuntimeNameAsString();
S += '}';
@@ -6645,7 +6868,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
S += '@';
- if (OPT->getInterfaceDecl() &&
+ if (OPT->getInterfaceDecl() &&
(FD || EncodingProperty || EncodeClassNames)) {
S += '"';
S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString();
@@ -6670,7 +6893,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (NotEncodedT)
*NotEncodedT = T;
return;
-
+
// We could see an undeduced auto type here during error recovery.
// Just ignore it.
case Type::Auto:
@@ -6702,7 +6925,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
if (!RDecl->getDefinition() || RDecl->getDefinition()->isInvalidDecl())
return;
- CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);
+ const auto *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);
std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets;
const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
@@ -6718,7 +6941,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
}
}
}
-
+
unsigned i = 0;
for (auto *Field : RDecl->fields()) {
uint64_t offs = layout.getFieldOffset(i);
@@ -6779,7 +7002,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
#ifndef NDEBUG
assert(CurOffs <= CurLayObj->first);
if (CurOffs < CurLayObj->first) {
- uint64_t padding = CurLayObj->first - CurOffs;
+ uint64_t padding = CurLayObj->first - CurOffs;
// FIXME: There doesn't seem to be a way to indicate in the encoding that
// packing/alignment of members is different that normal, in which case
// the encoding will be out-of-sync with the real layout.
@@ -6795,7 +7018,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
if (!dcl)
break; // reached end of structure.
- if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) {
+ if (auto *base = dyn_cast<CXXRecordDecl>(dcl)) {
// We expand the bases without their virtual bases since those are going
// in the initial structure. Note that this differs from gcc which
// expands virtual bases each time one is encountered in the hierarchy,
@@ -6807,7 +7030,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
#endif
} else {
- FieldDecl *field = cast<FieldDecl>(dcl);
+ const auto *field = cast<FieldDecl>(dcl);
if (FD) {
S += '"';
S += field->getNameAsString();
@@ -6879,15 +7102,15 @@ TypedefDecl *ASTContext::getObjCClassDecl() const {
ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {
if (!ObjCProtocolClassDecl) {
- ObjCProtocolClassDecl
- = ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(),
+ ObjCProtocolClassDecl
+ = ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(),
SourceLocation(),
&Idents.get("Protocol"),
/*typeParamList=*/nullptr,
/*PrevDecl=*/nullptr,
- SourceLocation(), true);
+ SourceLocation(), true);
}
-
+
return ObjCProtocolClassDecl;
}
@@ -7250,6 +7473,10 @@ TypedefDecl *ASTContext::getBuiltinMSVaListDecl() const {
return BuiltinMSVaListDecl;
}
+bool ASTContext::canBuiltinBeRedeclared(const FunctionDecl *FD) const {
+ return BuiltinInfo.canBeRedeclared(FD->getBuiltinID());
+}
+
void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
assert(ObjCConstantStringType.isNull() &&
"'NSConstantString' type already set!");
@@ -7257,7 +7484,7 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
ObjCConstantStringType = getObjCInterfaceType(Decl);
}
-/// \brief Retrieve the template name that corresponds to a non-empty
+/// Retrieve the template name that corresponds to a non-empty
/// lookup.
TemplateName
ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
@@ -7267,12 +7494,13 @@ ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
void *memory = Allocate(sizeof(OverloadedTemplateStorage) +
size * sizeof(FunctionTemplateDecl*));
- OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size);
+ auto *OT = new (memory) OverloadedTemplateStorage(size);
NamedDecl **Storage = OT->getStorage();
for (UnresolvedSetIterator I = Begin; I != End; ++I) {
NamedDecl *D = *I;
assert(isa<FunctionTemplateDecl>(D) ||
+ isa<UnresolvedUsingValueDecl>(D) ||
(isa<UsingShadowDecl>(D) &&
isa<FunctionTemplateDecl>(D->getUnderlyingDecl())));
*Storage++ = D;
@@ -7281,14 +7509,14 @@ ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
return TemplateName(OT);
}
-/// \brief Retrieve the template name that represents a qualified
+/// Retrieve the template name that represents a qualified
/// template name such as \c std::vector.
TemplateName
ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
TemplateDecl *Template) const {
assert(NNS && "Missing nested-name-specifier in qualified template name");
-
+
// FIXME: Canonicalization?
llvm::FoldingSetNodeID ID;
QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
@@ -7305,7 +7533,7 @@ ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
return TemplateName(QTN);
}
-/// \brief Retrieve the template name that represents a dependent
+/// Retrieve the template name that represents a dependent
/// template name such as \c MetaFun::template apply.
TemplateName
ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
@@ -7341,24 +7569,24 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
return TemplateName(QTN);
}
-/// \brief Retrieve the template name that represents a dependent
+/// Retrieve the template name that represents a dependent
/// template name such as \c MetaFun::template operator+.
-TemplateName
+TemplateName
ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
OverloadedOperatorKind Operator) const {
assert((!NNS || NNS->isDependent()) &&
"Nested name specifier must be dependent");
-
+
llvm::FoldingSetNodeID ID;
DependentTemplateName::Profile(ID, NNS, Operator);
void *InsertPos = nullptr;
DependentTemplateName *QTN
= DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
-
+
if (QTN)
return TemplateName(QTN);
-
+
NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
if (CanonNNS == NNS) {
QTN = new (*this, alignof(DependentTemplateName))
@@ -7373,12 +7601,12 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
assert(!CheckQTN && "Dependent template name canonicalization broken");
(void)CheckQTN;
}
-
+
DependentTemplateNames.InsertNode(QTN, InsertPos);
return TemplateName(QTN);
}
-TemplateName
+TemplateName
ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
TemplateName replacement) const {
llvm::FoldingSetNodeID ID;
@@ -7387,7 +7615,7 @@ ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
void *insertPos = nullptr;
SubstTemplateTemplateParmStorage *subst
= SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos);
-
+
if (!subst) {
subst = new (*this) SubstTemplateTemplateParmStorage(param, replacement);
SubstTemplateTemplateParms.InsertNode(subst, insertPos);
@@ -7396,19 +7624,19 @@ ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
return TemplateName(subst);
}
-TemplateName
+TemplateName
ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
const TemplateArgument &ArgPack) const {
- ASTContext &Self = const_cast<ASTContext &>(*this);
+ auto &Self = const_cast<ASTContext &>(*this);
llvm::FoldingSetNodeID ID;
SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack);
void *InsertPos = nullptr;
SubstTemplateTemplateParmPackStorage *Subst
= SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos);
-
+
if (!Subst) {
- Subst = new (*this) SubstTemplateTemplateParmPackStorage(Param,
+ Subst = new (*this) SubstTemplateTemplateParmPackStorage(Param,
ArgPack.pack_size(),
ArgPack.pack_begin());
SubstTemplateTemplateParmPacks.InsertNode(Subst, InsertPos);
@@ -7422,7 +7650,7 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
/// is actually a value of type @c TargetInfo::IntType.
CanQualType ASTContext::getFromTargetType(unsigned Type) const {
switch (Type) {
- case TargetInfo::NoInt: return CanQualType();
+ case TargetInfo::NoInt: return {};
case TargetInfo::SignedChar: return SignedCharTy;
case TargetInfo::UnsignedChar: return UnsignedCharTy;
case TargetInfo::SignedShort: return ShortTy;
@@ -7465,7 +7693,7 @@ Qualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const {
// pointer.
#ifndef NDEBUG
QualType CT = Ty->getCanonicalTypeInternal();
- while (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+ while (const auto *AT = dyn_cast<ArrayType>(CT))
CT = AT->getElementType();
assert(CT->isAnyPointerType() || CT->isBlockPointerType());
#endif
@@ -7496,8 +7724,8 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec,
// Treat Neon vector types and most AltiVec vector types as if they are the
// equivalent GCC vector types.
- const VectorType *First = FirstVec->getAs<VectorType>();
- const VectorType *Second = SecondVec->getAs<VectorType>();
+ const auto *First = FirstVec->getAs<VectorType>();
+ const auto *Second = SecondVec->getAs<VectorType>();
if (First->getNumElements() == Second->getNumElements() &&
hasSameType(First->getElementType(), Second->getElementType()) &&
First->getVectorKind() != VectorType::AltiVecPixel &&
@@ -7528,12 +7756,12 @@ ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
/// ObjCQualifiedClassTypesAreCompatible - compare Class<pr,...> and
/// Class<pr1, ...>.
-bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,
+bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,
QualType rhs) {
- const ObjCObjectPointerType *lhsQID = lhs->getAs<ObjCObjectPointerType>();
- const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+ const auto *lhsQID = lhs->getAs<ObjCObjectPointerType>();
+ const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
assert((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
-
+
for (auto *lhsProto : lhsQID->quals()) {
bool match = false;
for (auto *rhsProto : rhsOPT->quals()) {
@@ -7561,7 +7789,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
return true;
if (const ObjCObjectPointerType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
- const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+ const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
if (!rhsOPT) return false;
@@ -7638,7 +7866,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
if (!match)
return false;
}
-
+
// Static class's protocols, or its super class or category protocols
// must be found, direct or indirect in rhs's qualifier list or it is a mismatch.
if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) {
@@ -7700,12 +7928,12 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
QualType(RHSOPT,0),
false));
}
-
+
if (LHS->isObjCQualifiedClass() && RHS->isObjCQualifiedClass()) {
return finish(ObjCQualifiedClassTypesAreCompatible(QualType(LHSOPT,0),
QualType(RHSOPT,0)));
}
-
+
// If we have 2 user-defined types, fall into that path.
if (LHS->getInterface() && RHS->getInterface()) {
return finish(canAssignObjCInterfaces(LHS, RHS));
@@ -7715,7 +7943,7 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
}
/// canAssignObjCInterfacesInBlockPointer - This routine is specifically written
-/// for providing type-safety for objective-c pointers used to pass/return
+/// for providing type-safety for objective-c pointers used to pass/return
/// arguments in block literals. When passed as arguments, passing 'A*' where
/// 'id' is expected is not OK. Passing 'Sub *" where 'Super *" is expected is
/// not OK. For the return type, the opposite is not OK.
@@ -7744,17 +7972,17 @@ bool ASTContext::canAssignObjCInterfacesInBlockPointer(
if (RHSOPT->isObjCBuiltinType() || LHSOPT->isObjCIdType())
return true;
-
+
if (LHSOPT->isObjCBuiltinType()) {
return finish(RHSOPT->isObjCBuiltinType() ||
RHSOPT->isObjCQualifiedIdType());
}
-
+
if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType())
return finish(ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0),
QualType(RHSOPT,0),
false));
-
+
const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
if (LHS && RHS) { // We have 2 user-defined types.
@@ -7782,13 +8010,13 @@ static int compareObjCProtocolsByName(ObjCProtocolDecl * const *lhs,
/// the given common base.
/// It is used to build composite qualifier list of the composite type of
/// the conditional expression involving two objective-c pointer objects.
-static
+static
void getIntersectionOfProtocols(ASTContext &Context,
const ObjCInterfaceDecl *CommonBase,
const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT,
SmallVectorImpl<ObjCProtocolDecl *> &IntersectionSet) {
-
+
const ObjCObjectType* LHS = LHSOPT->getObjectType();
const ObjCObjectType* RHS = RHSOPT->getObjectType();
assert(LHS->getInterface() && "LHS must have an interface base");
@@ -7847,14 +8075,14 @@ void getIntersectionOfProtocols(ASTContext &Context,
static bool canAssignObjCObjectTypes(ASTContext &ctx, QualType lhs,
QualType rhs) {
// Common case: two object pointers.
- const ObjCObjectPointerType *lhsOPT = lhs->getAs<ObjCObjectPointerType>();
- const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+ const auto *lhsOPT = lhs->getAs<ObjCObjectPointerType>();
+ const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
if (lhsOPT && rhsOPT)
return ctx.canAssignObjCInterfaces(lhsOPT, rhsOPT);
// Two block pointers.
- const BlockPointerType *lhsBlock = lhs->getAs<BlockPointerType>();
- const BlockPointerType *rhsBlock = rhs->getAs<BlockPointerType>();
+ const auto *lhsBlock = lhs->getAs<BlockPointerType>();
+ const auto *rhsBlock = rhs->getAs<BlockPointerType>();
if (lhsBlock && rhsBlock)
return ctx.typesAreBlockPointerCompatible(lhs, rhs);
@@ -7914,7 +8142,7 @@ QualType ASTContext::areCommonBaseCompatible(
const ObjCInterfaceDecl* RDecl = RHS->getInterface();
if (!LDecl || !RDecl)
- return QualType();
+ return {};
// When either LHS or RHS is a kindof type, we should return a kindof type.
// For example, for common base of kindof(ASub1) and kindof(ASub2), we return
@@ -7939,7 +8167,7 @@ QualType ASTContext::areCommonBaseCompatible(
if (!sameObjCTypeArgs(*this, LHS->getInterface(),
LHS->getTypeArgs(), RHS->getTypeArgs(),
/*stripKindOf=*/true))
- return QualType();
+ return {};
} else if (LHS->isSpecialized() != RHS->isSpecialized()) {
// If only one has type arguments, the result will not have type
// arguments.
@@ -7990,7 +8218,7 @@ QualType ASTContext::areCommonBaseCompatible(
if (!sameObjCTypeArgs(*this, LHS->getInterface(),
LHS->getTypeArgs(), RHS->getTypeArgs(),
/*stripKindOf=*/true))
- return QualType();
+ return {};
} else if (LHS->isSpecialized() != RHS->isSpecialized()) {
// If only one has type arguments, the result will not have type
// arguments.
@@ -8025,7 +8253,7 @@ QualType ASTContext::areCommonBaseCompatible(
RHS = RHSSuperType->castAs<ObjCObjectType>();
}
- return QualType();
+ return {};
}
bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
@@ -8057,7 +8285,7 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
// If there is no protocols associated with RHS, it is not a match.
if (SuperClassInheritedProtocols.empty())
return false;
-
+
for (const auto *LHSProto : LHS->quals()) {
bool SuperImplementsProtocol = false;
for (auto *SuperClassProto : SuperClassInheritedProtocols)
@@ -8092,8 +8320,8 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) {
// get the "pointed to" types
- const ObjCObjectPointerType *LHSOPT = LHS->getAs<ObjCObjectPointerType>();
- const ObjCObjectPointerType *RHSOPT = RHS->getAs<ObjCObjectPointerType>();
+ const auto *LHSOPT = LHS->getAs<ObjCObjectPointerType>();
+ const auto *RHSOPT = RHS->getAs<ObjCObjectPointerType>();
if (!LHSOPT || !RHSOPT)
return false;
@@ -8146,7 +8374,7 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
}
}
- return QualType();
+ return {};
}
/// mergeFunctionParameterTypes - merge two types which appear as function
@@ -8170,13 +8398,13 @@ QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs,
return mergeTypes(lhs, rhs, OfBlockPointer, Unqualified);
}
-QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
+QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
bool OfBlockPointer,
bool Unqualified) {
- const FunctionType *lbase = lhs->getAs<FunctionType>();
- const FunctionType *rbase = rhs->getAs<FunctionType>();
- const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
- const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
+ const auto *lbase = lhs->getAs<FunctionType>();
+ const auto *rbase = rhs->getAs<FunctionType>();
+ const auto *lproto = dyn_cast<FunctionProtoType>(lbase);
+ const auto *rproto = dyn_cast<FunctionProtoType>(rbase);
bool allLTypes = true;
bool allRTypes = true;
@@ -8193,8 +8421,9 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
else
retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false,
Unqualified);
- if (retType.isNull()) return QualType();
-
+ if (retType.isNull())
+ return {};
+
if (Unqualified)
retType = retType.getUnqualifiedType();
@@ -8204,7 +8433,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
LRetType = LRetType.getUnqualifiedType();
RRetType = RRetType.getUnqualifiedType();
}
-
+
if (getCanonicalType(retType) != LRetType)
allLTypes = false;
if (getCanonicalType(retType) != RRetType)
@@ -8219,18 +8448,20 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// Compatible functions must have compatible calling conventions
if (lbaseInfo.getCC() != rbaseInfo.getCC())
- return QualType();
+ return {};
// Regparm is part of the calling convention.
if (lbaseInfo.getHasRegParm() != rbaseInfo.getHasRegParm())
- return QualType();
+ return {};
if (lbaseInfo.getRegParm() != rbaseInfo.getRegParm())
- return QualType();
+ return {};
if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult())
- return QualType();
+ return {};
if (lbaseInfo.getNoCallerSavedRegs() != rbaseInfo.getNoCallerSavedRegs())
- return QualType();
+ return {};
+ if (lbaseInfo.getNoCfCheck() != rbaseInfo.getNoCfCheck())
+ return {};
// FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
@@ -8247,20 +8478,20 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
"C++ shouldn't be here");
// Compatible functions must have the same number of parameters
if (lproto->getNumParams() != rproto->getNumParams())
- return QualType();
+ return {};
// Variadic and non-variadic functions aren't compatible
if (lproto->isVariadic() != rproto->isVariadic())
- return QualType();
+ return {};
if (lproto->getTypeQuals() != rproto->getTypeQuals())
- return QualType();
+ return {};
SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos;
bool canUseLeft, canUseRight;
if (!mergeExtParameterInfo(lproto, rproto, canUseLeft, canUseRight,
newParamInfos))
- return QualType();
+ return {};
if (!canUseLeft)
allLTypes = false;
@@ -8275,7 +8506,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
QualType paramType = mergeFunctionParameterTypes(
lParamType, rParamType, OfBlockPointer, Unqualified);
if (paramType.isNull())
- return QualType();
+ return {};
if (Unqualified)
paramType = paramType.getUnqualifiedType();
@@ -8291,7 +8522,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (getCanonicalType(paramType) != getCanonicalType(rParamType))
allRTypes = false;
}
-
+
if (allLTypes) return lhs;
if (allRTypes) return rhs;
@@ -8308,7 +8539,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
const FunctionProtoType *proto = lproto ? lproto : rproto;
if (proto) {
assert(!proto->hasExceptionSpec() && "C++ shouldn't be here");
- if (proto->isVariadic()) return QualType();
+ if (proto->isVariadic())
+ return {};
// Check that the types are compatible with the types that
// would result from default argument promotions (C99 6.7.5.3p15).
// The only types actually affected are promotable integer
@@ -8319,15 +8551,15 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// Look at the converted type of enum types, since that is the type used
// to pass enum values.
- if (const EnumType *Enum = paramTy->getAs<EnumType>()) {
+ if (const auto *Enum = paramTy->getAs<EnumType>()) {
paramTy = Enum->getDecl()->getIntegerType();
if (paramTy.isNull())
- return QualType();
+ return {};
}
if (paramTy->isPromotableIntegerType() ||
getCanonicalType(paramTy).getUnqualifiedType() == FloatTy)
- return QualType();
+ return {};
}
if (allLTypes) return lhs;
@@ -8351,7 +8583,8 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET,
// Compatibility is based on the underlying type, not the promotion
// type.
QualType underlyingType = ET->getDecl()->getIntegerType();
- if (underlyingType.isNull()) return QualType();
+ if (underlyingType.isNull())
+ return {};
if (Context.hasSameType(underlyingType, other))
return other;
@@ -8361,10 +8594,10 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET,
Context.getTypeSize(underlyingType) == Context.getTypeSize(other))
return other;
- return QualType();
+ return {};
}
-QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
+QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
bool OfBlockPointer,
bool Unqualified, bool BlockReturnType) {
// C++ [expr]: If an expression initially has the type "reference to T", the
@@ -8379,7 +8612,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
LHS = LHS.getUnqualifiedType();
RHS = RHS.getUnqualifiedType();
}
-
+
QualType LHSCan = getCanonicalType(LHS),
RHSCan = getCanonicalType(RHS);
@@ -8397,7 +8630,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
LQuals.getAddressSpace() != RQuals.getAddressSpace() ||
LQuals.getObjCLifetime() != RQuals.getObjCLifetime() ||
LQuals.hasUnaligned() != RQuals.hasUnaligned())
- return QualType();
+ return {};
// Exactly one GC qualifier difference is allowed: __strong is
// okay if the other type has no GC qualifier but is an Objective
@@ -8409,7 +8642,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");
if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)
- return QualType();
+ return {};
if (GC_L == Qualifiers::Strong && RHSCan->isObjCObjectPointerType()) {
return mergeTypes(LHS, getObjCGCQualType(RHS, Qualifiers::Strong));
@@ -8417,7 +8650,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
if (GC_R == Qualifiers::Strong && LHSCan->isObjCObjectPointerType()) {
return mergeTypes(getObjCGCQualType(LHS, Qualifiers::Strong), RHS);
}
- return QualType();
+ return {};
}
// Okay, qualifiers are equal.
@@ -8448,7 +8681,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
if (LHSClass != RHSClass) {
// Note that we only have special rules for turning block enum
// returns into block int returns, not vice-versa.
- if (const EnumType* ETy = LHS->getAs<EnumType>()) {
+ if (const auto *ETy = LHS->getAs<EnumType>()) {
return mergeEnumWithInteger(*this, ETy, RHS, false);
}
if (const EnumType* ETy = RHS->getAs<EnumType>()) {
@@ -8461,8 +8694,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
if (RHS->isObjCIdType() && LHS->isBlockPointerType())
return RHS;
}
-
- return QualType();
+
+ return {};
}
// The canonical type classes match.
@@ -8498,9 +8731,10 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
LHSPointee = LHSPointee.getUnqualifiedType();
RHSPointee = RHSPointee.getUnqualifiedType();
}
- QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false,
+ QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false,
Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
return LHS;
if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
@@ -8522,7 +8756,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
// Blocks can't be an expression in a ternary operator (OpenCL v2.0
// 6.12.5) thus the following check is asymmetric.
if (!LHSPteeQual.isAddressSpaceSupersetOf(RHSPteeQual))
- return QualType();
+ return {};
LHSPteeQual.removeAddressSpace();
RHSPteeQual.removeAddressSpace();
LHSPointee =
@@ -8532,7 +8766,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
}
QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer,
Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
return LHS;
if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
@@ -8548,9 +8783,10 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
LHSValue = LHSValue.getUnqualifiedType();
RHSValue = RHSValue.getUnqualifiedType();
}
- QualType ResultType = mergeTypes(LHSValue, RHSValue, false,
+ QualType ResultType = mergeTypes(LHSValue, RHSValue, false,
Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
if (getCanonicalType(LHSValue) == getCanonicalType(ResultType))
return LHS;
if (getCanonicalType(RHSValue) == getCanonicalType(ResultType))
@@ -8562,7 +8798,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);
const ConstantArrayType* RCAT = getAsConstantArrayType(RHS);
if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize())
- return QualType();
+ return {};
QualType LHSElem = getAsArrayType(LHS)->getElementType();
QualType RHSElem = getAsArrayType(RHS)->getElementType();
@@ -8570,9 +8806,42 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
LHSElem = LHSElem.getUnqualifiedType();
RHSElem = RHSElem.getUnqualifiedType();
}
-
+
QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
+
+ const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
+ const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
+
+ // If either side is a variable array, and both are complete, check whether
+ // the current dimension is definite.
+ if (LVAT || RVAT) {
+ auto SizeFetch = [this](const VariableArrayType* VAT,
+ const ConstantArrayType* CAT)
+ -> std::pair<bool,llvm::APInt> {
+ if (VAT) {
+ llvm::APSInt TheInt;
+ Expr *E = VAT->getSizeExpr();
+ if (E && E->isIntegerConstantExpr(TheInt, *this))
+ return std::make_pair(true, TheInt);
+ else
+ return std::make_pair(false, TheInt);
+ } else if (CAT) {
+ return std::make_pair(true, CAT->getSize());
+ } else {
+ return std::make_pair(false, llvm::APInt());
+ }
+ };
+
+ bool HaveLSize, HaveRSize;
+ llvm::APInt LSize, RSize;
+ std::tie(HaveLSize, LSize) = SizeFetch(LVAT, LCAT);
+ std::tie(HaveRSize, RSize) = SizeFetch(RVAT, RCAT);
+ if (HaveLSize && HaveRSize && !llvm::APInt::isSameValue(LSize, RSize))
+ return {}; // Definite, but unequal, array dimension
+ }
+
if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
return LHS;
if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
@@ -8581,8 +8850,6 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
ArrayType::ArraySizeModifier(), 0);
if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(),
ArrayType::ArraySizeModifier(), 0);
- const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
- const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
return LHS;
if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
@@ -8608,29 +8875,29 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return mergeFunctionTypes(LHS, RHS, OfBlockPointer, Unqualified);
case Type::Record:
case Type::Enum:
- return QualType();
+ return {};
case Type::Builtin:
// Only exactly equal builtin types are compatible, which is tested above.
- return QualType();
+ return {};
case Type::Complex:
// Distinct complex types are incompatible.
- return QualType();
+ return {};
case Type::Vector:
// FIXME: The merged type should be an ExtVector!
if (areCompatVectorTypes(LHSCan->getAs<VectorType>(),
RHSCan->getAs<VectorType>()))
return LHS;
- return QualType();
+ return {};
case Type::ObjCObject: {
// Check if the types are assignment compatible.
// FIXME: This should be type compatibility, e.g. whether
// "LHS x; RHS x;" at global scope is legal.
- const ObjCObjectType* LHSIface = LHS->getAs<ObjCObjectType>();
- const ObjCObjectType* RHSIface = RHS->getAs<ObjCObjectType>();
+ const auto *LHSIface = LHS->getAs<ObjCObjectType>();
+ const auto *RHSIface = RHS->getAs<ObjCObjectType>();
if (canAssignObjCInterfaces(LHSIface, RHSIface))
return LHS;
- return QualType();
+ return {};
}
case Type::ObjCObjectPointer:
if (OfBlockPointer) {
@@ -8639,17 +8906,17 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
RHS->getAs<ObjCObjectPointerType>(),
BlockReturnType))
return LHS;
- return QualType();
+ return {};
}
if (canAssignObjCInterfaces(LHS->getAs<ObjCObjectPointerType>(),
RHS->getAs<ObjCObjectPointerType>()))
return LHS;
- return QualType();
+ return {};
case Type::Pipe:
assert(LHS != RHS &&
"Equivalent pipe types should have already been handled!");
- return QualType();
+ return {};
}
llvm_unreachable("Invalid Type::Class!");
@@ -8717,20 +8984,20 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
return LHS;
if (RHSCan->isFunctionType()) {
if (!LHSCan->isFunctionType())
- return QualType();
+ return {};
QualType OldReturnType =
cast<FunctionType>(RHSCan.getTypePtr())->getReturnType();
QualType NewReturnType =
cast<FunctionType>(LHSCan.getTypePtr())->getReturnType();
- QualType ResReturnType =
+ QualType ResReturnType =
mergeObjCGCQualifiers(NewReturnType, OldReturnType);
if (ResReturnType.isNull())
- return QualType();
+ return {};
if (ResReturnType == NewReturnType || ResReturnType == OldReturnType) {
// id foo(); ... __strong id foo(); or: __strong id foo(); ... id foo();
// In either case, use OldReturnType to build the new function type.
- const FunctionType *F = LHS->getAs<FunctionType>();
- if (const FunctionProtoType *FPT = cast<FunctionProtoType>(F)) {
+ const auto *F = LHS->getAs<FunctionType>();
+ if (const auto *FPT = cast<FunctionProtoType>(F)) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = getFunctionExtInfo(LHS);
QualType ResultType =
@@ -8738,9 +9005,9 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
return ResultType;
}
}
- return QualType();
+ return {};
}
-
+
// If the qualifiers are different, the types can still be merged.
Qualifiers LQuals = LHSCan.getLocalQualifiers();
Qualifiers RQuals = RHSCan.getLocalQualifiers();
@@ -8748,8 +9015,8 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
// If any of these qualifiers are different, we have a type mismatch.
if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||
LQuals.getAddressSpace() != RQuals.getAddressSpace())
- return QualType();
-
+ return {};
+
// Exactly one GC qualifier difference is allowed: __strong is
// okay if the other type has no GC qualifier but is an Objective
// C object pointer (i.e. implicitly strong by default). We fix
@@ -8758,17 +9025,17 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
Qualifiers::GC GC_L = LQuals.getObjCGCAttr();
Qualifiers::GC GC_R = RQuals.getObjCGCAttr();
assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");
-
+
if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)
- return QualType();
-
+ return {};
+
if (GC_L == Qualifiers::Strong)
return LHS;
if (GC_R == Qualifiers::Strong)
return RHS;
- return QualType();
+ return {};
}
-
+
if (LHSCan->isObjCObjectPointerType() && RHSCan->isObjCObjectPointerType()) {
QualType LHSBaseQT = LHS->getAs<ObjCObjectPointerType>()->getPointeeType();
QualType RHSBaseQT = RHS->getAs<ObjCObjectPointerType>()->getPointeeType();
@@ -8778,7 +9045,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
if (ResQT == RHSBaseQT)
return RHS;
}
- return QualType();
+ return {};
}
//===----------------------------------------------------------------------===//
@@ -8786,7 +9053,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
//===----------------------------------------------------------------------===//
unsigned ASTContext::getIntWidth(QualType T) const {
- if (const EnumType *ET = T->getAs<EnumType>())
+ if (const auto *ET = T->getAs<EnumType>())
T = ET->getDecl()->getIntegerType();
if (T->isBooleanType())
return 1;
@@ -8795,19 +9062,20 @@ unsigned ASTContext::getIntWidth(QualType T) const {
}
QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
- assert(T->hasSignedIntegerRepresentation() && "Unexpected type");
-
+ assert((T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) &&
+ "Unexpected type");
+
// Turn <4 x signed int> -> <4 x unsigned int>
- if (const VectorType *VTy = T->getAs<VectorType>())
+ if (const auto *VTy = T->getAs<VectorType>())
return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
VTy->getNumElements(), VTy->getVectorKind());
// For enums, we return the unsigned version of the base type.
- if (const EnumType *ETy = T->getAs<EnumType>())
+ if (const auto *ETy = T->getAs<EnumType>())
T = ETy->getDecl()->getIntegerType();
-
- const BuiltinType *BTy = T->getAs<BuiltinType>();
- assert(BTy && "Unexpected signed integer type");
+
+ const auto *BTy = T->getAs<BuiltinType>();
+ assert(BTy && "Unexpected signed integer or fixed point type");
switch (BTy->getKind()) {
case BuiltinType::Char_S:
case BuiltinType::SChar:
@@ -8822,8 +9090,33 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
return UnsignedLongLongTy;
case BuiltinType::Int128:
return UnsignedInt128Ty;
+
+ case BuiltinType::ShortAccum:
+ return UnsignedShortAccumTy;
+ case BuiltinType::Accum:
+ return UnsignedAccumTy;
+ case BuiltinType::LongAccum:
+ return UnsignedLongAccumTy;
+ case BuiltinType::SatShortAccum:
+ return SatUnsignedShortAccumTy;
+ case BuiltinType::SatAccum:
+ return SatUnsignedAccumTy;
+ case BuiltinType::SatLongAccum:
+ return SatUnsignedLongAccumTy;
+ case BuiltinType::ShortFract:
+ return UnsignedShortFractTy;
+ case BuiltinType::Fract:
+ return UnsignedFractTy;
+ case BuiltinType::LongFract:
+ return UnsignedLongFractTy;
+ case BuiltinType::SatShortFract:
+ return SatUnsignedShortFractTy;
+ case BuiltinType::SatFract:
+ return SatUnsignedFractTy;
+ case BuiltinType::SatLongFract:
+ return SatUnsignedLongFractTy;
default:
- llvm_unreachable("Unexpected signed integer type");
+ llvm_unreachable("Unexpected signed integer or fixed point type");
}
}
@@ -8852,7 +9145,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
int HowLong = 0;
bool Signed = false, Unsigned = false;
RequiresICE = false;
-
+
// Read the prefixed modifiers first.
bool Done = false;
#ifndef NDEBUG
@@ -8931,10 +9224,12 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
Type = Context.FloatTy;
break;
case 'd':
- assert(HowLong < 2 && !Signed && !Unsigned &&
+ assert(HowLong < 3 && !Signed && !Unsigned &&
"Bad modifiers used with 'd'!");
- if (HowLong)
+ if (HowLong == 1)
Type = Context.LongDoubleTy;
+ else if (HowLong == 2)
+ Type = Context.Float128Ty;
else
Type = Context.DoubleTy;
break;
@@ -9014,10 +9309,10 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
assert(End != Str && "Missing vector size");
Str = End;
- QualType ElementType = DecodeTypeFromStr(Str, Context, Error,
+ QualType ElementType = DecodeTypeFromStr(Str, Context, Error,
RequiresICE, false);
assert(!RequiresICE && "Can't require vector ICE");
-
+
// TODO: No way to make AltiVec vectors in builtins yet.
Type = Context.getVectorType(ElementType, NumElements,
VectorType::GenericVector);
@@ -9025,16 +9320,16 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
}
case 'E': {
char *End;
-
+
unsigned NumElements = strtoul(Str, &End, 10);
assert(End != Str && "Missing vector size");
-
+
Str = End;
-
+
QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE,
false);
Type = Context.getExtVectorType(ElementType, NumElements);
- break;
+ break;
}
case 'X': {
QualType ElementType = DecodeTypeFromStr(Str, Context, Error, RequiresICE,
@@ -9042,7 +9337,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
assert(!RequiresICE && "Can't require complex ICE");
Type = Context.getComplexType(ElementType);
break;
- }
+ }
case 'Y':
Type = Context.getPointerDiffType();
break;
@@ -9050,7 +9345,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
Type = Context.getFILEType();
if (Type.isNull()) {
Error = ASTContext::GE_Missing_stdio;
- return QualType();
+ return {};
}
break;
case 'J':
@@ -9061,7 +9356,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
if (Type.isNull()) {
Error = ASTContext::GE_Missing_setjmp;
- return QualType();
+ return {};
}
break;
case 'K':
@@ -9070,7 +9365,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
if (Type.isNull()) {
Error = ASTContext::GE_Missing_ucontext;
- return QualType();
+ return {};
}
break;
case 'p':
@@ -9112,9 +9407,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
break;
}
}
-
+
assert((!RequiresICE || Type->isIntegralOrEnumerationType()) &&
- "Integer constant 'I' type must be an integer");
+ "Integer constant 'I' type must be an integer");
return Type;
}
@@ -9132,20 +9427,20 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
QualType ResType = DecodeTypeFromStr(TypeStr, *this, Error,
RequiresICE, true);
if (Error != GE_None)
- return QualType();
-
+ return {};
+
assert(!RequiresICE && "Result of intrinsic cannot be required to be an ICE");
-
+
while (TypeStr[0] && TypeStr[0] != '.') {
QualType Ty = DecodeTypeFromStr(TypeStr, *this, Error, RequiresICE, true);
if (Error != GE_None)
- return QualType();
+ return {};
// If this argument is required to be an IntegerConstantExpression and the
// caller cares, fill in the bitmask we return.
if (RequiresICE && IntegerConstantArgs)
*IntegerConstantArgs |= 1 << ArgTypes.size();
-
+
// Do array -> pointer decay. The builtin should use the decayed type.
if (Ty->isArrayType())
Ty = getArrayDecayedType(Ty);
@@ -9154,7 +9449,7 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
}
if (Id == Builtin::BI__GetExceptionInfo)
- return QualType();
+ return {};
assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
"'.' should only occur at end of builtin type list!");
@@ -9185,7 +9480,7 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
// Non-user-provided functions get emitted as weak definitions with every
// use, no matter whether they've been explicitly instantiated etc.
- if (auto *MD = dyn_cast<CXXMethodDecl>(FD))
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
if (!MD->isUserProvided())
return GVA_DiscardableODR;
@@ -9375,7 +9670,7 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
}
bool ASTContext::DeclMustBeEmitted(const Decl *D) {
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (!VD->isFileVarDecl())
return false;
// Global named register variables (GNU extension) are never emitted.
@@ -9384,14 +9679,13 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (VD->getDescribedVarTemplate() ||
isa<VarTemplatePartialSpecializationDecl>(VD))
return false;
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// We never need to emit an uninstantiated function template.
if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
return false;
} else if (isa<PragmaCommentDecl>(D))
return true;
- else if (isa<OMPThreadPrivateDecl>(D) ||
- D->hasAttr<OMPDeclareTargetDeclAttr>())
+ else if (isa<OMPThreadPrivateDecl>(D))
return true;
else if (isa<PragmaDetectMismatchDecl>(D))
return true;
@@ -9404,6 +9698,29 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
else
return false;
+ if (D->isFromASTFile() && !LangOpts.BuildingPCHWithObjectFile) {
+ assert(getExternalSource() && "It's from an AST file; must have a source.");
+ // On Windows, PCH files are built together with an object file. If this
+ // declaration comes from such a PCH and DeclMustBeEmitted would return
+ // true, it would have returned true and the decl would have been emitted
+ // into that object file, so it doesn't need to be emitted here.
+ // Note that decls are still emitted if they're referenced, as usual;
+ // DeclMustBeEmitted is used to decide whether a decl must be emitted even
+ // if it's not referenced.
+ //
+ // Explicit template instantiation definitions are tricky. If there was an
+ // explicit template instantiation decl in the PCH before, it will look like
+ // the definition comes from there, even if that was just the declaration.
+ // (Explicit instantiation defs of variable templates always get emitted.)
+ bool IsExpInstDef =
+ isa<FunctionDecl>(D) &&
+ cast<FunctionDecl>(D)->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+
+ if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef)
+ return false;
+ }
+
// If this is a member of a class template, we do not need to emit it.
if (D->getDeclContext()->isDependentContext())
return false;
@@ -9416,7 +9733,11 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())
return true;
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+ // Multiversioned functions always have to be emitted, because they are used
+ // by the resolver.
+ if (FD->isMultiVersion())
+ return true;
// Forward declarations aren't required.
if (!FD->doesThisDeclarationHaveABody())
return FD->doesDeclarationForceExternallyVisibleDefinition();
@@ -9424,11 +9745,11 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Constructors and destructors are required.
if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
return true;
-
+
// The key function for a class is required. This rule only comes
// into play when inline functions can be key functions, though.
if (getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
const CXXRecordDecl *RD = MD->getParent();
if (MD->isOutOfLine() && RD->isDynamicClass()) {
const CXXMethodDecl *KeyFunc = getCurrentKeyFunction(RD);
@@ -9445,8 +9766,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Implicit template instantiations can also be deferred in C++.
return !isDiscardableGVALinkage(Linkage);
}
-
- const VarDecl *VD = cast<VarDecl>(D);
+
+ const auto *VD = cast<VarDecl>(D);
assert(VD->isFileVarDecl() && "Expected file scoped var");
if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&
@@ -9474,15 +9795,37 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Likewise, variables with tuple-like bindings are required if their
// bindings have side-effects.
- if (auto *DD = dyn_cast<DecompositionDecl>(VD))
- for (auto *BD : DD->bindings())
- if (auto *BindingVD = BD->getHoldingVar())
+ if (const auto *DD = dyn_cast<DecompositionDecl>(VD))
+ for (const auto *BD : DD->bindings())
+ if (const auto *BindingVD = BD->getHoldingVar())
if (DeclMustBeEmitted(BindingVD))
return true;
+ // If the decl is marked as `declare target`, it should be emitted.
+ if (const llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
+ OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
+ return *Res != OMPDeclareTargetDeclAttr::MT_Link;
+
return false;
}
+void ASTContext::forEachMultiversionedFunctionVersion(
+ const FunctionDecl *FD,
+ llvm::function_ref<void(FunctionDecl *)> Pred) const {
+ assert(FD->isMultiVersion() && "Only valid for multiversioned functions");
+ llvm::SmallDenseSet<const FunctionDecl*, 4> SeenDecls;
+ FD = FD->getCanonicalDecl();
+ for (auto *CurDecl :
+ FD->getDeclContext()->getRedeclContext()->lookup(FD->getDeclName())) {
+ FunctionDecl *CurFD = CurDecl->getAsFunction()->getCanonicalDecl();
+ if (CurFD && hasSameType(CurFD->getType(), FD->getType()) &&
+ std::end(SeenDecls) == llvm::find(SeenDecls, CurFD)) {
+ SeenDecls.insert(CurFD);
+ Pred(CurFD);
+ }
+ }
+}
+
CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
bool IsCXXMethod) const {
// Pass through to the C++ ABI object
@@ -9595,7 +9938,7 @@ QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const {
case TargetInfo::Float128:
return Float128Ty;
case TargetInfo::NoFloat:
- return QualType();
+ return {};
}
llvm_unreachable("Unhandled TargetInfo::RealType value");
@@ -9673,7 +10016,7 @@ void ASTContext::setParameterIndex(const ParmVarDecl *D, unsigned int index) {
unsigned ASTContext::getParameterIndex(const ParmVarDecl *D) const {
ParameterIndexTable::const_iterator I = ParamIndices.find(D);
- assert(I != ParamIndices.end() &&
+ assert(I != ParamIndices.end() &&
"ParmIndices lacks entry set by ParmVarDecl");
return I->second;
}
@@ -9739,7 +10082,7 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
}
/// @}
- /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
+ /// A \c RecursiveASTVisitor that builds a map from nodes to their
/// parents as defined by the \c RecursiveASTVisitor.
///
/// Note that the relationship described here is purely in terms of AST
@@ -9749,7 +10092,7 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
public:
- /// \brief Builds and returns the translation unit's parent map.
+ /// Builds and returns the translation unit's parent map.
///
/// The caller takes ownership of the returned \c ParentMap.
static std::pair<ASTContext::ParentMapPointers *,
@@ -9874,7 +10217,8 @@ static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
if (I == Map.end()) {
return llvm::ArrayRef<ast_type_traits::DynTypedNode>();
}
- if (auto *V = I->second.template dyn_cast<ASTContext::ParentVector *>()) {
+ if (const auto *V =
+ I->second.template dyn_cast<ASTContext::ParentVector *>()) {
return llvm::makeArrayRef(*V);
}
return getSingleDynTypedNodeFromParentMap(I->second);
@@ -9906,10 +10250,10 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
return false;
if (!hasSameType(MethodDecl->getReturnType(), MethodImpl->getReturnType()))
return false;
-
+
if (MethodDecl->param_size() != MethodImpl->param_size())
return false;
-
+
for (ObjCMethodDecl::param_const_iterator IM = MethodImpl->param_begin(),
IF = MethodDecl->param_begin(), EM = MethodImpl->param_end(),
EF = MethodDecl->param_end();
@@ -9942,6 +10286,42 @@ unsigned ASTContext::getTargetAddressSpace(LangAS AS) const {
return (*AddrSpaceMap)[(unsigned)AS];
}
+QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+
+ if (Ty->isSaturatedFixedPointType()) return Ty;
+
+ const auto &BT = Ty->getAs<BuiltinType>();
+ switch (BT->getKind()) {
+ default:
+ llvm_unreachable("Not a fixed point type!");
+ case BuiltinType::ShortAccum:
+ return SatShortAccumTy;
+ case BuiltinType::Accum:
+ return SatAccumTy;
+ case BuiltinType::LongAccum:
+ return SatLongAccumTy;
+ case BuiltinType::UShortAccum:
+ return SatUnsignedShortAccumTy;
+ case BuiltinType::UAccum:
+ return SatUnsignedAccumTy;
+ case BuiltinType::ULongAccum:
+ return SatUnsignedLongAccumTy;
+ case BuiltinType::ShortFract:
+ return SatShortFractTy;
+ case BuiltinType::Fract:
+ return SatFractTy;
+ case BuiltinType::LongFract:
+ return SatLongFractTy;
+ case BuiltinType::UShortFract:
+ return SatUnsignedShortFractTy;
+ case BuiltinType::UFract:
+ return SatUnsignedFractTy;
+ case BuiltinType::ULongFract:
+ return SatUnsignedLongFractTy;
+ }
+}
+
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
// doesn't include ASTContext.h
template
@@ -9950,3 +10330,92 @@ clang::LazyGenerationalUpdatePtr<
clang::LazyGenerationalUpdatePtr<
const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(
const clang::ASTContext &Ctx, Decl *Value);
+
+unsigned char ASTContext::getFixedPointScale(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+
+ const auto *BT = Ty->getAs<BuiltinType>();
+ const TargetInfo &Target = getTargetInfo();
+ switch (BT->getKind()) {
+ default:
+ llvm_unreachable("Not a fixed point type!");
+ case BuiltinType::ShortAccum:
+ case BuiltinType::SatShortAccum:
+ return Target.getShortAccumScale();
+ case BuiltinType::Accum:
+ case BuiltinType::SatAccum:
+ return Target.getAccumScale();
+ case BuiltinType::LongAccum:
+ case BuiltinType::SatLongAccum:
+ return Target.getLongAccumScale();
+ case BuiltinType::UShortAccum:
+ case BuiltinType::SatUShortAccum:
+ return Target.getUnsignedShortAccumScale();
+ case BuiltinType::UAccum:
+ case BuiltinType::SatUAccum:
+ return Target.getUnsignedAccumScale();
+ case BuiltinType::ULongAccum:
+ case BuiltinType::SatULongAccum:
+ return Target.getUnsignedLongAccumScale();
+ case BuiltinType::ShortFract:
+ case BuiltinType::SatShortFract:
+ return Target.getShortFractScale();
+ case BuiltinType::Fract:
+ case BuiltinType::SatFract:
+ return Target.getFractScale();
+ case BuiltinType::LongFract:
+ case BuiltinType::SatLongFract:
+ return Target.getLongFractScale();
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatUShortFract:
+ return Target.getUnsignedShortFractScale();
+ case BuiltinType::UFract:
+ case BuiltinType::SatUFract:
+ return Target.getUnsignedFractScale();
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatULongFract:
+ return Target.getUnsignedLongFractScale();
+ }
+}
+
+unsigned char ASTContext::getFixedPointIBits(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+
+ const auto *BT = Ty->getAs<BuiltinType>();
+ const TargetInfo &Target = getTargetInfo();
+ switch (BT->getKind()) {
+ default:
+ llvm_unreachable("Not a fixed point type!");
+ case BuiltinType::ShortAccum:
+ case BuiltinType::SatShortAccum:
+ return Target.getShortAccumIBits();
+ case BuiltinType::Accum:
+ case BuiltinType::SatAccum:
+ return Target.getAccumIBits();
+ case BuiltinType::LongAccum:
+ case BuiltinType::SatLongAccum:
+ return Target.getLongAccumIBits();
+ case BuiltinType::UShortAccum:
+ case BuiltinType::SatUShortAccum:
+ return Target.getUnsignedShortAccumIBits();
+ case BuiltinType::UAccum:
+ case BuiltinType::SatUAccum:
+ return Target.getUnsignedAccumIBits();
+ case BuiltinType::ULongAccum:
+ case BuiltinType::SatULongAccum:
+ return Target.getUnsignedLongAccumIBits();
+ case BuiltinType::ShortFract:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::SatFract:
+ case BuiltinType::LongFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatULongFract:
+ return 0;
+ }
+}