diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/ASTContext.cpp | 1554 |
1 files changed, 800 insertions, 754 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp index a03cf9e7..bccdae9 100644 --- a/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp +++ b/contrib/llvm/tools/clang/lib/AST/ASTContext.cpp @@ -29,6 +29,7 @@ #include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TypeLoc.h" +#include "clang/AST/VTableBuilder.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -62,6 +63,13 @@ enum FloatingRank { RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { if (!CommentsLoaded && ExternalSource) { ExternalSource->ReadComments(); + +#ifndef NDEBUG + ArrayRef<RawComment *> RawComments = Comments.getComments(); + assert(std::is_sorted(RawComments.begin(), RawComments.end(), + BeforeThanCompare<RawComment>(SourceMgr))); +#endif + CommentsLoaded = true; } @@ -69,23 +77,23 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { // User can not attach documentation to implicit declarations. if (D->isImplicit()) - return NULL; + return nullptr; // User can not attach documentation to implicit instantiations. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) - return NULL; + return nullptr; } if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (VD->isStaticDataMember() && VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) - return NULL; + return nullptr; } if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) { if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) - return NULL; + return nullptr; } if (const ClassTemplateSpecializationDecl *CTSD = @@ -93,35 +101,35 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { TemplateSpecializationKind TSK = CTSD->getSpecializationKind(); if (TSK == TSK_ImplicitInstantiation || TSK == TSK_Undeclared) - return NULL; + return nullptr; } if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) { if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) - return NULL; + return nullptr; } if (const TagDecl *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()) - return NULL; + return nullptr; } // TODO: handle comments for function parameters properly. if (isa<ParmVarDecl>(D)) - return NULL; + return nullptr; // TODO: we could look up template parameter documentation in the template // documentation. if (isa<TemplateTypeParmDecl>(D) || isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTemplateParmDecl>(D)) - return NULL; + return nullptr; ArrayRef<RawComment *> RawComments = Comments.getComments(); // If there are no comments anywhere, we won't find anything. if (RawComments.empty()) - return NULL; + return nullptr; // Find declaration location. // For Objective-C declarations we generally don't expect to have multiple @@ -137,17 +145,29 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { DeclLoc = D->getLocStart(); else { DeclLoc = D->getLocation(); - // If location of the typedef name is in a macro, it is because being - // declared via a macro. Try using declaration's starting location - // as the "declaration location". - if (DeclLoc.isMacroID() && isa<TypedefDecl>(D)) - DeclLoc = D->getLocStart(); + if (DeclLoc.isMacroID()) { + if (isa<TypedefDecl>(D)) { + // If location of the typedef name is in a macro, it is because being + // 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)) { + // 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 + // case, adjust the source location to the expansion loc so that we can + // attach the comment to the tag decl. + if (SourceMgr.isMacroArgExpansion(DeclLoc) && + TD->isCompleteDefinition()) + DeclLoc = SourceMgr.getExpansionLoc(DeclLoc); + } + } } // If the declaration doesn't map directly to a location in a file, we // can't find the comment. if (DeclLoc.isInvalid() || !DeclLoc.isFileID()) - return NULL; + return nullptr; // Find the comment that occurs just after this declaration. ArrayRef<RawComment *>::iterator Comment; @@ -201,12 +221,12 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { // The comment just after the declaration was not a trailing comment. // Let's look at the previous comment. if (Comment == RawComments.begin()) - return NULL; + return nullptr; --Comment; // Check that we actually have a non-member Doxygen comment. if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment()) - return NULL; + return nullptr; // Decompose the end of the comment. std::pair<FileID, unsigned> CommentEndDecomp @@ -215,14 +235,14 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { // If the comment and the declaration aren't in the same file, then they // aren't related. if (DeclLocDecomp.first != CommentEndDecomp.first) - return NULL; + return nullptr; // Get the corresponding buffer. bool Invalid = false; const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first, &Invalid).data(); if (Invalid) - return NULL; + return nullptr; // Extract text between the comment and declaration. StringRef Text(Buffer + CommentEndDecomp.second, @@ -231,7 +251,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { // There should be no other declarations or preprocessor directives between // comment and declaration. if (Text.find_first_of(";{}#@") != StringRef::npos) - return NULL; + return nullptr; return *Comment; } @@ -329,13 +349,11 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl( } // Search for comments attached to declarations in the redeclaration chain. - const RawComment *RC = NULL; - const Decl *OriginalDeclForRC = NULL; - for (Decl::redecl_iterator I = D->redecls_begin(), - E = D->redecls_end(); - I != E; ++I) { + const RawComment *RC = nullptr; + const Decl *OriginalDeclForRC = nullptr; + for (auto I : D->redecls()) { llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos = - RedeclComments.find(*I); + RedeclComments.find(I); if (Pos != RedeclComments.end()) { const RawCommentAndCacheFlags &Raw = Pos->second; if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) { @@ -344,16 +362,16 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl( break; } } else { - RC = getRawCommentForDeclNoCache(*I); - OriginalDeclForRC = *I; + RC = getRawCommentForDeclNoCache(I); + OriginalDeclForRC = I; RawCommentAndCacheFlags Raw; if (RC) { Raw.setRaw(RC); Raw.setKind(RawCommentAndCacheFlags::FromDecl); } else Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl); - Raw.setOriginalDecl(*I); - RedeclComments[*I] = Raw; + Raw.setOriginalDecl(I); + RedeclComments[I] = Raw; if (RC) break; } @@ -371,10 +389,8 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl( Raw.setKind(RawCommentAndCacheFlags::FromRedecl); Raw.setOriginalDecl(OriginalDeclForRC); - for (Decl::redecl_iterator I = D->redecls_begin(), - E = D->redecls_end(); - I != E; ++I) { - RawCommentAndCacheFlags &R = RedeclComments[*I]; + for (auto I : D->redecls()) { + RawCommentAndCacheFlags &R = RedeclComments[I]; if (R.getKind() == RawCommentAndCacheFlags::NoCommentInDecl) R = Raw; } @@ -390,10 +406,7 @@ static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod, if (!ID) return; // Add redeclared method here. - for (ObjCInterfaceDecl::known_extensions_iterator - Ext = ID->known_extensions_begin(), - ExtEnd = ID->known_extensions_end(); - Ext != ExtEnd; ++Ext) { + for (const auto *Ext : ID->known_extensions()) { if (ObjCMethodDecl *RedeclaredMethod = Ext->getMethod(ObjCMethod->getSelector(), ObjCMethod->isInstanceMethod())) @@ -409,6 +422,8 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC, ThisDeclInfo->IsFilled = false; ThisDeclInfo->fill(); ThisDeclInfo->CommentDecl = FC->getDecl(); + if (!ThisDeclInfo->TemplateParameters) + ThisDeclInfo->TemplateParameters = FC->getDeclInfo()->TemplateParameters; comments::FullComment *CFC = new (*this) comments::FullComment(FC->getBlocks(), ThisDeclInfo); @@ -418,14 +433,14 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC, comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const { const RawComment *RC = getRawCommentForDeclNoCache(D); - return RC ? RC->parse(*this, 0, D) : 0; + return RC ? RC->parse(*this, nullptr, D) : nullptr; } comments::FullComment *ASTContext::getCommentForDecl( const Decl *D, const Preprocessor *PP) const { if (D->isInvalidDecl()) - return NULL; + return nullptr; D = adjustDeclToTemplate(D); const Decl *Canonical = D->getCanonicalDecl(); @@ -482,13 +497,12 @@ comments::FullComment *ASTContext::getCommentForDecl( } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { if (!(RD = RD->getDefinition())) - return NULL; + return nullptr; // Check non-virtual bases. - for (CXXRecordDecl::base_class_const_iterator I = - RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { - if (I->isVirtual() || (I->getAccessSpecifier() != AS_public)) + for (const auto &I : RD->bases()) { + if (I.isVirtual() || (I.getAccessSpecifier() != AS_public)) continue; - QualType Ty = I->getType(); + QualType Ty = I.getType(); if (Ty.isNull()) continue; if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) { @@ -500,11 +514,10 @@ comments::FullComment *ASTContext::getCommentForDecl( } } // Check virtual bases. - for (CXXRecordDecl::base_class_const_iterator I = - RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) { - if (I->getAccessSpecifier() != AS_public) + for (const auto &I : RD->vbases()) { + if (I.getAccessSpecifier() != AS_public) continue; - QualType Ty = I->getType(); + QualType Ty = I.getType(); if (Ty.isNull()) continue; if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) { @@ -515,7 +528,7 @@ comments::FullComment *ASTContext::getCommentForDecl( } } } - return NULL; + return nullptr; } // If the RawComment was attached to other redeclaration of this Decl, we @@ -576,7 +589,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( // Check if we already have a canonical template template parameter. llvm::FoldingSetNodeID ID; CanonicalTemplateTemplateParm::Profile(ID, TTP); - void *InsertPos = 0; + void *InsertPos = nullptr; CanonicalTemplateTemplateParm *Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); if (Canonical) @@ -595,7 +608,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( SourceLocation(), SourceLocation(), TTP->getDepth(), - TTP->getIndex(), 0, false, + TTP->getIndex(), nullptr, false, TTP->isParameterPack())); else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) { @@ -615,7 +628,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( SourceLocation(), SourceLocation(), NTTP->getDepth(), - NTTP->getPosition(), 0, + NTTP->getPosition(), nullptr, T, TInfo, ExpandedTypes.data(), @@ -626,7 +639,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( SourceLocation(), SourceLocation(), NTTP->getDepth(), - NTTP->getPosition(), 0, + NTTP->getPosition(), nullptr, T, NTTP->isParameterPack(), TInfo); @@ -643,7 +656,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( SourceLocation(), TTP->getDepth(), TTP->getPosition(), TTP->isParameterPack(), - 0, + nullptr, TemplateParameterList::Create(*this, SourceLocation(), SourceLocation(), CanonParams.data(), @@ -652,7 +665,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( // Get the new insert position for the node we care about. Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); - assert(Canonical == 0 && "Shouldn't be in the map!"); + assert(!Canonical && "Shouldn't be in the map!"); (void)Canonical; // Create the canonical template template parameter entry. @@ -662,13 +675,13 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( } CXXABI *ASTContext::createCXXABI(const TargetInfo &T) { - if (!LangOpts.CPlusPlus) return 0; + if (!LangOpts.CPlusPlus) return nullptr; switch (T.getCXXABI().getKind()) { - case TargetCXXABI::GenericARM: + case TargetCXXABI::GenericARM: // Same as Itanium at this level case TargetCXXABI::iOS: - return CreateARMCXXABI(*this); - case TargetCXXABI::GenericAArch64: // Same as Itanium at this level + case TargetCXXABI::iOS64: + case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericItanium: return CreateItaniumCXXABI(*this); case TargetCXXABI::Microsoft: @@ -710,47 +723,40 @@ static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI, } ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM, - const TargetInfo *t, IdentifierTable &idents, SelectorTable &sels, - Builtin::Context &builtins, - unsigned size_reserve, - bool DelayInitialization) + Builtin::Context &builtins) : FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()), DependentTemplateSpecializationTypes(this_()), SubstTemplateTemplateParmPacks(this_()), - GlobalNestedNameSpecifier(0), - Int128Decl(0), UInt128Decl(0), Float128StubDecl(0), - BuiltinVaListDecl(0), - ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0), - BOOLDecl(0), - CFConstantStringTypeDecl(0), ObjCInstanceTypeDecl(0), - FILEDecl(0), - jmp_bufDecl(0), sigjmp_bufDecl(0), ucontext_tDecl(0), - BlockDescriptorType(0), BlockDescriptorExtendedType(0), - cudaConfigureCallDecl(0), + GlobalNestedNameSpecifier(nullptr), + Int128Decl(nullptr), UInt128Decl(nullptr), Float128StubDecl(nullptr), + BuiltinVaListDecl(nullptr), + ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr), + ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr), + CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr), + FILEDecl(nullptr), + jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr), + BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr), + cudaConfigureCallDecl(nullptr), NullTypeSourceInfo(QualType()), FirstLocalImport(), LastLocalImport(), SourceMgr(SM), LangOpts(LOpts), - AddrSpaceMap(0), Target(t), PrintingPolicy(LOpts), + AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), BuiltinInfo(builtins), DeclarationNames(*this), - ExternalSource(0), Listener(0), + ExternalSource(nullptr), Listener(nullptr), Comments(SM), CommentsLoaded(false), CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), - LastSDM(0, 0) + LastSDM(nullptr, 0) { - if (size_reserve > 0) Types.reserve(size_reserve); TUDecl = TranslationUnitDecl::Create(*this); - - if (!DelayInitialization) { - assert(t && "No target supplied for ASTContext initialization"); - InitBuiltinTypes(*t); - } } ASTContext::~ASTContext() { + ReleaseParentMapEntries(); + // Release the DenseMaps associated with DeclContext objects. // FIXME: Is this the ideal solution? ReleaseDeclContextMaps(); @@ -782,11 +788,19 @@ ASTContext::~ASTContext() { A != AEnd; ++A) A->second->~AttrVec(); - for (llvm::DenseMap<const DeclContext *, MangleNumberingContext *>::iterator - I = MangleNumberingContexts.begin(), - E = MangleNumberingContexts.end(); - I != E; ++I) - delete I->second; + llvm::DeleteContainerSeconds(MangleNumberingContexts); +} + +void ASTContext::ReleaseParentMapEntries() { + if (!AllParents) return; + for (const auto &Entry : *AllParents) { + if (Entry.second.is<ast_type_traits::DynTypedNode *>()) { + delete Entry.second.get<ast_type_traits::DynTypedNode *>(); + } else { + assert(Entry.second.is<ParentVector *>()); + delete Entry.second.get<ParentVector *>(); + } + } } void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { @@ -794,8 +808,8 @@ void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) { } void -ASTContext::setExternalSource(OwningPtr<ExternalASTSource> &Source) { - ExternalSource.reset(Source.take()); +ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) { + ExternalSource = Source; } void ASTContext::PrintStats() const { @@ -849,7 +863,7 @@ void ASTContext::PrintStats() const { << NumImplicitDestructors << " implicit destructors created\n"; - if (ExternalSource.get()) { + if (ExternalSource) { llvm::errs() << "\n"; ExternalSource->PrintStats(); } @@ -857,45 +871,47 @@ void ASTContext::PrintStats() const { BumpAlloc.PrintStats(); } +RecordDecl *ASTContext::buildImplicitRecord(StringRef Name, + RecordDecl::TagKind TK) const { + SourceLocation Loc; + RecordDecl *NewDecl; + if (getLangOpts().CPlusPlus) + NewDecl = CXXRecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, + Loc, &Idents.get(Name)); + else + NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc, + &Idents.get(Name)); + NewDecl->setImplicit(); + return NewDecl; +} + +TypedefDecl *ASTContext::buildImplicitTypedef(QualType T, + StringRef Name) const { + TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T); + TypedefDecl *NewDecl = TypedefDecl::Create( + const_cast<ASTContext &>(*this), getTranslationUnitDecl(), + SourceLocation(), SourceLocation(), &Idents.get(Name), TInfo); + NewDecl->setImplicit(); + return NewDecl; +} + TypedefDecl *ASTContext::getInt128Decl() const { - if (!Int128Decl) { - TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(Int128Ty); - Int128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this), - getTranslationUnitDecl(), - SourceLocation(), - SourceLocation(), - &Idents.get("__int128_t"), - TInfo); - } - + if (!Int128Decl) + Int128Decl = buildImplicitTypedef(Int128Ty, "__int128_t"); return Int128Decl; } TypedefDecl *ASTContext::getUInt128Decl() const { - if (!UInt128Decl) { - TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(UnsignedInt128Ty); - UInt128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this), - getTranslationUnitDecl(), - SourceLocation(), - SourceLocation(), - &Idents.get("__uint128_t"), - TInfo); - } - + if (!UInt128Decl) + UInt128Decl = buildImplicitTypedef(UnsignedInt128Ty, "__uint128_t"); return UInt128Decl; } TypeDecl *ASTContext::getFloat128StubType() const { assert(LangOpts.CPlusPlus && "should only be called for c++"); - if (!Float128StubDecl) { - Float128StubDecl = CXXRecordDecl::Create(const_cast<ASTContext &>(*this), - TTK_Struct, - getTranslationUnitDecl(), - SourceLocation(), - SourceLocation(), - &Idents.get("__float128")); - } - + if (!Float128StubDecl) + Float128StubDecl = buildImplicitRecord("__float128"); + return Float128StubDecl; } @@ -1106,7 +1122,7 @@ FunctionDecl *ASTContext::getClassScopeSpecializationPattern( llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos = ClassScopeSpecializationPattern.find(FD); if (Pos == ClassScopeSpecializationPattern.end()) - return 0; + return nullptr; return Pos->second; } @@ -1123,7 +1139,7 @@ ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) { llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos = InstantiatedFromUsingDecl.find(UUD); if (Pos == InstantiatedFromUsingDecl.end()) - return 0; + return nullptr; return Pos->second; } @@ -1143,7 +1159,7 @@ ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) { llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos = InstantiatedFromUsingShadowDecl.find(Inst); if (Pos == InstantiatedFromUsingShadowDecl.end()) - return 0; + return nullptr; return Pos->second; } @@ -1159,7 +1175,7 @@ FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) { llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos = InstantiatedFromUnnamedFieldDecl.find(Field); if (Pos == InstantiatedFromUnnamedFieldDecl.end()) - return 0; + return nullptr; return Pos->second; } @@ -1179,7 +1195,7 @@ ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) - return 0; + return nullptr; return Pos->second.begin(); } @@ -1189,7 +1205,7 @@ ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const { llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos = OverriddenMethods.find(Method->getCanonicalDecl()); if (Pos == OverriddenMethods.end()) - return 0; + return nullptr; return Pos->second.end(); } @@ -1293,13 +1309,14 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { QualType T = VD->getType(); - if (const ReferenceType* RT = T->getAs<ReferenceType>()) { + if (const ReferenceType *RT = T->getAs<ReferenceType>()) { if (ForAlignof) T = RT->getPointeeType(); else T = getPointerType(RT->getPointeeType()); } - if (!T->isIncompleteType() && !T->isFunctionType()) { + QualType BaseT = getBaseElementType(T); + if (!BaseT->isIncompleteType() && !T->isFunctionType()) { // Adjust alignments of declarations with array type by the // large-array alignment on the target. if (const ArrayType *arrayType = getAsArrayType(T)) { @@ -1311,9 +1328,6 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType))) Align = std::max(Align, Target->getLargeArrayAlign()); } - - // Walk through any array types while we're at it. - T = getBaseElementType(arrayType); } Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { @@ -1618,7 +1632,7 @@ ASTContext::getTypeInfoImpl(const Type *T) const { } case Type::MemberPointer: { const MemberPointerType *MPT = cast<MemberPointerType>(T); - llvm::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT); + std::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT); break; } case Type::Complex: { @@ -1632,8 +1646,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const { } case Type::ObjCObject: return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr()); + case Type::Adjusted: case Type::Decayed: - return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr()); + return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr()); case Type::ObjCInterface: { const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T); const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); @@ -1761,13 +1776,19 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const { if (Target->getTriple().getArch() == llvm::Triple::xcore) return ABIAlign; // Never overalign on XCore. + const TypedefType *TT = T->getAs<TypedefType>(); + // Double and long long should be naturally aligned if possible. - if (const ComplexType* CT = T->getAs<ComplexType>()) + T = T->getBaseElementTypeUnsafe(); + if (const ComplexType *CT = T->getAs<ComplexType>()) T = CT->getElementType().getTypePtr(); if (T->isSpecificBuiltinType(BuiltinType::Double) || T->isSpecificBuiltinType(BuiltinType::LongLong) || T->isSpecificBuiltinType(BuiltinType::ULongLong)) - return std::max(ABIAlign, (unsigned)getTypeSize(T)); + // Don't increase the alignment if an alignment attribute was specified on a + // typedef declaration. + if (!TT || !TT->getDecl()->getMaxAlignment()) + return std::max(ABIAlign, (unsigned)getTypeSize(T)); return ABIAlign; } @@ -1796,9 +1817,8 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass()) DeepCollectObjCIvars(SuperClass, false, Ivars); if (!leafClass) { - for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(), - E = OI->ivar_end(); I != E; ++I) - Ivars.push_back(*I); + 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; @@ -1814,24 +1834,17 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl, if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) { // We can use protocol_iterator here instead of // all_referenced_protocol_iterator since we are walking all categories. - for (ObjCInterfaceDecl::all_protocol_iterator P = OI->all_referenced_protocol_begin(), - PE = OI->all_referenced_protocol_end(); P != PE; ++P) { - ObjCProtocolDecl *Proto = (*P); + for (auto *Proto : OI->all_referenced_protocols()) { Protocols.insert(Proto->getCanonicalDecl()); - for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), - PE = Proto->protocol_end(); P != PE; ++P) { - Protocols.insert((*P)->getCanonicalDecl()); - CollectInheritedProtocols(*P, Protocols); + for (auto *P : Proto->protocols()) { + Protocols.insert(P->getCanonicalDecl()); + CollectInheritedProtocols(P, Protocols); } } // Categories of this Interface. - for (ObjCInterfaceDecl::visible_categories_iterator - Cat = OI->visible_categories_begin(), - CatEnd = OI->visible_categories_end(); - Cat != CatEnd; ++Cat) { - CollectInheritedProtocols(*Cat, Protocols); - } + for (const auto *Cat : OI->visible_categories()) + CollectInheritedProtocols(Cat, Protocols); if (ObjCInterfaceDecl *SD = OI->getSuperClass()) while (SD) { @@ -1839,22 +1852,16 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl, SD = SD->getSuperClass(); } } else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) { - for (ObjCCategoryDecl::protocol_iterator P = OC->protocol_begin(), - PE = OC->protocol_end(); P != PE; ++P) { - ObjCProtocolDecl *Proto = (*P); + for (auto *Proto : OC->protocols()) { Protocols.insert(Proto->getCanonicalDecl()); - for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), - PE = Proto->protocol_end(); P != PE; ++P) - CollectInheritedProtocols(*P, Protocols); + for (const auto *P : Proto->protocols()) + CollectInheritedProtocols(P, Protocols); } } else if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) { - for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(), - PE = OP->protocol_end(); P != PE; ++P) { - ObjCProtocolDecl *Proto = (*P); + for (auto *Proto : OP->protocols()) { Protocols.insert(Proto->getCanonicalDecl()); - for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(), - PE = Proto->protocol_end(); P != PE; ++P) - CollectInheritedProtocols(*P, Protocols); + for (const auto *P : Proto->protocols()) + CollectInheritedProtocols(P, Protocols); } } } @@ -1862,12 +1869,8 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl, unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const { unsigned count = 0; // Count ivars declared in class extension. - for (ObjCInterfaceDecl::known_extensions_iterator - Ext = OI->known_extensions_begin(), - ExtEnd = OI->known_extensions_end(); - Ext != ExtEnd; ++Ext) { + for (const auto *Ext : OI->known_extensions()) count += Ext->ivar_size(); - } // Count ivar defined in this class's implementation. This // includes synthesized ivars. @@ -1901,7 +1904,7 @@ ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) I = ObjCImpls.find(D); if (I != ObjCImpls.end()) return cast<ObjCImplementationDecl>(I->second); - return 0; + return nullptr; } /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) { @@ -1909,7 +1912,7 @@ ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) { I = ObjCImpls.find(D); if (I != ObjCImpls.end()) return cast<ObjCCategoryImplDecl>(I->second); - return 0; + return nullptr; } /// \brief Set the implementation of ObjCInterfaceDecl. @@ -1937,7 +1940,7 @@ const ObjCInterfaceDecl *ASTContext::getObjContainingInterface( dyn_cast<ObjCImplDecl>(ND->getDeclContext())) return IMD->getClassInterface(); - return 0; + return nullptr; } /// \brief Get the copy initialization expression of VarDecl,or NULL if @@ -1948,7 +1951,7 @@ Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) { "getBlockVarCopyInits - not __block var"); llvm::DenseMap<const VarDecl*, Expr*>::iterator I = BlockVarCopyInits.find(VD); - return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : 0; + return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : nullptr; } /// \brief Set the copy inialization expression of a block var decl. @@ -1982,7 +1985,7 @@ TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T, const ASTRecordLayout & ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const { - return getObjCLayout(D, 0); + return getObjCLayout(D, nullptr); } const ASTRecordLayout & @@ -2003,7 +2006,7 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const { // Check if we've already instantiated this type. llvm::FoldingSetNodeID ID; ExtQuals::Profile(ID, baseType, quals); - void *insertPos = 0; + void *insertPos = nullptr; if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) { assert(eq->getQualifiers() == quals); return QualType(eq, fastQuals); @@ -2080,12 +2083,12 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T, QualType Result; if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(T)) { - Result = getFunctionNoProtoType(FNPT->getResultType(), Info); + Result = getFunctionNoProtoType(FNPT->getReturnType(), Info); } else { const FunctionProtoType *FPT = cast<FunctionProtoType>(T); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.ExtInfo = Info; - Result = getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI); + Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI); } return cast<FunctionType>(Result.getTypePtr()); @@ -2097,7 +2100,7 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD, while (true) { const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - FD->setType(getFunctionType(ResultType, FPT->getArgTypes(), EPI)); + FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI)); if (FunctionDecl *Next = FD->getPreviousDecl()) FD = Next; else @@ -2115,7 +2118,7 @@ QualType ASTContext::getComplexType(QualType T) const { llvm::FoldingSetNodeID ID; ComplexType::Profile(ID, T); - void *InsertPos = 0; + void *InsertPos = nullptr; if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(CT, 0); @@ -2127,7 +2130,7 @@ QualType ASTContext::getComplexType(QualType T) const { // Get the new insert position for the node we care about. ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical); Types.push_back(New); @@ -2143,7 +2146,7 @@ QualType ASTContext::getPointerType(QualType T) const { llvm::FoldingSetNodeID ID; PointerType::Profile(ID, T); - void *InsertPos = 0; + void *InsertPos = nullptr; if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(PT, 0); @@ -2155,7 +2158,7 @@ QualType ASTContext::getPointerType(QualType T) const { // Get the new insert position for the node we care about. PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical); Types.push_back(New); @@ -2163,15 +2166,30 @@ QualType ASTContext::getPointerType(QualType T) const { return QualType(New, 0); } +QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const { + llvm::FoldingSetNodeID ID; + AdjustedType::Profile(ID, Orig, New); + void *InsertPos = nullptr; + AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + if (AT) + return QualType(AT, 0); + + QualType Canonical = getCanonicalType(New); + + // Get the new insert position for the node we care about. + AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(!AT && "Shouldn't be in the map!"); + + AT = new (*this, TypeAlignment) + AdjustedType(Type::Adjusted, Orig, New, Canonical); + Types.push_back(AT); + AdjustedTypes.InsertNode(AT, InsertPos); + return QualType(AT, 0); +} + QualType ASTContext::getDecayedType(QualType T) const { assert((T->isArrayType() || T->isFunctionType()) && "T does not decay"); - llvm::FoldingSetNodeID ID; - DecayedType::Profile(ID, T); - void *InsertPos = 0; - if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(DT, 0); - QualType Decayed; // C99 6.7.5.3p7: @@ -2189,17 +2207,23 @@ QualType ASTContext::getDecayedType(QualType T) const { if (T->isFunctionType()) Decayed = getPointerType(T); + llvm::FoldingSetNodeID ID; + AdjustedType::Profile(ID, T, Decayed); + void *InsertPos = nullptr; + AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + if (AT) + return QualType(AT, 0); + QualType Canonical = getCanonicalType(Decayed); // Get the new insert position for the node we care about. - DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(!AT && "Shouldn't be in the map!"); - DecayedType *New = - new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); - Types.push_back(New); - DecayedTypes.InsertNode(New, InsertPos); - return QualType(New, 0); + AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); + Types.push_back(AT); + AdjustedTypes.InsertNode(AT, InsertPos); + return QualType(AT, 0); } /// getBlockPointerType - Return the uniqued reference to the type for @@ -2211,7 +2235,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const { llvm::FoldingSetNodeID ID; BlockPointerType::Profile(ID, T); - void *InsertPos = 0; + void *InsertPos = nullptr; if (BlockPointerType *PT = BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(PT, 0); @@ -2225,7 +2249,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const { // Get the new insert position for the node we care about. BlockPointerType *NewIP = BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } BlockPointerType *New = new (*this, TypeAlignment) BlockPointerType(T, Canonical); @@ -2246,7 +2270,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const { llvm::FoldingSetNodeID ID; ReferenceType::Profile(ID, T, SpelledAsLValue); - void *InsertPos = 0; + void *InsertPos = nullptr; if (LValueReferenceType *RT = LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(RT, 0); @@ -2263,7 +2287,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const { // Get the new insert position for the node we care about. LValueReferenceType *NewIP = LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } LValueReferenceType *New @@ -2283,7 +2307,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const { llvm::FoldingSetNodeID ID; ReferenceType::Profile(ID, T, false); - void *InsertPos = 0; + void *InsertPos = nullptr; if (RValueReferenceType *RT = RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(RT, 0); @@ -2300,7 +2324,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const { // Get the new insert position for the node we care about. RValueReferenceType *NewIP = RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } RValueReferenceType *New @@ -2318,7 +2342,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const { llvm::FoldingSetNodeID ID; MemberPointerType::Profile(ID, T, Cls); - void *InsertPos = 0; + void *InsertPos = nullptr; if (MemberPointerType *PT = MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(PT, 0); @@ -2332,7 +2356,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const { // Get the new insert position for the node we care about. MemberPointerType *NewIP = MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } MemberPointerType *New = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical); @@ -2360,7 +2384,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, llvm::FoldingSetNodeID ID; ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals); - void *InsertPos = 0; + void *InsertPos = nullptr; if (ConstantArrayType *ATP = ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(ATP, 0); @@ -2377,7 +2401,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, // Get the new insert position for the node we care about. ConstantArrayType *NewIP = ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } ConstantArrayType *New = new(*this,TypeAlignment) @@ -2495,7 +2519,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { const IncompleteArrayType *iat = cast<IncompleteArrayType>(ty); result = getVariableArrayType( getVariableArrayDecayedType(iat->getElementType()), - /*size*/ 0, + /*size*/ nullptr, ArrayType::Normal, iat->getIndexTypeCVRQualifiers(), SourceRange()); @@ -2507,7 +2531,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { const VariableArrayType *vat = cast<VariableArrayType>(ty); result = getVariableArrayType( getVariableArrayDecayedType(vat->getElementType()), - /*size*/ 0, + /*size*/ nullptr, ArrayType::Star, vat->getIndexTypeCVRQualifiers(), vat->getBracketsRange()); @@ -2577,7 +2601,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType, SplitQualType canonElementType = getCanonicalType(elementType).split(); - void *insertPos = 0; + void *insertPos = nullptr; llvm::FoldingSetNodeID ID; DependentSizedArrayType::Profile(ID, *this, QualType(canonElementType.Ty, 0), @@ -2622,7 +2646,7 @@ QualType ASTContext::getIncompleteArrayType(QualType elementType, llvm::FoldingSetNodeID ID; IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals); - void *insertPos = 0; + void *insertPos = nullptr; if (IncompleteArrayType *iat = IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos)) return QualType(iat, 0); @@ -2662,7 +2686,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, llvm::FoldingSetNodeID ID; VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind); - void *InsertPos = 0; + void *InsertPos = nullptr; if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(VTP, 0); @@ -2674,7 +2698,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts, // Get the new insert position for the node we care about. VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } VectorType *New = new (*this, TypeAlignment) VectorType(vecType, NumElts, Canonical, VecKind); @@ -2693,7 +2717,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const { llvm::FoldingSetNodeID ID; VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, VectorType::GenericVector); - void *InsertPos = 0; + void *InsertPos = nullptr; if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(VTP, 0); @@ -2705,7 +2729,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const { // Get the new insert position for the node we care about. VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } ExtVectorType *New = new (*this, TypeAlignment) ExtVectorType(vecType, NumElts, Canonical); @@ -2722,7 +2746,7 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType, DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType), SizeExpr); - void *InsertPos = 0; + void *InsertPos = nullptr; DependentSizedExtVectorType *Canon = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos); DependentSizedExtVectorType *New; @@ -2768,7 +2792,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy, llvm::FoldingSetNodeID ID; FunctionNoProtoType::Profile(ID, ResultTy, Info); - void *InsertPos = 0; + void *InsertPos = nullptr; if (FunctionNoProtoType *FT = FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(FT, 0); @@ -2780,7 +2804,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy, // Get the new insert position for the node we care about. FunctionNoProtoType *NewIP = FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv); @@ -2798,8 +2822,6 @@ static bool isCanonicalResultType(QualType T) { T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone); } -/// getFunctionType - Return a normal function type with a typed argument -/// list. isVariadic indicates whether the argument list includes '...'. QualType ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, const FunctionProtoType::ExtProtoInfo &EPI) const { @@ -2811,7 +2833,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI, *this); - void *InsertPos = 0; + void *InsertPos = nullptr; if (FunctionProtoType *FTP = FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(FTP, 0); @@ -2851,7 +2873,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, // Get the new insert position for the node we care about. FunctionProtoType *NewIP = FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } // FunctionProtoType objects are allocated with extra bytes after @@ -2873,7 +2895,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray, } else if (EPI.ExceptionSpecType == EST_Unevaluated) { Size += sizeof(FunctionDecl*); } - if (EPI.ConsumedArguments) + if (EPI.ConsumedParameters) Size += NumArgs * sizeof(bool); FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment); @@ -2995,7 +3017,7 @@ QualType ASTContext::getAttributedType(AttributedType::Kind attrKind, llvm::FoldingSetNodeID id; AttributedType::Profile(id, attrKind, modifiedType, equivalentType); - void *insertPos = 0; + void *insertPos = nullptr; AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos); if (type) return QualType(type, 0); @@ -3019,7 +3041,7 @@ ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, llvm::FoldingSetNodeID ID; SubstTemplateTypeParmType::Profile(ID, Parm, Replacement); - void *InsertPos = 0; + void *InsertPos = nullptr; SubstTemplateTypeParmType *SubstParm = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -3038,17 +3060,15 @@ QualType ASTContext::getSubstTemplateTypeParmPackType( const TemplateTypeParmType *Parm, const TemplateArgument &ArgPack) { #ifndef NDEBUG - for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(), - PEnd = ArgPack.pack_end(); - P != PEnd; ++P) { - assert(P->getKind() == TemplateArgument::Type &&"Pack contains a non-type"); - assert(P->getAsType().isCanonical() && "Pack contains non-canonical type"); + for (const auto &P : ArgPack.pack_elements()) { + assert(P.getKind() == TemplateArgument::Type &&"Pack contains a non-type"); + assert(P.getAsType().isCanonical() && "Pack contains non-canonical type"); } #endif llvm::FoldingSetNodeID ID; SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack); - void *InsertPos = 0; + void *InsertPos = nullptr; if (SubstTemplateTypeParmPackType *SubstParm = SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(SubstParm, 0); @@ -3077,7 +3097,7 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, TemplateTypeParmDecl *TTPDecl) const { llvm::FoldingSetNodeID ID; TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl); - void *InsertPos = 0; + void *InsertPos = nullptr; TemplateTypeParmType *TypeParm = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -3218,7 +3238,7 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, TemplateSpecializationType::Profile(ID, CanonTemplate, CanonArgs.data(), NumArgs, *this); - void *InsertPos = 0; + void *InsertPos = nullptr; TemplateSpecializationType *Spec = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -3246,7 +3266,7 @@ ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword, llvm::FoldingSetNodeID ID; ElaboratedType::Profile(ID, Keyword, NNS, NamedType); - void *InsertPos = 0; + void *InsertPos = nullptr; ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); if (T) return QualType(T, 0); @@ -3270,7 +3290,7 @@ ASTContext::getParenType(QualType InnerType) const { llvm::FoldingSetNodeID ID; ParenType::Profile(ID, InnerType); - void *InsertPos = 0; + void *InsertPos = nullptr; ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos); if (T) return QualType(T, 0); @@ -3293,8 +3313,6 @@ QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType Canon) const { - assert(NNS->isDependent() && "nested-name-specifier must be dependent"); - if (Canon.isNull()) { NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS); ElaboratedTypeKeyword CanonKeyword = Keyword; @@ -3308,7 +3326,7 @@ QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword, llvm::FoldingSetNodeID ID; DependentNameType::Profile(ID, Keyword, NNS, Name); - void *InsertPos = 0; + void *InsertPos = nullptr; DependentNameType *T = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos); if (T) @@ -3349,7 +3367,7 @@ ASTContext::getDependentTemplateSpecializationType( DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS, Name, NumArgs, Args); - void *InsertPos = 0; + void *InsertPos = nullptr; DependentTemplateSpecializationType *T = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos); if (T) @@ -3395,7 +3413,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern, assert(Pattern->containsUnexpandedParameterPack() && "Pack expansions must expand one or more parameter packs"); - void *InsertPos = 0; + void *InsertPos = nullptr; PackExpansionType *T = PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); if (T) @@ -3408,7 +3426,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern, // contains an alias template specialization which ignores one of its // parameters. if (Canon->containsUnexpandedParameterPack()) { - Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions); + Canon = getPackExpansionType(Canon, NumExpansions); // Find the insert position again, in case we inserted an element into // PackExpansionTypes and invalidated our insert position. @@ -3419,7 +3437,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern, T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions); Types.push_back(T); PackExpansionTypes.InsertNode(T, InsertPos); - return QualType(T, 0); + return QualType(T, 0); } /// CmpProtocolNames - Comparison predicate for sorting protocols @@ -3470,7 +3488,7 @@ QualType ASTContext::getObjCObjectType(QualType BaseType, // Look in the folding set for an existing type. llvm::FoldingSetNodeID ID; ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols); - void *InsertPos = 0; + void *InsertPos = nullptr; if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(QT, 0); @@ -3507,13 +3525,79 @@ QualType ASTContext::getObjCObjectType(QualType BaseType, return QualType(T, 0); } +/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's +/// protocol list adopt all protocols in QT's qualified-id protocol +/// list. +bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT, + ObjCInterfaceDecl *IC) { + if (!QT->isObjCQualifiedIdType()) + return false; + + if (const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>()) { + // If both the right and left sides have qualifiers. + for (auto *Proto : OPT->quals()) { + if (!IC->ClassImplementsProtocol(Proto, false)) + return false; + } + return true; + } + return false; +} + +/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in +/// QT's qualified-id protocol list adopt all protocols in IDecl's list +/// of protocols. +bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT, + ObjCInterfaceDecl *IDecl) { + if (!QT->isObjCQualifiedIdType()) + return false; + const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>(); + if (!OPT) + return false; + if (!IDecl->hasDefinition()) + return false; + llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocols; + CollectInheritedProtocols(IDecl, InheritedProtocols); + if (InheritedProtocols.empty()) + return false; + // Check that if every protocol in list of id<plist> conforms to a protcol + // of IDecl's, then bridge casting is ok. + bool Conforms = false; + for (auto *Proto : OPT->quals()) { + Conforms = false; + for (auto *PI : InheritedProtocols) { + if (ProtocolCompatibleWithProtocol(Proto, PI)) { + Conforms = true; + break; + } + } + if (!Conforms) + break; + } + if (Conforms) + return true; + + for (auto *PI : InheritedProtocols) { + // If both the right and left sides have qualifiers. + bool Adopts = false; + for (auto *Proto : OPT->quals()) { + // return 'true' if 'PI' is in the inheritance hierarchy of Proto + if ((Adopts = ProtocolCompatibleWithProtocol(PI, Proto))) + break; + } + if (!Adopts) + return false; + } + return true; +} + /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for /// the given object type. QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const { llvm::FoldingSetNodeID ID; ObjCObjectPointerType::Profile(ID, ObjectT); - void *InsertPos = 0; + void *InsertPos = nullptr; if (ObjCObjectPointerType *QT = ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(QT, 0); @@ -3572,7 +3656,7 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const { llvm::FoldingSetNodeID ID; DependentTypeOfExprType::Profile(ID, *this, tofExpr); - void *InsertPos = 0; + void *InsertPos = nullptr; DependentTypeOfExprType *Canon = DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos); if (Canon) { @@ -3596,10 +3680,10 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const { } /// getTypeOfType - Unlike many "get<Type>" functions, we don't unique -/// TypeOfType AST's. The only motivation to unique these nodes would be +/// TypeOfType nodes. The only motivation to unique these nodes would be /// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be -/// an issue. This doesn't effect the type checker, since it operates -/// on canonical type's (which are always unique). +/// an issue. This doesn't affect the type checker, since it operates +/// 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); @@ -3608,39 +3692,34 @@ QualType ASTContext::getTypeOfType(QualType tofType) const { } -/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique -/// DecltypeType AST's. The only motivation to unique these nodes would be -/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be -/// an issue. This doesn't effect the type checker, since it operates -/// on canonical types (which are always unique). +/// \brief 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. QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const { DecltypeType *dt; - - // C++0x [temp.type]p2: + + // C++11 [temp.type]p2: // If an expression e involves a template parameter, decltype(e) denotes a - // unique dependent type. Two such decltype-specifiers refer to the same - // type only if their expressions are equivalent (14.5.6.1). + // unique dependent type. Two such decltype-specifiers refer to the same + // type only if their expressions are equivalent (14.5.6.1). if (e->isInstantiationDependent()) { llvm::FoldingSetNodeID ID; DependentDecltypeType::Profile(ID, *this, e); - void *InsertPos = 0; + void *InsertPos = nullptr; DependentDecltypeType *Canon = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos); - if (Canon) { - // We already have a "canonical" version of an equivalent, dependent - // decltype type. Use that as our canonical type. - dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, - QualType((DecltypeType*)Canon, 0)); - } else { + if (!Canon) { // Build a new, canonical typeof(expr) type. Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e); DependentDecltypeTypes.InsertNode(Canon, InsertPos); - dt = Canon; } + dt = new (*this, TypeAlignment) + DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0)); } else { - dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, - getCanonicalType(UnderlyingType)); + dt = new (*this, TypeAlignment) + DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType)); } Types.push_back(dt); return QualType(dt, 0); @@ -3670,7 +3749,7 @@ QualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto, return getAutoDeductType(); // Look in the folding set for an existing type. - void *InsertPos = 0; + void *InsertPos = nullptr; llvm::FoldingSetNodeID ID; AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent); if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos)) @@ -3693,7 +3772,7 @@ QualType ASTContext::getAtomicType(QualType T) const { llvm::FoldingSetNodeID ID; AtomicType::Profile(ID, T); - void *InsertPos = 0; + void *InsertPos = nullptr; if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(AT, 0); @@ -3705,7 +3784,7 @@ QualType ASTContext::getAtomicType(QualType T) const { // Get the new insert position for the node we care about. AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; + assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical); Types.push_back(New); @@ -4064,7 +4143,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { NestedNameSpecifier * ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { if (!NNS) - return 0; + return nullptr; switch (NNS->getKind()) { case NestedNameSpecifier::Identifier: @@ -4076,13 +4155,13 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { case NestedNameSpecifier::Namespace: // A namespace is canonical; build a nested-name-specifier with // this namespace and no prefix. - return NestedNameSpecifier::Create(*this, 0, + return NestedNameSpecifier::Create(*this, nullptr, NNS->getAsNamespace()->getOriginalNamespace()); case NestedNameSpecifier::NamespaceAlias: // A namespace is canonical; build a nested-name-specifier with // this namespace and no prefix. - return NestedNameSpecifier::Create(*this, 0, + return NestedNameSpecifier::Create(*this, nullptr, NNS->getAsNamespaceAlias()->getNamespace() ->getOriginalNamespace()); @@ -4104,8 +4183,8 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const { // Otherwise, just canonicalize the type, and force it to be a TypeSpec. // FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the // first place? - return NestedNameSpecifier::Create(*this, 0, false, - const_cast<Type*>(T.getTypePtr())); + return NestedNameSpecifier::Create(*this, nullptr, false, + const_cast<Type *>(T.getTypePtr())); } case NestedNameSpecifier::Global: @@ -4127,7 +4206,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const { // Handle the common negative case fast. if (!isa<ArrayType>(T.getCanonicalType())) - return 0; + return nullptr; // Apply any qualifiers from the array type to the element type. This // implements C99 6.7.3p8: "If the specification of an array type includes @@ -4142,7 +4221,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const { // If we have a simple case, just return now. const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty); - if (ATy == 0 || qs.empty()) + if (!ATy || qs.empty()) return ATy; // Otherwise, we have an array and we have qualifiers on it. Push the @@ -4428,7 +4507,7 @@ static const Type *getIntegerTypeForEnum(const EnumType *ET) { // FIXME: In C++, enum types are never integer types. if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped()) return ET->getDecl()->getIntegerType().getTypePtr(); - return NULL; + return nullptr; } /// getIntegerTypeOrder - Returns the highest ranked integer type: @@ -4479,22 +4558,10 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const { return 1; } -static RecordDecl * -CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK, - DeclContext *DC, IdentifierInfo *Id) { - SourceLocation Loc; - if (Ctx.getLangOpts().CPlusPlus) - return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); - else - return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); -} - // getCFConstantStringType - Return the type used for constant CFStrings. QualType ASTContext::getCFConstantStringType() const { if (!CFConstantStringTypeDecl) { - CFConstantStringTypeDecl = - CreateRecordDecl(*this, TTK_Struct, TUDecl, - &Idents.get("NSConstantString")); + CFConstantStringTypeDecl = buildImplicitRecord("NSConstantString"); CFConstantStringTypeDecl->startDefinition(); QualType FieldTypes[4]; @@ -4512,9 +4579,9 @@ QualType ASTContext::getCFConstantStringType() const { for (unsigned i = 0; i < 4; ++i) { FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl, SourceLocation(), - SourceLocation(), 0, - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, + SourceLocation(), nullptr, + FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); @@ -4529,8 +4596,7 @@ QualType ASTContext::getCFConstantStringType() const { QualType ASTContext::getObjCSuperType() const { if (ObjCSuperType.isNull()) { - RecordDecl *ObjCSuperTypeDecl = - CreateRecordDecl(*this, TTK_Struct, TUDecl, &Idents.get("objc_super")); + RecordDecl *ObjCSuperTypeDecl = buildImplicitRecord("objc_super"); TUDecl->addDecl(ObjCSuperTypeDecl); ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl); } @@ -4547,12 +4613,11 @@ QualType ASTContext::getBlockDescriptorType() const { if (BlockDescriptorType) return getTagDeclType(BlockDescriptorType); - RecordDecl *T; + RecordDecl *RD; // FIXME: Needs the FlagAppleBlock bit. - T = CreateRecordDecl(*this, TTK_Struct, TUDecl, - &Idents.get("__block_descriptor")); - T->startDefinition(); - + RD = buildImplicitRecord("__block_descriptor"); + RD->startDefinition(); + QualType FieldTypes[] = { UnsignedLongTy, UnsignedLongTy, @@ -4564,20 +4629,17 @@ QualType ASTContext::getBlockDescriptorType() const { }; for (size_t i = 0; i < 2; ++i) { - FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), - SourceLocation(), - &Idents.get(FieldNames[i]), - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, - /*Mutable=*/false, - ICIS_NoInit); + FieldDecl *Field = FieldDecl::Create( + *this, RD, SourceLocation(), SourceLocation(), + &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); - T->addDecl(Field); + RD->addDecl(Field); } - T->completeDefinition(); + RD->completeDefinition(); - BlockDescriptorType = T; + BlockDescriptorType = RD; return getTagDeclType(BlockDescriptorType); } @@ -4586,12 +4648,11 @@ QualType ASTContext::getBlockDescriptorExtendedType() const { if (BlockDescriptorExtendedType) return getTagDeclType(BlockDescriptorExtendedType); - RecordDecl *T; + RecordDecl *RD; // FIXME: Needs the FlagAppleBlock bit. - T = CreateRecordDecl(*this, TTK_Struct, TUDecl, - &Idents.get("__block_descriptor_withcopydispose")); - T->startDefinition(); - + RD = buildImplicitRecord("__block_descriptor_withcopydispose"); + RD->startDefinition(); + QualType FieldTypes[] = { UnsignedLongTy, UnsignedLongTy, @@ -4607,21 +4668,18 @@ QualType ASTContext::getBlockDescriptorExtendedType() const { }; for (size_t i = 0; i < 4; ++i) { - FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), - SourceLocation(), - &Idents.get(FieldNames[i]), - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, - /*Mutable=*/false, - ICIS_NoInit); + FieldDecl *Field = FieldDecl::Create( + *this, RD, SourceLocation(), SourceLocation(), + &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, + /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); - T->addDecl(Field); + RD->addDecl(Field); } - T->completeDefinition(); - - BlockDescriptorExtendedType = T; + RD->completeDefinition(); + BlockDescriptorExtendedType = RD; return getTagDeclType(BlockDescriptorExtendedType); } @@ -4691,12 +4749,8 @@ bool ASTContext::getByrefLifetime(QualType Ty, TypedefDecl *ASTContext::getObjCInstanceTypeDecl() { if (!ObjCInstanceTypeDecl) - ObjCInstanceTypeDecl = TypedefDecl::Create(*this, - getTranslationUnitDecl(), - SourceLocation(), - SourceLocation(), - &Idents.get("instancetype"), - getTrivialTypeSourceInfo(getObjCIdType())); + ObjCInstanceTypeDecl = + buildImplicitTypedef(getObjCIdType(), "instancetype"); return ObjCInstanceTypeDecl; } @@ -4727,6 +4781,12 @@ CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const { return sz; } +bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const { + return getLangOpts().MSVCCompat && VD->isStaticDataMember() && + VD->getType()->isIntegralOrEnumerationType() && + !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit(); +} + static inline std::string charUnitsToString(const CharUnits &CU) { return llvm::itostr(CU.getQuantity()); @@ -4742,21 +4802,19 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { Expr->getType()->getAs<BlockPointerType>()->getPointeeType(); // Encode result type. if (getLangOpts().EncodeExtendedBlockSig) - getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, - BlockTy->getAs<FunctionType>()->getResultType(), - S, true /*Extended*/); + getObjCEncodingForMethodParameter( + Decl::OBJC_TQ_None, BlockTy->getAs<FunctionType>()->getReturnType(), S, + true /*Extended*/); else - getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getResultType(), - S); + getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getReturnType(), S); // Compute size of all parameters. // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! SourceLocation Loc; CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); CharUnits ParmOffset = PtrSize; - for (BlockDecl::param_const_iterator PI = Decl->param_begin(), - E = Decl->param_end(); PI != E; ++PI) { - QualType PType = (*PI)->getType(); + for (auto PI : Decl->params()) { + QualType PType = PI->getType(); CharUnits sz = getObjCEncodingTypeSize(PType); if (sz.isZero()) continue; @@ -4770,9 +4828,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { // Argument types. ParmOffset = PtrSize; - for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E = - Decl->param_end(); PI != E; ++PI) { - ParmVarDecl *PVDecl = *PI; + for (auto PVDecl : Decl->params()) { QualType PType = PVDecl->getOriginalType(); if (const ArrayType *AT = dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { @@ -4797,12 +4853,11 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const { bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S) { // Encode result type. - getObjCEncodingForType(Decl->getResultType(), S); + getObjCEncodingForType(Decl->getReturnType(), S); CharUnits ParmOffset; // Compute size of all parameters. - for (FunctionDecl::param_const_iterator PI = Decl->param_begin(), - E = Decl->param_end(); PI != E; ++PI) { - QualType PType = (*PI)->getType(); + for (auto PI : Decl->params()) { + QualType PType = PI->getType(); CharUnits sz = getObjCEncodingTypeSize(PType); if (sz.isZero()) continue; @@ -4815,9 +4870,7 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, ParmOffset = CharUnits::Zero(); // Argument types. - for (FunctionDecl::param_const_iterator PI = Decl->param_begin(), - E = Decl->param_end(); PI != E; ++PI) { - ParmVarDecl *PVDecl = *PI; + for (auto PVDecl : Decl->params()) { QualType PType = PVDecl->getOriginalType(); if (const ArrayType *AT = dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { @@ -4844,7 +4897,7 @@ void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, // Encode type qualifer, 'in', 'inout', etc. for the parameter. getObjCEncodingForTypeQualifier(QT, S); // Encode parameter type. - getObjCEncodingForTypeImpl(T, S, true, true, 0, + getObjCEncodingForTypeImpl(T, S, true, true, nullptr, true /*OutermostType*/, false /*EncodingProperty*/, false /*StructField*/, @@ -4859,8 +4912,8 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended) const { // FIXME: This is not very efficient. // Encode return type. - getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(), - Decl->getResultType(), S, Extended); + getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(), + Decl->getReturnType(), S, Extended); // Compute size of all parameters. // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! @@ -4907,6 +4960,26 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, return false; } +ObjCPropertyImplDecl * +ASTContext::getObjCPropertyImplDeclForPropertyDecl( + const ObjCPropertyDecl *PD, + const Decl *Container) const { + if (!Container) + return nullptr; + if (const ObjCCategoryImplDecl *CID = + dyn_cast<ObjCCategoryImplDecl>(Container)) { + for (auto *PID : CID->property_impls()) + if (PID->getPropertyDecl() == PD) + return PID; + } else { + const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container); + for (auto *PID : OID->property_impls()) + if (PID->getPropertyDecl() == PD) + return PID; + } + return nullptr; +} + /// getObjCEncodingForPropertyDecl - Return the encoded type for this /// property declaration. If non-NULL, Container must be either an /// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be @@ -4937,39 +5010,14 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, std::string& S) const { // Collect information from the property implementation decl(s). bool Dynamic = false; - ObjCPropertyImplDecl *SynthesizePID = 0; - - // FIXME: Duplicated code due to poor abstraction. - if (Container) { - if (const ObjCCategoryImplDecl *CID = - dyn_cast<ObjCCategoryImplDecl>(Container)) { - for (ObjCCategoryImplDecl::propimpl_iterator - i = CID->propimpl_begin(), e = CID->propimpl_end(); - i != e; ++i) { - ObjCPropertyImplDecl *PID = *i; - if (PID->getPropertyDecl() == PD) { - if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) { - Dynamic = true; - } else { - SynthesizePID = PID; - } - } - } - } else { - const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container); - for (ObjCCategoryImplDecl::propimpl_iterator - i = OID->propimpl_begin(), e = OID->propimpl_end(); - i != e; ++i) { - ObjCPropertyImplDecl *PID = *i; - if (PID->getPropertyDecl() == PD) { - if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) { - Dynamic = true; - } else { - SynthesizePID = PID; - } - } - } - } + ObjCPropertyImplDecl *SynthesizePID = nullptr; + + if (ObjCPropertyImplDecl *PropertyImpDecl = + getObjCPropertyImplDeclForPropertyDecl(PD, Container)) { + if (PropertyImpDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) + Dynamic = true; + else + SynthesizePID = PropertyImpDecl; } // FIXME: This is not very efficient. @@ -4978,9 +5026,7 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, // Encode result type. // GCC has some special rules regarding encoding of properties which // closely resembles encoding of ivars. - getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0, - true /* outermost type */, - true /* encoding for property */); + getObjCEncodingForPropertyType(PD->getType(), S); if (PD->isReadOnly()) { S += ",R"; @@ -4988,6 +5034,8 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, S += ",C"; if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) S += ",&"; + if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak) + S += ",W"; } else { switch (PD->getSetterKind()) { case ObjCPropertyDecl::Assign: break; @@ -5051,6 +5099,16 @@ void ASTContext::getObjCEncodingForType(QualType T, std::string& S, true /* outermost type */); } +void ASTContext::getObjCEncodingForPropertyType(QualType T, + std::string& S) const { + // Encode result type. + // GCC has some special rules regarding encoding of properties which + // closely resembles encoding of ivars. + getObjCEncodingForTypeImpl(T, S, true, true, nullptr, + true /* outermost type */, + true /* encoding property */); +} + static char getObjCEncodingForPrimitiveKind(const ASTContext *C, BuiltinType::Kind kind) { switch (kind) { @@ -5180,15 +5238,15 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, case Type::Complex: { const ComplexType *CT = T->castAs<ComplexType>(); S += 'j'; - getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, 0, false, - false); + getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr, + false, false); return; } case Type::Atomic: { const AtomicType *AT = T->castAs<AtomicType>(); S += 'A'; - getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, 0, + getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr, false, false); return; } @@ -5260,7 +5318,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getLegacyIntegralTypeEncoding(PointeeTy); getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures, - NULL); + nullptr); return; } @@ -5322,9 +5380,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, if (!RDecl->isUnion()) { getObjCEncodingForStructureImpl(RDecl, S, FD); } else { - for (RecordDecl::field_iterator Field = RDecl->field_begin(), - FieldEnd = RDecl->field_end(); - Field != FieldEnd; ++Field) { + for (const auto *Field : RDecl->fields()) { if (FD) { S += '"'; S += Field->getNameAsString(); @@ -5334,7 +5390,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, // Special case bit-fields. if (Field->isBitField()) { getObjCEncodingForTypeImpl(Field->getType(), S, false, true, - *Field); + Field); } else { QualType qt = Field->getType(); getLegacyIntegralTypeEncoding(qt); @@ -5358,37 +5414,38 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, S += '<'; // Block return type - getObjCEncodingForTypeImpl(FT->getResultType(), S, - ExpandPointedToStructures, ExpandStructures, - FD, - false /* OutermostType */, - EncodingProperty, - false /* StructField */, - EncodeBlockParameters, - EncodeClassNames); + getObjCEncodingForTypeImpl( + FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures, + FD, false /* OutermostType */, EncodingProperty, + false /* StructField */, EncodeBlockParameters, EncodeClassNames); // Block self S += "@?"; // Block parameters if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) { - for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), - E = FPT->arg_type_end(); I && (I != E); ++I) { - getObjCEncodingForTypeImpl(*I, S, - ExpandPointedToStructures, - ExpandStructures, - FD, - false /* OutermostType */, - EncodingProperty, - false /* StructField */, - EncodeBlockParameters, - EncodeClassNames); - } + for (const auto &I : FPT->param_types()) + getObjCEncodingForTypeImpl( + I, S, ExpandPointedToStructures, ExpandStructures, FD, + false /* OutermostType */, EncodingProperty, + false /* StructField */, EncodeBlockParameters, EncodeClassNames); } S += '>'; } return; } - case Type::ObjCObject: + case Type::ObjCObject: { + // hack to match legacy encoding of *id and *Class + QualType Ty = getObjCObjectPointerType(CT); + if (Ty->isObjCIdType()) { + S += "{objc_object=}"; + return; + } + else if (Ty->isObjCClassType()) { + S += "{objc_class=}"; + return; + } + } + case Type::ObjCInterface: { // Ignore protocol qualifiers when mangling at this level. T = T->castAs<ObjCObjectType>()->getBaseType(); @@ -5440,10 +5497,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, // Note that we do extended encoding of protocol qualifer list // Only when doing ivar or property encoding. S += '"'; - for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), - E = OPT->qual_end(); I != E; ++I) { + for (const auto *I : OPT->quals()) { S += '<'; - S += (*I)->getNameAsString(); + S += I->getNameAsString(); S += '>'; } S += '"'; @@ -5475,7 +5531,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, } getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures, - NULL, + nullptr, false, false, false, false, false, /*EncodePointerToObjCTypedef*/true); return; @@ -5486,10 +5542,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, (FD || EncodingProperty || EncodeClassNames)) { S += '"'; S += OPT->getInterfaceDecl()->getIdentifier()->getName(); - for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), - E = OPT->qual_end(); I != E; ++I) { + for (const auto *I : OPT->quals()) { S += '<'; - S += (*I)->getNameAsString(); + S += I->getNameAsString(); S += '>'; } S += '"'; @@ -5542,11 +5597,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, const ASTRecordLayout &layout = getASTRecordLayout(RDecl); if (CXXRec) { - for (CXXRecordDecl::base_class_iterator - BI = CXXRec->bases_begin(), - BE = CXXRec->bases_end(); BI != BE; ++BI) { - if (!BI->isVirtual()) { - CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl(); + for (const auto &BI : CXXRec->bases()) { + if (!BI.isVirtual()) { + CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl(); if (base->isEmpty()) continue; uint64_t offs = toBits(layout.getBaseClassOffset(base)); @@ -5566,10 +5619,8 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, } if (CXXRec && includeVBases) { - for (CXXRecordDecl::base_class_iterator - BI = CXXRec->vbases_begin(), - BE = CXXRec->vbases_end(); BI != BE; ++BI) { - CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl(); + for (const auto &BI : CXXRec->vbases()) { + CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl(); if (base->isEmpty()) continue; uint64_t offs = toBits(layout.getVBaseClassOffset(base)); @@ -5587,7 +5638,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, size = layout.getSize(); } +#ifndef NDEBUG uint64_t CurOffs = 0; +#endif std::multimap<uint64_t, NamedDecl *>::iterator CurLayObj = FieldOrBaseOffsets.begin(); @@ -5601,19 +5654,21 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, S += '"'; } S += "^^?"; +#ifndef NDEBUG CurOffs += getTypeSize(VoidPtrTy); +#endif } if (!RDecl->hasFlexibleArrayMember()) { // Mark the end of the structure. uint64_t offs = toBits(size); FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), - std::make_pair(offs, (NamedDecl*)0)); + std::make_pair(offs, nullptr)); } for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) { +#ifndef NDEBUG assert(CurOffs <= CurLayObj->first); - if (CurOffs < CurLayObj->first) { uint64_t padding = CurLayObj->first - CurOffs; // FIXME: There doesn't seem to be a way to indicate in the encoding that @@ -5625,9 +5680,10 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, // longer then though. CurOffs += padding; } +#endif NamedDecl *dcl = CurLayObj->second; - if (dcl == 0) + if (!dcl) break; // reached end of structure. if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) { @@ -5637,7 +5693,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, // making the encoding type bigger than it really is. getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false); assert(!base->isEmpty()); +#ifndef NDEBUG CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize()); +#endif } else { FieldDecl *field = cast<FieldDecl>(dcl); if (FD) { @@ -5648,7 +5706,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, if (field->isBitField()) { EncodeBitField(this, S, field->getType(), field); +#ifndef NDEBUG CurOffs += field->getBitWidthValue(*this); +#endif } else { QualType qt = field->getType(); getLegacyIntegralTypeEncoding(qt); @@ -5656,7 +5716,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, /*OutermostType*/false, /*EncodingProperty*/false, /*StructField*/true); +#ifndef NDEBUG CurOffs += getTypeSize(field->getType()); +#endif } } } @@ -5680,41 +5742,27 @@ void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, TypedefDecl *ASTContext::getObjCIdDecl() const { if (!ObjCIdDecl) { - QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0); + QualType T = getObjCObjectType(ObjCBuiltinIdTy, nullptr, 0); T = getObjCObjectPointerType(T); - TypeSourceInfo *IdInfo = getTrivialTypeSourceInfo(T); - ObjCIdDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this), - getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Idents.get("id"), IdInfo); + ObjCIdDecl = buildImplicitTypedef(T, "id"); } - return ObjCIdDecl; } TypedefDecl *ASTContext::getObjCSelDecl() const { if (!ObjCSelDecl) { - QualType SelT = getPointerType(ObjCBuiltinSelTy); - TypeSourceInfo *SelInfo = getTrivialTypeSourceInfo(SelT); - ObjCSelDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this), - getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Idents.get("SEL"), SelInfo); + QualType T = getPointerType(ObjCBuiltinSelTy); + ObjCSelDecl = buildImplicitTypedef(T, "SEL"); } return ObjCSelDecl; } TypedefDecl *ASTContext::getObjCClassDecl() const { if (!ObjCClassDecl) { - QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0); + QualType T = getObjCObjectType(ObjCBuiltinClassTy, nullptr, 0); T = getObjCObjectPointerType(T); - TypeSourceInfo *ClassInfo = getTrivialTypeSourceInfo(T); - ObjCClassDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this), - getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Idents.get("Class"), ClassInfo); + ObjCClassDecl = buildImplicitTypedef(T, "Class"); } - return ObjCClassDecl; } @@ -5724,7 +5772,7 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const { = ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(), SourceLocation(), &Idents.get("Protocol"), - /*PrevDecl=*/0, + /*PrevDecl=*/nullptr, SourceLocation(), true); } @@ -5737,56 +5785,30 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const { static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) { // typedef char* __builtin_va_list; - QualType CharPtrType = Context->getPointerType(Context->CharTy); - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(CharPtrType); - - TypedefDecl *VaListTypeDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - TInfo); - return VaListTypeDecl; + QualType T = Context->getPointerType(Context->CharTy); + return Context->buildImplicitTypedef(T, "__builtin_va_list"); } static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) { // typedef void* __builtin_va_list; - QualType VoidPtrType = Context->getPointerType(Context->VoidTy); - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(VoidPtrType); - - TypedefDecl *VaListTypeDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - TInfo); - return VaListTypeDecl; + QualType T = Context->getPointerType(Context->VoidTy); + return Context->buildImplicitTypedef(T, "__builtin_va_list"); } static TypedefDecl * CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) { - RecordDecl *VaListTagDecl; + // struct __va_list + RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list"); if (Context->getLangOpts().CPlusPlus) { // namespace std { struct __va_list { NamespaceDecl *NS; NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context), Context->getTranslationUnitDecl(), - /*Inline*/false, SourceLocation(), + /*Inline*/ false, SourceLocation(), SourceLocation(), &Context->Idents.get("std"), - /*PrevDecl*/0); - - VaListTagDecl = CXXRecordDecl::Create(*Context, TTK_Struct, - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__va_list")); + /*PrevDecl*/ nullptr); + NS->setImplicit(); VaListTagDecl->setDeclContext(NS); - } else { - // struct __va_list - VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, - Context->getTranslationUnitDecl(), - &Context->Idents.get("__va_list")); } VaListTagDecl->startDefinition(); @@ -5822,8 +5844,8 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) { SourceLocation(), SourceLocation(), &Context->Idents.get(FieldNames[i]), - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, + FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); @@ -5834,23 +5856,14 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) { Context->VaListTagTy = VaListTagType; // } __builtin_va_list; - TypedefDecl *VaListTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - Context->getTrivialTypeSourceInfo(VaListTagType)); - - return VaListTypedefDecl; + return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list"); } static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { // typedef struct __va_list_tag { RecordDecl *VaListTagDecl; - VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, - Context->getTranslationUnitDecl(), - &Context->Idents.get("__va_list_tag")); + VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); VaListTagDecl->startDefinition(); const size_t NumFields = 5; @@ -5883,8 +5896,8 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { SourceLocation(), SourceLocation(), &Context->Idents.get(FieldNames[i]), - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, + FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); @@ -5895,12 +5908,9 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { Context->VaListTagTy = VaListTagType; // } __va_list_tag; - TypedefDecl *VaListTagTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__va_list_tag"), - Context->getTrivialTypeSourceInfo(VaListTagType)); + TypedefDecl *VaListTagTypedefDecl = + Context->buildImplicitTypedef(VaListTagType, "__va_list_tag"); + QualType VaListTagTypedefType = Context->getTypedefType(VaListTagTypedefDecl); @@ -5909,25 +5919,14 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) { QualType VaListTagArrayType = Context->getConstantArrayType(VaListTagTypedefType, Size, ArrayType::Normal, 0); - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(VaListTagArrayType); - TypedefDecl *VaListTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - TInfo); - - return VaListTypedefDecl; + return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } static TypedefDecl * CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { // typedef struct __va_list_tag { RecordDecl *VaListTagDecl; - VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, - Context->getTranslationUnitDecl(), - &Context->Idents.get("__va_list_tag")); + VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); VaListTagDecl->startDefinition(); const size_t NumFields = 4; @@ -5957,8 +5956,8 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { SourceLocation(), SourceLocation(), &Context->Idents.get(FieldNames[i]), - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, + FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); @@ -5969,12 +5968,9 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { Context->VaListTagTy = VaListTagType; // } __va_list_tag; - TypedefDecl *VaListTagTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__va_list_tag"), - Context->getTrivialTypeSourceInfo(VaListTagType)); + TypedefDecl *VaListTagTypedefDecl = + Context->buildImplicitTypedef(VaListTagType, "__va_list_tag"); + QualType VaListTagTypedefType = Context->getTypedefType(VaListTagTypedefDecl); @@ -5983,16 +5979,7 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) { QualType VaListTagArrayType = Context->getConstantArrayType(VaListTagTypedefType, Size, ArrayType::Normal,0); - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(VaListTagArrayType); - TypedefDecl *VaListTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - TInfo); - - return VaListTypedefDecl; + return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) { @@ -6001,19 +5988,13 @@ static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) { QualType IntArrayType = Context->getConstantArrayType(Context->IntTy, Size, ArrayType::Normal, 0); - TypedefDecl *VaListTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - Context->getTrivialTypeSourceInfo(IntArrayType)); - - return VaListTypedefDecl; + return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list"); } static TypedefDecl * CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { - RecordDecl *VaListDecl; + // struct __va_list + RecordDecl *VaListDecl = Context->buildImplicitRecord("__va_list"); if (Context->getLangOpts().CPlusPlus) { // namespace std { struct __va_list { NamespaceDecl *NS; @@ -6021,20 +6002,9 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { Context->getTranslationUnitDecl(), /*Inline*/false, SourceLocation(), SourceLocation(), &Context->Idents.get("std"), - /*PrevDecl*/0); - - VaListDecl = CXXRecordDecl::Create(*Context, TTK_Struct, - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__va_list")); - + /*PrevDecl*/ nullptr); + NS->setImplicit(); VaListDecl->setDeclContext(NS); - - } else { - // struct __va_list { - VaListDecl = CreateRecordDecl(*Context, TTK_Struct, - Context->getTranslationUnitDecl(), - &Context->Idents.get("__va_list")); } VaListDecl->startDefinition(); @@ -6046,8 +6016,8 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { SourceLocation(), &Context->Idents.get("__ap"), Context->getPointerType(Context->VoidTy), - /*TInfo=*/0, - /*BitWidth=*/0, + /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); @@ -6057,26 +6027,15 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { VaListDecl->completeDefinition(); // typedef struct __va_list __builtin_va_list; - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(Context->getRecordType(VaListDecl)); - - TypedefDecl *VaListTypeDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - TInfo); - - return VaListTypeDecl; + QualType T = Context->getRecordType(VaListDecl); + return Context->buildImplicitTypedef(T, "__builtin_va_list"); } static TypedefDecl * CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { // typedef struct __va_list_tag { RecordDecl *VaListTagDecl; - VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct, - Context->getTranslationUnitDecl(), - &Context->Idents.get("__va_list_tag")); + VaListTagDecl = Context->buildImplicitRecord("__va_list_tag"); VaListTagDecl->startDefinition(); const size_t NumFields = 4; @@ -6106,8 +6065,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { SourceLocation(), SourceLocation(), &Context->Idents.get(FieldNames[i]), - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, + FieldTypes[i], /*TInfo=*/nullptr, + /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit); Field->setAccess(AS_public); @@ -6118,12 +6077,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { Context->VaListTagTy = VaListTagType; // } __va_list_tag; - TypedefDecl *VaListTagTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__va_list_tag"), - Context->getTrivialTypeSourceInfo(VaListTagType)); + TypedefDecl *VaListTagTypedefDecl = + Context->buildImplicitTypedef(VaListTagType, "__va_list_tag"); QualType VaListTagTypedefType = Context->getTypedefType(VaListTagTypedefDecl); @@ -6132,16 +6087,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) { QualType VaListTagArrayType = Context->getConstantArrayType(VaListTagTypedefType, Size, ArrayType::Normal,0); - TypeSourceInfo *TInfo - = Context->getTrivialTypeSourceInfo(VaListTagArrayType); - TypedefDecl *VaListTypedefDecl - = TypedefDecl::Create(const_cast<ASTContext &>(*Context), - Context->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - &Context->Idents.get("__builtin_va_list"), - TInfo); - return VaListTypedefDecl; + return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list"); } static TypedefDecl *CreateVaListDecl(const ASTContext *Context, @@ -6169,8 +6116,10 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context, } TypedefDecl *ASTContext::getBuiltinVaListDecl() const { - if (!BuiltinVaListDecl) + if (!BuiltinVaListDecl) { BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind()); + assert(BuiltinVaListDecl->isImplicit()); + } return BuiltinVaListDecl; } @@ -6227,7 +6176,7 @@ ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, llvm::FoldingSetNodeID ID; QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template); - void *InsertPos = 0; + void *InsertPos = nullptr; QualifiedTemplateName *QTN = QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos); if (!QTN) { @@ -6250,7 +6199,7 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, llvm::FoldingSetNodeID ID; DependentTemplateName::Profile(ID, NNS, Name); - void *InsertPos = 0; + void *InsertPos = nullptr; DependentTemplateName *QTN = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); @@ -6285,8 +6234,8 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS, llvm::FoldingSetNodeID ID; DependentTemplateName::Profile(ID, NNS, Operator); - - void *InsertPos = 0; + + void *InsertPos = nullptr; DependentTemplateName *QTN = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos); @@ -6317,8 +6266,8 @@ ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param, TemplateName replacement) const { llvm::FoldingSetNodeID ID; SubstTemplateTemplateParmStorage::Profile(ID, param, replacement); - - void *insertPos = 0; + + void *insertPos = nullptr; SubstTemplateTemplateParmStorage *subst = SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos); @@ -6336,8 +6285,8 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param, ASTContext &Self = const_cast<ASTContext &>(*this); llvm::FoldingSetNodeID ID; SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack); - - void *InsertPos = 0; + + void *InsertPos = nullptr; SubstTemplateTemplateParmPackStorage *Subst = SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos); @@ -6454,9 +6403,8 @@ ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, ObjCProtocolDecl *rProto) const { if (declaresSameEntity(lProto, rProto)) return true; - for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(), - E = rProto->protocol_end(); PI != E; ++PI) - if (ProtocolCompatibleWithProtocol(lProto, *PI)) + for (auto *PI : rProto->protocols()) + if (ProtocolCompatibleWithProtocol(lProto, PI)) return true; return false; } @@ -6469,13 +6417,9 @@ bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs, const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>(); assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible"); - for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), - E = lhsQID->qual_end(); I != E; ++I) { + for (auto *lhsProto : lhsQID->quals()) { bool match = false; - ObjCProtocolDecl *lhsProto = *I; - for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(), - E = rhsOPT->qual_end(); J != E; ++J) { - ObjCProtocolDecl *rhsProto = *J; + for (auto *rhsProto : rhsOPT->quals()) { if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) { match = true; break; @@ -6508,12 +6452,11 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, // If the RHS is a unqualified interface pointer "NSString*", // make sure we check the class hierarchy. if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) { - for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), - E = lhsQID->qual_end(); I != E; ++I) { + for (auto *I : lhsQID->quals()) { // when comparing an id<P> on lhs with a static type on rhs, // see if static class implements all of id's protocols, directly or // through its super class and categories. - if (!rhsID->ClassImplementsProtocol(*I, true)) + if (!rhsID->ClassImplementsProtocol(I, true)) return false; } } @@ -6521,17 +6464,13 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, return true; } // Both the right and left sides have qualifiers. - for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), - E = lhsQID->qual_end(); I != E; ++I) { - ObjCProtocolDecl *lhsProto = *I; + for (auto *lhsProto : lhsQID->quals()) { bool match = false; // when comparing an id<P> on lhs with a static type on rhs, // see if static class implements all of id's protocols, directly or // through its super class and categories. - for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(), - E = rhsOPT->qual_end(); J != E; ++J) { - ObjCProtocolDecl *rhsProto = *J; + for (auto *rhsProto : rhsOPT->quals()) { if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { match = true; @@ -6541,12 +6480,11 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, // If the RHS is a qualified interface pointer "NSString<P>*", // make sure we check the class hierarchy. if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) { - for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), - E = lhsQID->qual_end(); I != E; ++I) { + for (auto *I : lhsQID->quals()) { // when comparing an id<P> on lhs with a static type on rhs, // see if static class implements all of id's protocols, directly or // through its super class and categories. - if (rhsID->ClassImplementsProtocol(*I, true)) { + if (rhsID->ClassImplementsProtocol(I, true)) { match = true; break; } @@ -6565,9 +6503,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, if (const ObjCObjectPointerType *lhsOPT = lhs->getAsObjCInterfacePointerType()) { // If both the right and left sides have qualifiers. - for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(), - E = lhsOPT->qual_end(); I != E; ++I) { - ObjCProtocolDecl *lhsProto = *I; + for (auto *lhsProto : lhsOPT->quals()) { bool match = false; // when comparing an id<P> on rhs with a static type on lhs, @@ -6575,9 +6511,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, // through its super class and categories. // First, lhs protocols in the qualifier list must be found, direct // or indirect in rhs's qualifier list or it is a mismatch. - for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), - E = rhsQID->qual_end(); J != E; ++J) { - ObjCProtocolDecl *rhsProto = *J; + for (auto *rhsProto : rhsQID->quals()) { if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { match = true; @@ -6598,14 +6532,9 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, // assume that it is mismatch. if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty()) return false; - for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = - LHSInheritedProtocols.begin(), - E = LHSInheritedProtocols.end(); I != E; ++I) { + for (auto *lhsProto : LHSInheritedProtocols) { bool match = false; - ObjCProtocolDecl *lhsProto = (*I); - for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), - E = rhsQID->qual_end(); J != E; ++J) { - ObjCProtocolDecl *rhsProto = *J; + for (auto *rhsProto : rhsQID->quals()) { if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { match = true; @@ -6798,16 +6727,9 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS, if (SuperClassInheritedProtocols.empty()) return false; - for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(), - LHSPE = LHS->qual_end(); - LHSPI != LHSPE; LHSPI++) { - bool SuperImplementsProtocol = false; - ObjCProtocolDecl *LHSProto = (*LHSPI); - - for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = - SuperClassInheritedProtocols.begin(), - E = SuperClassInheritedProtocols.end(); I != E; ++I) { - ObjCProtocolDecl *SuperClassProto = (*I); + for (const auto *LHSProto : LHS->quals()) { + bool SuperImplementsProtocol = false; + for (auto *SuperClassProto : SuperClassInheritedProtocols) { if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) { SuperImplementsProtocol = true; break; @@ -6821,17 +6743,13 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS, return false; } - for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(), - LHSPE = LHS->qual_end(); - LHSPI != LHSPE; LHSPI++) { + for (const auto *LHSPI : LHS->quals()) { bool RHSImplementsProtocol = false; // If the RHS doesn't implement the protocol on the left, the types // are incompatible. - for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(), - RHSPE = RHS->qual_end(); - RHSPI != RHSPE; RHSPI++) { - if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) { + for (auto *RHSPI : RHS->quals()) { + if (RHSPI->lookupProtocolNamed(LHSPI->getIdentifier())) { RHSImplementsProtocol = true; break; } @@ -6891,9 +6809,8 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType, if (const RecordType *UT = T->getAsUnionType()) { RecordDecl *UD = UT->getDecl(); if (UD->hasAttr<TransparentUnionAttr>()) { - for (RecordDecl::field_iterator it = UD->field_begin(), - itend = UD->field_end(); it != itend; ++it) { - QualType ET = it->getType().getUnqualifiedType(); + for (const auto *I : UD->fields()) { + QualType ET = I->getType().getUnqualifiedType(); QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified); if (!MT.isNull()) return MT; @@ -6904,11 +6821,11 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType, return QualType(); } -/// mergeFunctionArgumentTypes - merge two types which appear as function -/// argument types -QualType ASTContext::mergeFunctionArgumentTypes(QualType lhs, QualType rhs, - bool OfBlockPointer, - bool Unqualified) { +/// mergeFunctionParameterTypes - merge two types which appear as function +/// parameter types +QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs, + bool OfBlockPointer, + bool Unqualified) { // GNU extension: two types are compatible if they appear as a function // argument, one of the types is a transparent union type and the other // type is compatible with a union member @@ -6938,23 +6855,23 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, // Check return type QualType retType; if (OfBlockPointer) { - QualType RHS = rbase->getResultType(); - QualType LHS = lbase->getResultType(); + QualType RHS = rbase->getReturnType(); + QualType LHS = lbase->getReturnType(); bool UnqualifiedResult = Unqualified; if (!UnqualifiedResult) UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers()); retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true); } else - retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), false, + retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false, Unqualified); if (retType.isNull()) return QualType(); if (Unqualified) retType = retType.getUnqualifiedType(); - CanQualType LRetType = getCanonicalType(lbase->getResultType()); - CanQualType RRetType = getCanonicalType(rbase->getResultType()); + CanQualType LRetType = getCanonicalType(lbase->getReturnType()); + CanQualType RRetType = getCanonicalType(rbase->getReturnType()); if (Unqualified) { LRetType = LRetType.getUnqualifiedType(); RRetType = RRetType.getUnqualifiedType(); @@ -6998,11 +6915,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (lproto && rproto) { // two C99 style function prototypes assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() && "C++ shouldn't be here"); - unsigned lproto_nargs = lproto->getNumArgs(); - unsigned rproto_nargs = rproto->getNumArgs(); - - // Compatible functions must have the same number of arguments - if (lproto_nargs != rproto_nargs) + // Compatible functions must have the same number of parameters + if (lproto->getNumParams() != rproto->getNumParams()) return QualType(); // Variadic and non-variadic functions aren't compatible @@ -7015,29 +6929,29 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (LangOpts.ObjCAutoRefCount && !FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto)) return QualType(); - - // Check argument compatibility + + // Check parameter type compatibility SmallVector<QualType, 10> types; - for (unsigned i = 0; i < lproto_nargs; i++) { - QualType largtype = lproto->getArgType(i).getUnqualifiedType(); - QualType rargtype = rproto->getArgType(i).getUnqualifiedType(); - QualType argtype = mergeFunctionArgumentTypes(largtype, rargtype, - OfBlockPointer, - Unqualified); - if (argtype.isNull()) return QualType(); - + for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) { + QualType lParamType = lproto->getParamType(i).getUnqualifiedType(); + QualType rParamType = rproto->getParamType(i).getUnqualifiedType(); + QualType paramType = mergeFunctionParameterTypes( + lParamType, rParamType, OfBlockPointer, Unqualified); + if (paramType.isNull()) + return QualType(); + if (Unqualified) - argtype = argtype.getUnqualifiedType(); - - types.push_back(argtype); + paramType = paramType.getUnqualifiedType(); + + types.push_back(paramType); if (Unqualified) { - largtype = largtype.getUnqualifiedType(); - rargtype = rargtype.getUnqualifiedType(); + lParamType = lParamType.getUnqualifiedType(); + rParamType = rParamType.getUnqualifiedType(); } - - if (getCanonicalType(argtype) != getCanonicalType(largtype)) + + if (getCanonicalType(paramType) != getCanonicalType(lParamType)) allLTypes = false; - if (getCanonicalType(argtype) != getCanonicalType(rargtype)) + if (getCanonicalType(paramType) != getCanonicalType(rParamType)) allRTypes = false; } @@ -7061,20 +6975,19 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, // The only types actually affected are promotable integer // types and floats, which would be passed as a different // type depending on whether the prototype is visible. - unsigned proto_nargs = proto->getNumArgs(); - for (unsigned i = 0; i < proto_nargs; ++i) { - QualType argTy = proto->getArgType(i); - + for (unsigned i = 0, n = proto->getNumParams(); i < n; ++i) { + QualType paramTy = proto->getParamType(i); + // Look at the converted type of enum types, since that is the type used // to pass enum values. - if (const EnumType *Enum = argTy->getAs<EnumType>()) { - argTy = Enum->getDecl()->getIntegerType(); - if (argTy.isNull()) + if (const EnumType *Enum = paramTy->getAs<EnumType>()) { + paramTy = Enum->getDecl()->getIntegerType(); + if (paramTy.isNull()) return QualType(); } - - if (argTy->isPromotableIntegerType() || - getCanonicalType(argTy).getUnqualifiedType() == FloatTy) + + if (paramTy->isPromotableIntegerType() || + getCanonicalType(paramTy).getUnqualifiedType() == FloatTy) return QualType(); } @@ -7083,7 +6996,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo(); EPI.ExtInfo = einfo; - return getFunctionType(retType, proto->getArgTypes(), EPI); + return getFunctionType(retType, proto->getParamTypes(), EPI); } if (allLTypes) return lhs; @@ -7387,18 +7300,16 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs( const FunctionProtoType *FromFunctionType, const FunctionProtoType *ToFunctionType) { - if (FromFunctionType->hasAnyConsumedArgs() != - ToFunctionType->hasAnyConsumedArgs()) + if (FromFunctionType->hasAnyConsumedParams() != + ToFunctionType->hasAnyConsumedParams()) return false; FunctionProtoType::ExtProtoInfo FromEPI = FromFunctionType->getExtProtoInfo(); FunctionProtoType::ExtProtoInfo ToEPI = ToFunctionType->getExtProtoInfo(); - if (FromEPI.ConsumedArguments && ToEPI.ConsumedArguments) - for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs(); - ArgIdx != NumArgs; ++ArgIdx) { - if (FromEPI.ConsumedArguments[ArgIdx] != - ToEPI.ConsumedArguments[ArgIdx]) + if (FromEPI.ConsumedParameters && ToEPI.ConsumedParameters) + for (unsigned i = 0, n = FromFunctionType->getNumParams(); i != n; ++i) { + if (FromEPI.ConsumedParameters[i] != ToEPI.ConsumedParameters[i]) return false; } return true; @@ -7416,10 +7327,10 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) { if (RHSCan->isFunctionType()) { if (!LHSCan->isFunctionType()) return QualType(); - QualType OldReturnType = - cast<FunctionType>(RHSCan.getTypePtr())->getResultType(); + QualType OldReturnType = + cast<FunctionType>(RHSCan.getTypePtr())->getReturnType(); QualType NewReturnType = - cast<FunctionType>(LHSCan.getTypePtr())->getResultType(); + cast<FunctionType>(LHSCan.getTypePtr())->getReturnType(); QualType ResReturnType = mergeObjCGCQualifiers(NewReturnType, OldReturnType); if (ResReturnType.isNull()) @@ -7432,7 +7343,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.ExtInfo = getFunctionExtInfo(LHS); QualType ResultType = - getFunctionType(OldReturnType, FPT->getArgTypes(), EPI); + getFunctionType(OldReturnType, FPT->getParamTypes(), EPI); return ResultType; } } @@ -7573,6 +7484,19 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, assert(HowLong <= 2 && "Can't have LLLL modifier"); ++HowLong; break; + case 'W': + // This modifier represents int64 type. + assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!"); + switch (Context.getTargetInfo().getInt64Type()) { + default: + llvm_unreachable("Unexpected integer type"); + case TargetInfo::SignedLong: + HowLong = 1; + break; + case TargetInfo::SignedLongLong: + HowLong = 2; + break; + } } } @@ -7834,7 +7758,8 @@ QualType ASTContext::GetBuiltinType(unsigned Id, return getFunctionType(ResType, ArgTypes, EPI); } -GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) { +static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, + const FunctionDecl *FD) { if (!FD->isExternallyVisible()) return GVA_Internal; @@ -7846,68 +7771,126 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) { break; case TSK_ExplicitInstantiationDefinition: - return GVA_ExplicitTemplateInstantiation; + return GVA_StrongODR; + // C++11 [temp.explicit]p10: + // [ Note: The intent is that an inline function that is the subject of + // an explicit instantiation declaration will still be implicitly + // instantiated when used so that the body can be considered for + // inlining, but that no out-of-line copy of the inline function would be + // generated in the translation unit. -- end note ] case TSK_ExplicitInstantiationDeclaration: + return GVA_AvailableExternally; + case TSK_ImplicitInstantiation: - External = GVA_TemplateInstantiation; + External = GVA_DiscardableODR; break; } if (!FD->isInlined()) return External; - if ((!getLangOpts().CPlusPlus && !getLangOpts().MicrosoftMode) || + if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat && + !FD->hasAttr<DLLExportAttr>()) || FD->hasAttr<GNUInlineAttr>()) { + // FIXME: This doesn't match gcc's behavior for dllexport inline functions. + // GNU or C99 inline semantics. Determine whether this symbol should be // externally visible. if (FD->isInlineDefinitionExternallyVisible()) return External; // C99 inline semantics, where the symbol is not externally visible. - return GVA_C99Inline; + return GVA_AvailableExternally; } - // C++0x [temp.explicit]p9: - // [ Note: The intent is that an inline function that is the subject of - // an explicit instantiation declaration will still be implicitly - // instantiated when used so that the body can be considered for - // inlining, but that no out-of-line copy of the inline function would be - // generated in the translation unit. -- end note ] - if (FD->getTemplateSpecializationKind() - == TSK_ExplicitInstantiationDeclaration) - return GVA_C99Inline; + // Functions specified with extern and inline in -fms-compatibility mode + // forcibly get emitted. While the body of the function cannot be later + // replaced, the function definition cannot be discarded. + if (FD->getMostRecentDecl()->isMSExternInline()) + return GVA_StrongODR; - return GVA_CXXInline; + return GVA_DiscardableODR; } -GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { +static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) { + // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx + // dllexport/dllimport on inline functions. + if (D->hasAttr<DLLImportAttr>()) { + if (L == GVA_DiscardableODR || L == GVA_StrongODR) + return GVA_AvailableExternally; + } else if (D->hasAttr<DLLExportAttr>()) { + if (L == GVA_DiscardableODR) + return GVA_StrongODR; + } + return L; +} + +GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const { + return adjustGVALinkageForDLLAttribute(basicGVALinkageForFunction(*this, FD), + FD); +} + +static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, + const VarDecl *VD) { if (!VD->isExternallyVisible()) return GVA_Internal; + if (VD->isStaticLocal()) { + GVALinkage StaticLocalLinkage = GVA_DiscardableODR; + const DeclContext *LexicalContext = VD->getParentFunctionOrMethod(); + while (LexicalContext && !isa<FunctionDecl>(LexicalContext)) + LexicalContext = LexicalContext->getLexicalParent(); + + // Let the static local variable inherit it's linkage from the nearest + // enclosing function. + if (LexicalContext) + StaticLocalLinkage = + Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext)); + + // GVA_StrongODR function linkage is stronger than what we need, + // downgrade to GVA_DiscardableODR. + // This allows us to discard the variable if we never end up needing it. + return StaticLocalLinkage == GVA_StrongODR ? GVA_DiscardableODR + : StaticLocalLinkage; + } + + // MSVC treats in-class initialized static data members as definitions. + // By giving them non-strong linkage, out-of-line definitions won't + // cause link errors. + if (Context.isMSStaticDataMemberInlineDefinition(VD)) + return GVA_DiscardableODR; + switch (VD->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ExplicitSpecialization: return GVA_StrongExternal; - case TSK_ExplicitInstantiationDeclaration: - llvm_unreachable("Variable should not be instantiated"); - // Fall through to treat this like any other instantiation. - case TSK_ExplicitInstantiationDefinition: - return GVA_ExplicitTemplateInstantiation; + return GVA_StrongODR; + + case TSK_ExplicitInstantiationDeclaration: + return GVA_AvailableExternally; case TSK_ImplicitInstantiation: - return GVA_TemplateInstantiation; + return GVA_DiscardableODR; } llvm_unreachable("Invalid Linkage!"); } +GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { + return adjustGVALinkageForDLLAttribute(basicGVALinkageForVariable(*this, VD), + VD); +} + bool ASTContext::DeclMustBeEmitted(const Decl *D) { if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (!VD->isFileVarDecl()) return false; + // Global named register variables (GNU extension) are never emitted. + if (VD->getStorageClass() == SC_Register) + return false; } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { // We never need to emit an uninstantiated function template. if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) @@ -7954,8 +7937,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // static, static inline, always_inline, and extern inline functions can // always be deferred. Normal inline functions can be deferred in C99/C++. // Implicit template instantiations can also be deferred in C++. - if (Linkage == GVA_Internal || Linkage == GVA_C99Inline || - Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation) + if (Linkage == GVA_Internal || Linkage == GVA_AvailableExternally || + Linkage == GVA_DiscardableODR) return false; return true; } @@ -7963,12 +7946,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { const VarDecl *VD = cast<VarDecl>(D); assert(VD->isFileVarDecl() && "Expected file scoped var"); - if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly) + if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly && + !isMSStaticDataMemberInlineDefinition(VD)) return false; // Variables that can be needed in other TUs are required. GVALinkage L = GetGVALinkageForVariable(VD); - if (L != GVA_Internal && L != GVA_TemplateInstantiation) + if (L != GVA_Internal && L != GVA_AvailableExternally && + L != GVA_DiscardableODR) return true; // Variables that have destruction with side-effects are required. @@ -7996,12 +7981,23 @@ bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const { return ABI->isNearlyEmpty(RD); } +VTableContextBase *ASTContext::getVTableContext() { + if (!VTContext.get()) { + if (Target->getCXXABI().isMicrosoft()) + VTContext.reset(new MicrosoftVTableContext(*this)); + else + VTContext.reset(new ItaniumVTableContext(*this)); + } + return VTContext.get(); +} + MangleContext *ASTContext::createMangleContext() { switch (Target->getCXXABI().getKind()) { case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericItanium: case TargetCXXABI::GenericARM: case TargetCXXABI::iOS: + case TargetCXXABI::iOS64: return ItaniumMangleContext::create(*this, getDiagnostics()); case TargetCXXABI::Microsoft: return MicrosoftMangleContext::create(*this, getDiagnostics()); @@ -8071,6 +8067,17 @@ unsigned ASTContext::getManglingNumber(const NamedDecl *ND) const { return I != MangleNumbers.end() ? I->second : 1; } +void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) { + if (Number > 1) + StaticLocalNumbers[VD] = Number; +} + +unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const { + llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I = + StaticLocalNumbers.find(VD); + return I != StaticLocalNumbers.end() ? I->second : 1; +} + MangleNumberingContext & ASTContext::getManglingNumberContext(const DeclContext *DC) { assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C. @@ -8105,7 +8112,7 @@ ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E, llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I = MaterializedTemporaryValues.find(E); - return I == MaterializedTemporaryValues.end() ? 0 : &I->second; + return I == MaterializedTemporaryValues.end() ? nullptr : &I->second; } bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const { @@ -8168,18 +8175,45 @@ namespace { template <typename T> bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) { - if (Node == NULL) + if (!Node) return true; - if (ParentStack.size() > 0) - // FIXME: Currently we add the same parent multiple times, for example - // when we visit all subexpressions of template instantiations; this is - // suboptimal, bug benign: the only way to visit those is with - // hasAncestor / hasParent, and those do not create new matches. + if (ParentStack.size() > 0) { + // FIXME: Currently we add the same parent multiple times, but only + // when no memoization data is available for the type. + // For example when we visit all subexpressions of template + // instantiations; this is suboptimal, but benign: the only way to + // visit those is with hasAncestor / hasParent, and those do not create + // new matches. // The plan is to enable DynTypedNode to be storable in a map or hash // map. The main problem there is to implement hash functions / // comparison operators for all types that DynTypedNode supports that // do not have pointer identity. - (*Parents)[Node].push_back(ParentStack.back()); + auto &NodeOrVector = (*Parents)[Node]; + if (NodeOrVector.isNull()) { + NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back()); + } else { + if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) { + auto *Node = + NodeOrVector.template get<ast_type_traits::DynTypedNode *>(); + auto *Vector = new ASTContext::ParentVector(1, *Node); + NodeOrVector = Vector; + delete Node; + } + assert(NodeOrVector.template is<ASTContext::ParentVector *>()); + + auto *Vector = + NodeOrVector.template get<ASTContext::ParentVector *>(); + // Skip duplicates for types that have memoization data. + // We must check that the type has memoization data before calling + // std::find() because DynTypedNode::operator== can't compare all + // types. + bool Found = ParentStack.back().getMemoizationData() && + std::find(Vector->begin(), Vector->end(), + ParentStack.back()) != Vector->end(); + if (!Found) + Vector->push_back(ParentStack.back()); + } + } ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node)); bool Result = (this ->* traverse) (Node); ParentStack.pop_back(); @@ -8217,7 +8251,11 @@ ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { if (I == AllParents->end()) { return ParentVector(); } - return I->second; + if (I->second.is<ast_type_traits::DynTypedNode *>()) { + return ParentVector(1, *I->second.get<ast_type_traits::DynTypedNode *>()); + } + const auto &Parents = *I->second.get<ParentVector *>(); + return ParentVector(Parents.begin(), Parents.end()); } bool @@ -8230,8 +8268,7 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, if (MethodDecl->getObjCDeclQualifier() != MethodImpl->getObjCDeclQualifier()) return false; - if (!hasSameType(MethodDecl->getResultType(), - MethodImpl->getResultType())) + if (!hasSameType(MethodDecl->getReturnType(), MethodImpl->getReturnType())) return false; if (MethodDecl->param_size() != MethodImpl->param_size()) @@ -8251,3 +8288,12 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, return (MethodDecl->isVariadic() == MethodImpl->isVariadic()); } + +// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that +// doesn't include ASTContext.h +template +clang::LazyGenerationalUpdatePtr< + const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType +clang::LazyGenerationalUpdatePtr< + const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue( + const clang::ASTContext &Ctx, Decl *Value); |