diff options
author | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
commit | 9dd834653b811ad20382e98a87dff824980c9916 (patch) | |
tree | a764184c2fc9486979b074250b013a0937ee64e5 /lib/Serialization/ASTReaderDecl.cpp | |
parent | bb9760db9b86e93a638ed430d0a14785f7ff9064 (diff) | |
download | FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.zip FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.tar.gz |
Vendor import of clang trunk r240225:
https://llvm.org/svn/llvm-project/cfe/trunk@240225
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 277 |
1 files changed, 158 insertions, 119 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 02273ed..00ebd3e 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -365,9 +365,72 @@ namespace clang { void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + + /// We've merged the definition \p MergedDef into the existing definition + /// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made + /// visible. + void mergeDefinitionVisibility(NamedDecl *Def, NamedDecl *MergedDef) { + if (Def->isHidden()) { + // If MergedDef is visible or becomes visible, make the definition visible. + if (!MergedDef->isHidden()) + Def->Hidden = false; + else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { + Reader.getContext().mergeDefinitionIntoModule( + Def, MergedDef->getImportedOwningModule(), + /*NotifyListeners*/ false); + Reader.PendingMergedDefinitionsToDeduplicate.insert(Def); + } else { + auto SubmoduleID = MergedDef->getOwningModuleID(); + assert(SubmoduleID && "hidden definition in no module"); + Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)].push_back(Def); + } + } + } }; } +namespace { +/// Iterator over the redeclarations of a declaration that have already +/// been merged into the same redeclaration chain. +template<typename DeclT> +class MergedRedeclIterator { + DeclT *Start, *Canonical, *Current; +public: + MergedRedeclIterator() : Current(nullptr) {} + MergedRedeclIterator(DeclT *Start) + : Start(Start), Canonical(nullptr), Current(Start) {} + + DeclT *operator*() { return Current; } + + MergedRedeclIterator &operator++() { + if (Current->isFirstDecl()) { + Canonical = Current; + Current = Current->getMostRecentDecl(); + } else + Current = Current->getPreviousDecl(); + + // If we started in the merged portion, we'll reach our start position + // eventually. Otherwise, we'll never reach it, but the second declaration + // we reached was the canonical declaration, so stop when we see that one + // again. + if (Current == Start || Current == Canonical) + Current = nullptr; + return *this; + } + + friend bool operator!=(const MergedRedeclIterator &A, + const MergedRedeclIterator &B) { + return A.Current != B.Current; + } +}; +} +template<typename DeclT> +llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) { + return llvm::iterator_range<MergedRedeclIterator<DeclT>>( + MergedRedeclIterator<DeclT>(D), + MergedRedeclIterator<DeclT>()); +} + uint64_t ASTDeclReader::GetCurrentCursorOffset() { return F.DeclsCursor.GetCurrentBitNo() + F.GlobalBitOffset; } @@ -585,9 +648,21 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { if (ED->IsCompleteDefinition && Reader.getContext().getLangOpts().Modules && Reader.getContext().getLangOpts().CPlusPlus) { - if (EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()]) { + EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()]; + if (!OldDef) { + // This is the first time we've seen an imported definition. Look for a + // local definition before deciding that we are the first definition. + for (auto *D : merged_redecls(ED->getCanonicalDecl())) { + if (!D->isFromASTFile() && D->isCompleteDefinition()) { + OldDef = D; + break; + } + } + } + if (OldDef) { Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef)); ED->IsCompleteDefinition = false; + mergeDefinitionVisibility(OldDef, ED); } else { OldDef = ED; } @@ -967,7 +1042,9 @@ void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { VisitNamedDecl(D); D->setAtLoc(ReadSourceLocation(Record, Idx)); D->setLParenLoc(ReadSourceLocation(Record, Idx)); - D->setType(GetTypeSourceInfo(Record, Idx)); + QualType T = Reader.readType(F, Record, Idx); + TypeSourceInfo *TSI = GetTypeSourceInfo(Record, Idx); + D->setType(T, TSI); // FIXME: stable encoding D->setPropertyAttributes( (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]); @@ -1391,32 +1468,22 @@ void ASTDeclReader::MergeDefinitionData( "merging class definition into non-definition"); auto &DD = *D->DefinitionData.getNotUpdated(); - // If the new definition has new special members, let the name lookup - // code know that it needs to look in the new definition too. - // - // FIXME: We only need to do this if the merged definition declares members - // that this definition did not declare, or if it defines members that this - // definition did not define. if (DD.Definition != MergeDD.Definition) { + // If the new definition has new special members, let the name lookup + // code know that it needs to look in the new definition too. + // + // FIXME: We only need to do this if the merged definition declares members + // that this definition did not declare, or if it defines members that this + // definition did not define. Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition); DD.Definition->setHasExternalVisibleStorage(); - if (DD.Definition->isHidden()) { - // If MergeDD is visible or becomes visible, make the definition visible. - if (!MergeDD.Definition->isHidden()) - DD.Definition->Hidden = false; - else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { - Reader.getContext().mergeDefinitionIntoModule( - DD.Definition, MergeDD.Definition->getImportedOwningModule(), - /*NotifyListeners*/ false); - Reader.PendingMergedDefinitionsToDeduplicate.insert(DD.Definition); - } else { - auto SubmoduleID = MergeDD.Definition->getOwningModuleID(); - assert(SubmoduleID && "hidden definition in no module"); - Reader.HiddenNamesMap[Reader.getSubmodule(SubmoduleID)].push_back( - DD.Definition); - } - } + // Track that we merged the definitions. + Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition, + DD.Definition)); + Reader.PendingDefinitions.erase(MergeDD.Definition); + MergeDD.Definition->IsCompleteDefinition = false; + mergeDefinitionVisibility(DD.Definition, MergeDD.Definition); } auto PFDI = Reader.PendingFakeDefinitionData.find(&DD); @@ -1525,42 +1592,21 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) { // because we're reading an update record, or because we've already done some // merging. Either way, just merge into it. CXXRecordDecl *Canon = D->getCanonicalDecl(); - if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) { - if (CanonDD->Definition != DD->Definition) - Reader.MergedDeclContexts.insert( - std::make_pair(DD->Definition, CanonDD->Definition)); + if (Canon->DefinitionData.getNotUpdated()) { MergeDefinitionData(Canon, std::move(*DD)); D->DefinitionData = Canon->DefinitionData; return; } - // Propagate the DefinitionData pointer to the canonical declaration, so - // that all other deserialized declarations will see it. - if (Canon == D) { - D->DefinitionData = DD; - D->IsCompleteDefinition = true; - - // If this is an update record, we can have redeclarations already. Make a - // note that we need to propagate the DefinitionData pointer onto them. - if (Update) - Reader.PendingDefinitions.insert(D); - } else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) { - // We have already deserialized a definition of this record. This - // definition is no longer really a definition. Note that the pre-existing - // definition is the *real* definition. - Reader.MergedDeclContexts.insert( - std::make_pair(D, CanonDD->Definition)); - D->DefinitionData = Canon->DefinitionData; - D->IsCompleteDefinition = false; - MergeDefinitionData(D, std::move(*DD)); - } else { - Canon->DefinitionData = DD; - D->DefinitionData = Canon->DefinitionData; - D->IsCompleteDefinition = true; + // Mark this declaration as being a definition. + D->IsCompleteDefinition = true; + D->DefinitionData = DD; - // Note that we have deserialized a definition. Any declarations - // deserialized before this one will be be given the DefinitionData - // pointer at the end. + // If this is not the first declaration or is an update record, we can have + // other redeclarations already. Make a note that we need to propagate the + // DefinitionData pointer onto them. + if (Update || Canon != D) { + Canon->DefinitionData = D->DefinitionData; Reader.PendingDefinitions.insert(D); } } @@ -1880,15 +1926,10 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( // This declaration might be a definition. Merge with any existing // definition. if (auto *DDD = D->DefinitionData.getNotUpdated()) { - if (auto *CanonDD = CanonSpec->DefinitionData.getNotUpdated()) { + if (CanonSpec->DefinitionData.getNotUpdated()) MergeDefinitionData(CanonSpec, std::move(*DDD)); - Reader.PendingDefinitions.erase(D); - Reader.MergedDeclContexts.insert( - std::make_pair(D, CanonDD->Definition)); - D->IsCompleteDefinition = false; - } else { + else CanonSpec->DefinitionData = D->DefinitionData; - } } D->DefinitionData = CanonSpec->DefinitionData; } @@ -2033,9 +2074,8 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record[Idx++]); - bool Inherited = Record[Idx++]; - TypeSourceInfo *DefArg = GetTypeSourceInfo(Record, Idx); - D->setDefaultArgument(DefArg, Inherited); + if (Record[Idx++]) + D->setDefaultArgument(GetTypeSourceInfo(Record, Idx)); } void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { @@ -2052,11 +2092,8 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { } else { // Rest of NonTypeTemplateParmDecl. D->ParameterPack = Record[Idx++]; - if (Record[Idx++]) { - Expr *DefArg = Reader.ReadExpr(F); - bool Inherited = Record[Idx++]; - D->setDefaultArgument(DefArg, Inherited); - } + if (Record[Idx++]) + D->setDefaultArgument(Reader.ReadExpr(F)); } } @@ -2072,10 +2109,10 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx); } else { // Rest of TemplateTemplateParmDecl. - TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(F, Record, Idx); - bool IsInherited = Record[Idx++]; - D->setDefaultArgument(Arg, IsInherited); D->ParameterPack = Record[Idx++]; + if (Record[Idx++]) + D->setDefaultArgument(Reader.getContext(), + Reader.ReadTemplateArgumentLoc(F, Record, Idx)); } } @@ -2189,14 +2226,12 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, auto *ExistingClass = cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl(); if (auto *DDD = DClass->DefinitionData.getNotUpdated()) { - if (auto *ExistingDD = ExistingClass->DefinitionData.getNotUpdated()) { + if (ExistingClass->DefinitionData.getNotUpdated()) { MergeDefinitionData(ExistingClass, std::move(*DDD)); - Reader.PendingDefinitions.erase(DClass); - Reader.MergedDeclContexts.insert( - std::make_pair(DClass, ExistingDD->Definition)); - DClass->IsCompleteDefinition = false; } else { ExistingClass->DefinitionData = DClass->DefinitionData; + // We may have skipped this before because we thought that DClass + // was the canonical declaration. Reader.PendingDefinitions.insert(DClass); } } @@ -2904,6 +2939,43 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) { llvm_unreachable("attachPreviousDecl on non-redeclarable declaration"); } +/// Inherit the default template argument from \p From to \p To. Returns +/// \c false if there is no default template for \p From. +template <typename ParmDecl> +static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From, + Decl *ToD) { + auto *To = cast<ParmDecl>(ToD); + if (!From->hasDefaultArgument()) + return false; + To->setInheritedDefaultArgument(Context, From); + return true; +} + +static void inheritDefaultTemplateArguments(ASTContext &Context, + TemplateDecl *From, + TemplateDecl *To) { + auto *FromTP = From->getTemplateParameters(); + auto *ToTP = To->getTemplateParameters(); + assert(FromTP->size() == ToTP->size() && "merged mismatched templates?"); + + for (unsigned I = 0, N = FromTP->size(); I != N; ++I) { + NamedDecl *FromParam = FromTP->getParam(N - I - 1); + NamedDecl *ToParam = ToTP->getParam(N - I - 1); + + if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) { + if (!inheritDefaultTemplateArgument(Context, FTTP, ToParam)) + break; + } else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam)) { + if (!inheritDefaultTemplateArgument(Context, FNTTP, ToParam)) + break; + } else { + if (!inheritDefaultTemplateArgument( + Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam)) + break; + } + } +} + void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous, Decl *Canon) { assert(D && Previous); @@ -2930,6 +3002,12 @@ void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D, // be too. if (Previous->Used) D->Used = true; + + // If the declaration declares a template, it may inherit default arguments + // from the previous declaration. + if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) + inheritDefaultTemplateArguments(Reader.getContext(), + cast<TemplateDecl>(Previous), TD); } template<typename DeclT> @@ -3579,48 +3657,6 @@ void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID, ModuleMgr.visit(ObjCCategoriesVisitor::visit, &Visitor); } -namespace { -/// Iterator over the redeclarations of a declaration that have already -/// been merged into the same redeclaration chain. -template<typename DeclT> -class MergedRedeclIterator { - DeclT *Start, *Canonical, *Current; -public: - MergedRedeclIterator() : Current(nullptr) {} - MergedRedeclIterator(DeclT *Start) - : Start(Start), Canonical(nullptr), Current(Start) {} - - DeclT *operator*() { return Current; } - - MergedRedeclIterator &operator++() { - if (Current->isFirstDecl()) { - Canonical = Current; - Current = Current->getMostRecentDecl(); - } else - Current = Current->getPreviousDecl(); - - // If we started in the merged portion, we'll reach our start position - // eventually. Otherwise, we'll never reach it, but the second declaration - // we reached was the canonical declaration, so stop when we see that one - // again. - if (Current == Start || Current == Canonical) - Current = nullptr; - return *this; - } - - friend bool operator!=(const MergedRedeclIterator &A, - const MergedRedeclIterator &B) { - return A.Current != B.Current; - } -}; -} -template<typename DeclT> -llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) { - return llvm::iterator_range<MergedRedeclIterator<DeclT>>( - MergedRedeclIterator<DeclT>(D), - MergedRedeclIterator<DeclT>()); -} - template<typename DeclT, typename Fn> static void forAllLaterRedecls(DeclT *D, Fn F) { F(D); @@ -3854,6 +3890,9 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, case UPD_DECL_EXPORTED: unsigned SubmoduleID = readSubmoduleID(Record, Idx); + auto *Exported = cast<NamedDecl>(D); + if (auto *TD = dyn_cast<TagDecl>(Exported)) + Exported = TD->getDefinition(); Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr; if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { // FIXME: This doesn't send the right notifications if there are |