diff options
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
| -rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 779 | 
1 files changed, 480 insertions, 299 deletions
| diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index a783183d2ef6..02273ed229a5 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -66,7 +66,12 @@ namespace clang {      serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {        return Reader.ReadDeclID(F, R, I);      } -     + +    void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) { +      for (unsigned I = 0, Size = Record[Idx++]; I != Size; ++I) +        IDs.push_back(ReadDeclID(Record, Idx)); +    } +      Decl *ReadDecl(const RecordData &R, unsigned &I) {        return Reader.ReadDecl(F, R, I);      } @@ -103,11 +108,11 @@ namespace clang {        return Reader.getSubmodule(readSubmoduleID(R, I));      } -    void ReadCXXRecordDefinition(CXXRecordDecl *D); +    void ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update);      void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data,                                 const RecordData &R, unsigned &I);      void MergeDefinitionData(CXXRecordDecl *D, -                             struct CXXRecordDecl::DefinitionData &NewDD); +                             struct CXXRecordDecl::DefinitionData &&NewDD);      static NamedDecl *getAnonymousDeclForMerging(ASTReader &Reader,                                                   DeclContext *DC, @@ -118,43 +123,42 @@ namespace clang {      /// \brief RAII class used to capture the first ID within a redeclaration      /// chain and to introduce it into the list of pending redeclaration chains      /// on destruction. -    /// -    /// The caller can choose not to introduce this ID into the list of pending -    /// redeclaration chains by calling \c suppress().      class RedeclarableResult {        ASTReader &Reader;        GlobalDeclID FirstID; +      Decl *MergeWith;        mutable bool Owning;        Decl::Kind DeclKind; -       -      void operator=(RedeclarableResult &) LLVM_DELETED_FUNCTION; -       + +      void operator=(RedeclarableResult &) = delete; +      public:        RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID, -                         Decl::Kind DeclKind) -        : Reader(Reader), FirstID(FirstID), Owning(true), DeclKind(DeclKind) { } - -      RedeclarableResult(const RedeclarableResult &Other) -        : Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning) , -          DeclKind(Other.DeclKind) -      {  +                         Decl *MergeWith, Decl::Kind DeclKind) +        : Reader(Reader), FirstID(FirstID), MergeWith(MergeWith), +          Owning(true), DeclKind(DeclKind) {} + +      RedeclarableResult(RedeclarableResult &&Other) +        : Reader(Other.Reader), FirstID(Other.FirstID), +          MergeWith(Other.MergeWith), Owning(Other.Owning), +          DeclKind(Other.DeclKind) {          Other.Owning = false;        }        ~RedeclarableResult() { -        if (FirstID && Owning && isRedeclarableDeclKind(DeclKind) && -            Reader.PendingDeclChainsKnown.insert(FirstID).second) -          Reader.PendingDeclChains.push_back(FirstID); +        if (FirstID && Owning && isRedeclarableDeclKind(DeclKind)) { +          auto Canon = Reader.GetDecl(FirstID)->getCanonicalDecl(); +          if (Reader.PendingDeclChainsKnown.insert(Canon).second) +            Reader.PendingDeclChains.push_back(Canon); +        }        } -       +        /// \brief Retrieve the first ID.        GlobalDeclID getFirstID() const { return FirstID; } -       -      /// \brief Do not introduce this declaration ID into the set of pending -      /// declaration chains. -      void suppress() { -        Owning = false; -      } + +      /// \brief Get a known declaration that this should be merged with, if +      /// any. +      Decl *getKnownMergeTarget() const { return MergeWith; }      };      /// \brief Class used to capture the result of searching for an existing @@ -171,7 +175,7 @@ namespace clang {        unsigned AnonymousDeclNumber;        IdentifierInfo *TypedefNameForLinkage; -      void operator=(FindExistingResult&) LLVM_DELETED_FUNCTION; +      void operator=(FindExistingResult&) = delete;      public:        FindExistingResult(ASTReader &Reader) @@ -205,6 +209,8 @@ namespace clang {        operator T*() const { return dyn_cast_or_null<T>(Existing); }      }; +    static DeclContext *getPrimaryContextForMerging(ASTReader &Reader, +                                                    DeclContext *DC);      FindExistingResult findExisting(NamedDecl *D);    public: @@ -216,10 +222,17 @@ namespace clang {            TypedefNameForLinkage(nullptr), HasPendingBody(false) {}      template <typename DeclT> +    static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D); +    static Decl *getMostRecentDeclImpl(...); +    static Decl *getMostRecentDecl(Decl *D); + +    template <typename DeclT>      static void attachPreviousDeclImpl(ASTReader &Reader, -                                       Redeclarable<DeclT> *D, Decl *Previous); +                                       Redeclarable<DeclT> *D, Decl *Previous, +                                       Decl *Canon);      static void attachPreviousDeclImpl(ASTReader &Reader, ...); -    static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous); +    static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous, +                                   Decl *Canon);      template <typename DeclT>      static void attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest); @@ -390,9 +403,14 @@ void ASTDeclReader::Visit(Decl *D) {      // FunctionDecl's body was written last after all other Stmts/Exprs.      // We only read it if FD doesn't already have a body (e.g., from another      // module). -    // FIXME: Also consider = default and = delete.      // FIXME: Can we diagnose ODR violations somehow?      if (Record[Idx++]) { +      if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) { +        CD->NumCtorInitializers = Record[Idx++]; +        if (CD->NumCtorInitializers) +          CD->CtorInitializers = +              Reader.ReadCXXCtorInitializersRef(F, Record, Idx); +      }        Reader.PendingBodies[FD] = GetCurrentCursorOffset();        HasPendingBody = true;      } @@ -440,24 +458,28 @@ void ASTDeclReader::VisitDecl(Decl *D) {    D->FromASTFile = true;    D->setModulePrivate(Record[Idx++]);    D->Hidden = D->isModulePrivate(); -   +    // Determine whether this declaration is part of a (sub)module. If so, it    // may not yet be visible.    if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) {      // Store the owning submodule ID in the declaration.      D->setOwningModuleID(SubmoduleID); -     -    // Module-private declarations are never visible, so there is no work to do. -    if (!D->isModulePrivate()) { -      if (Module *Owner = Reader.getSubmodule(SubmoduleID)) { -        if (Owner->NameVisibility != Module::AllVisible) { -          // The owning module is not visible. Mark this declaration as hidden. -          D->Hidden = true; -           -          // Note that this declaration was hidden because its owning module is  -          // not yet visible. -          Reader.HiddenNamesMap[Owner].HiddenDecls.push_back(D); -        } + +    if (D->Hidden) { +      // Module-private declarations are never visible, so there is no work to do. +    } else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { +      // If local visibility is being tracked, this declaration will become +      // hidden and visible as the owning module does. Inform Sema that this +      // declaration might not be visible. +      D->Hidden = true; +    } else if (Module *Owner = Reader.getSubmodule(SubmoduleID)) { +      if (Owner->NameVisibility != Module::AllVisible) { +        // The owning module is not visible. Mark this declaration as hidden. +        D->Hidden = true; +         +        // Note that this declaration was hidden because its owning module is  +        // not yet visible. +        Reader.HiddenNamesMap[Owner].push_back(D);        }      }    } @@ -470,8 +492,7 @@ void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {  void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {    VisitDecl(ND);    ND->setDeclName(Reader.ReadDeclarationName(F, Record, Idx)); -  if (needsAnonymousDeclarationNumber(ND)) -    AnonymousDeclNumber = Record[Idx++]; +  AnonymousDeclNumber = Record[Idx++];  }  void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { @@ -981,8 +1002,9 @@ void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {    D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));    D->setHasNonZeroConstructors(Record[Idx++]);    D->setHasDestructors(Record[Idx++]); -  std::tie(D->IvarInitializers, D->NumIvarInitializers) = -      Reader.ReadCXXCtorInitializers(F, Record, Idx); +  D->NumIvarInitializers = Record[Idx++]; +  if (D->NumIvarInitializers) +    D->IvarInitializers = Reader.ReadCXXCtorInitializersRef(F, Record, Idx);  } @@ -1041,13 +1063,15 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {    VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];    VD->VarDeclBits.TSCSpec = Record[Idx++];    VD->VarDeclBits.InitStyle = Record[Idx++]; -  VD->VarDeclBits.ExceptionVar = Record[Idx++]; -  VD->VarDeclBits.NRVOVariable = Record[Idx++]; -  VD->VarDeclBits.CXXForRangeDecl = Record[Idx++]; -  VD->VarDeclBits.ARCPseudoStrong = Record[Idx++]; -  VD->VarDeclBits.IsConstexpr = Record[Idx++]; -  VD->VarDeclBits.IsInitCapture = Record[Idx++]; -  VD->VarDeclBits.PreviousDeclInSameBlockScope = Record[Idx++]; +  if (!isa<ParmVarDecl>(VD)) { +    VD->NonParmVarDeclBits.ExceptionVar = Record[Idx++]; +    VD->NonParmVarDeclBits.NRVOVariable = Record[Idx++]; +    VD->NonParmVarDeclBits.CXXForRangeDecl = Record[Idx++]; +    VD->NonParmVarDeclBits.ARCPseudoStrong = Record[Idx++]; +    VD->NonParmVarDeclBits.IsConstexpr = Record[Idx++]; +    VD->NonParmVarDeclBits.IsInitCapture = Record[Idx++]; +    VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record[Idx++]; +  }    Linkage VarLinkage = Linkage(Record[Idx++]);    VD->setCachedLinkage(VarLinkage); @@ -1189,13 +1213,13 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {    D->LocStart = ReadSourceLocation(Record, Idx);    D->RBraceLoc = ReadSourceLocation(Record, Idx); +  // Defer loading the anonymous namespace until we've finished merging +  // this namespace; loading it might load a later declaration of the +  // same namespace, and we have an invariant that older declarations +  // get merged before newer ones try to merge. +  GlobalDeclID AnonNamespace = 0;    if (Redecl.getFirstID() == ThisDeclID) { -    // Each module has its own anonymous namespace, which is disjoint from -    // any other module's anonymous namespaces, so don't attach the anonymous -    // namespace at all. -    NamespaceDecl *Anon = ReadDeclAs<NamespaceDecl>(Record, Idx); -    if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) -      D->setAnonymousNamespace(Anon); +    AnonNamespace = ReadDeclID(Record, Idx);    } else {      // Link this namespace back to the first declaration, which has already      // been deserialized. @@ -1203,6 +1227,15 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {    }    mergeRedeclarable(D, Redecl); + +  if (AnonNamespace) { +    // Each module has its own anonymous namespace, which is disjoint from +    // any other module's anonymous namespaces, so don't attach the anonymous +    // namespace at all. +    NamespaceDecl *Anon = cast<NamespaceDecl>(Reader.GetDecl(AnonNamespace)); +    if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) +      D->setAnonymousNamespace(Anon); +  }  }  void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { @@ -1353,7 +1386,7 @@ void ASTDeclReader::ReadCXXDefinitionData(  }  void ASTDeclReader::MergeDefinitionData( -    CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &MergeDD) { +    CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &&MergeDD) {    assert(D->DefinitionData.getNotUpdated() &&           "merging class definition into non-definition");    auto &DD = *D->DefinitionData.getNotUpdated(); @@ -1364,14 +1397,45 @@ void ASTDeclReader::MergeDefinitionData(    // 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 (MergeDD.DeclaredSpecialMembers && DD.Definition != MergeDD.Definition) { +  if (DD.Definition != MergeDD.Definition) {      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); +      } +    } +  } + +  auto PFDI = Reader.PendingFakeDefinitionData.find(&DD); +  if (PFDI != Reader.PendingFakeDefinitionData.end() && +      PFDI->second == ASTReader::PendingFakeDefinitionKind::Fake) { +    // We faked up this definition data because we found a class for which we'd +    // not yet loaded the definition. Replace it with the real thing now. +    assert(!DD.IsLambda && !MergeDD.IsLambda && "faked up lambda definition?"); +    PFDI->second = ASTReader::PendingFakeDefinitionKind::FakeLoaded; + +    // Don't change which declaration is the definition; that is required +    // to be invariant once we select it. +    auto *Def = DD.Definition; +    DD = std::move(MergeDD); +    DD.Definition = Def; +    return;    }    // FIXME: Move this out into a .def file? -  // FIXME: Issue a diagnostic on a mismatched MATCH_FIELD, rather than -  // asserting; this can happen in the case of an ODR violation.    bool DetectedOdrViolation = false;  #define OR_FIELD(Field) DD.Field |= MergeDD.Field;  #define MATCH_FIELD(Field) \ @@ -1442,7 +1506,7 @@ void ASTDeclReader::MergeDefinitionData(      Reader.PendingOdrMergeFailures[DD.Definition].push_back(MergeDD.Definition);  } -void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) { +void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) {    struct CXXRecordDecl::DefinitionData *DD;    ASTContext &C = Reader.getContext(); @@ -1457,19 +1521,29 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) {    ReadCXXDefinitionData(*DD, Record, Idx); -  // If we're reading an update record, we might already have a definition for -  // this record. If so, just merge into it. -  if (D->DefinitionData.getNotUpdated()) { -    MergeDefinitionData(D, *DD); +  // We might already have a definition for this record. This can happen either +  // 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)); +    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. -  CXXRecordDecl *Canon = D->getCanonicalDecl();    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 @@ -1478,7 +1552,7 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) {          std::make_pair(D, CanonDD->Definition));      D->DefinitionData = Canon->DefinitionData;      D->IsCompleteDefinition = false; -    MergeDefinitionData(D, *DD); +    MergeDefinitionData(D, std::move(*DD));    } else {      Canon->DefinitionData = DD;      D->DefinitionData = Canon->DefinitionData; @@ -1535,7 +1609,7 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {    bool WasDefinition = Record[Idx++];    if (WasDefinition) -    ReadCXXRecordDefinition(D); +    ReadCXXRecordDefinition(D, /*Update*/false);    else      // Propagate DefinitionData pointer from the canonical declaration.      D->DefinitionData = D->getCanonicalDecl()->DefinitionData; @@ -1576,17 +1650,20 @@ void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {    VisitCXXMethodDecl(D);    if (auto *CD = ReadDeclAs<CXXConstructorDecl>(Record, Idx)) -    D->setInheritedConstructor(CD); +    if (D->isCanonicalDecl()) +      D->setInheritedConstructor(CD->getCanonicalDecl());    D->IsExplicitSpecified = Record[Idx++]; -  // FIXME: We should defer loading this until we need the constructor's body. -  std::tie(D->CtorInitializers, D->NumCtorInitializers) = -      Reader.ReadCXXCtorInitializers(F, Record, Idx);  }  void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {    VisitCXXMethodDecl(D); -  D->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx); +  if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx)) { +    auto *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl()); +    // FIXME: Check consistency if we have an old and new operator delete. +    if (!Canon->OperatorDelete) +      Canon->OperatorDelete = OperatorDelete; +  }  }  void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { @@ -1690,36 +1767,34 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {    return Redecl;  } +static DeclID *newDeclIDList(ASTContext &Context, DeclID *Old, +                             SmallVectorImpl<DeclID> &IDs) { +  assert(!IDs.empty() && "no IDs to add to list"); +  if (Old) { +    IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]); +    std::sort(IDs.begin(), IDs.end()); +    IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); +  } + +  auto *Result = new (Context) DeclID[1 + IDs.size()]; +  *Result = IDs.size(); +  std::copy(IDs.begin(), IDs.end(), Result + 1); +  return Result; +} +  void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {    RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);    if (ThisDeclID == Redecl.getFirstID()) {      // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of      // the specializations. -    SmallVector<serialization::DeclID, 2> SpecIDs; -    SpecIDs.push_back(0); -     -    // Specializations. -    unsigned Size = Record[Idx++]; -    SpecIDs[0] += Size; -    for (unsigned I = 0; I != Size; ++I) -      SpecIDs.push_back(ReadDeclID(Record, Idx)); - -    // Partial specializations. -    Size = Record[Idx++]; -    SpecIDs[0] += Size; -    for (unsigned I = 0; I != Size; ++I) -      SpecIDs.push_back(ReadDeclID(Record, Idx)); - -    ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr(); -    if (SpecIDs[0]) { -      typedef serialization::DeclID DeclID; -       -      // FIXME: Append specializations! -      CommonPtr->LazySpecializations -        = new (Reader.getContext()) DeclID [SpecIDs.size()]; -      memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),  -             SpecIDs.size() * sizeof(DeclID)); +    SmallVector<serialization::DeclID, 32> SpecIDs; +    ReadDeclIDList(SpecIDs); + +    if (!SpecIDs.empty()) { +      auto *CommonPtr = D->getCommonPtr(); +      CommonPtr->LazySpecializations = newDeclIDList( +          Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);      }    } @@ -1741,30 +1816,13 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {    if (ThisDeclID == Redecl.getFirstID()) {      // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of      // the specializations. -    SmallVector<serialization::DeclID, 2> SpecIDs; -    SpecIDs.push_back(0); - -    // Specializations. -    unsigned Size = Record[Idx++]; -    SpecIDs[0] += Size; -    for (unsigned I = 0; I != Size; ++I) -      SpecIDs.push_back(ReadDeclID(Record, Idx)); - -    // Partial specializations. -    Size = Record[Idx++]; -    SpecIDs[0] += Size; -    for (unsigned I = 0; I != Size; ++I) -      SpecIDs.push_back(ReadDeclID(Record, Idx)); - -    VarTemplateDecl::Common *CommonPtr = D->getCommonPtr(); -    if (SpecIDs[0]) { -      typedef serialization::DeclID DeclID; +    SmallVector<serialization::DeclID, 32> SpecIDs; +    ReadDeclIDList(SpecIDs); -      // FIXME: Append specializations! -      CommonPtr->LazySpecializations = -          new (Reader.getContext()) DeclID[SpecIDs.size()]; -      memcpy(CommonPtr->LazySpecializations, SpecIDs.data(), -             SpecIDs.size() * sizeof(DeclID)); +    if (!SpecIDs.empty()) { +      auto *CommonPtr = D->getCommonPtr(); +      CommonPtr->LazySpecializations = newDeclIDList( +          Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);      }    }  } @@ -1823,7 +1881,7 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(          // definition.          if (auto *DDD = D->DefinitionData.getNotUpdated()) {            if (auto *CanonDD = CanonSpec->DefinitionData.getNotUpdated()) { -            MergeDefinitionData(CanonSpec, *DDD); +            MergeDefinitionData(CanonSpec, std::move(*DDD));              Reader.PendingDefinitions.erase(D);              Reader.MergedDeclContexts.insert(                  std::make_pair(D, CanonDD->Definition)); @@ -1876,17 +1934,13 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {    if (ThisDeclID == Redecl.getFirstID()) {      // This FunctionTemplateDecl owns a CommonPtr; read it. +    SmallVector<serialization::DeclID, 32> SpecIDs; +    ReadDeclIDList(SpecIDs); -    // Read the function specialization declaration IDs. The specializations -    // themselves will be loaded if they're needed. -    if (unsigned NumSpecs = Record[Idx++]) { -      // FIXME: Append specializations! -      FunctionTemplateDecl::Common *CommonPtr = D->getCommonPtr(); -      CommonPtr->LazySpecializations = new (Reader.getContext()) -          serialization::DeclID[NumSpecs + 1]; -      CommonPtr->LazySpecializations[0] = NumSpecs; -      for (unsigned I = 0; I != NumSpecs; ++I) -        CommonPtr->LazySpecializations[I + 1] = ReadDeclID(Record, Idx); +    if (!SpecIDs.empty()) { +      auto *CommonPtr = D->getCommonPtr(); +      CommonPtr->LazySpecializations = newDeclIDList( +          Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);      }    }  } @@ -2049,15 +2103,25 @@ ASTDeclReader::VisitDeclContext(DeclContext *DC) {  }  template <typename T> -ASTDeclReader::RedeclarableResult  +ASTDeclReader::RedeclarableResult  ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {    DeclID FirstDeclID = ReadDeclID(Record, Idx); -   +  Decl *MergeWith = nullptr; +    // 0 indicates that this declaration was the only declaration of its entity,    // and is used for space optimization.    if (FirstDeclID == 0)      FirstDeclID = ThisDeclID; -   +  else if (unsigned N = Record[Idx++]) { +    // We have some declarations that must be before us in our redeclaration +    // chain. Read them now, and remember that we ought to merge with one of +    // them. +    // FIXME: Provide a known merge target to the second and subsequent such +    // declaration. +    for (unsigned I = 0; I != N; ++I) +      MergeWith = ReadDecl(Record, Idx/*, MergeWith*/); +  } +    T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));    if (FirstDecl != D) {      // We delay loading of the redeclaration chain to avoid deeply nested calls. @@ -2065,6 +2129,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {      // which is the one that matters and mark the real previous DeclID to be      // loaded & attached later on.      D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl); +    D->First = FirstDecl->getCanonicalDecl();    }        // Note that this declaration has been deserialized. @@ -2072,7 +2137,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {    // The result structure takes care to note that we need to load the     // other declaration chains for this ID. -  return RedeclarableResult(Reader, FirstDeclID, +  return RedeclarableResult(Reader, FirstDeclID, MergeWith,                              static_cast<T *>(D)->getKind());  } @@ -2083,23 +2148,19 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,                                        RedeclarableResult &Redecl,                                        DeclID TemplatePatternID) {    T *D = static_cast<T*>(DBase); -  T *DCanon = D->getCanonicalDecl(); -  if (D != DCanon && -      // IDs < NUM_PREDEF_DECL_IDS are not loaded from an AST file. -      Redecl.getFirstID() >= NUM_PREDEF_DECL_IDS && -      (!Reader.getContext().getLangOpts().Modules || -       Reader.getOwningModuleFile(DCanon) == Reader.getOwningModuleFile(D))) { -    // All redeclarations between this declaration and its originally-canonical -    // declaration get pulled in when we load DCanon; we don't need to -    // perform any more merging now. -    Redecl.suppress(); -  }    // If modules are not available, there is no reason to perform this merge.    if (!Reader.getContext().getLangOpts().Modules)      return; -  if (FindExistingResult ExistingRes = findExisting(D)) +  // If we're not the canonical declaration, we don't need to merge. +  if (!DBase->isFirstDecl()) +    return; + +  if (auto *Existing = Redecl.getKnownMergeTarget()) +    // We already know of an existing declaration we should merge with. +    mergeRedeclarable(D, cast<T>(Existing), Redecl, TemplatePatternID); +  else if (FindExistingResult ExistingRes = findExisting(D))      if (T *Existing = ExistingRes)        mergeRedeclarable(D, Existing, Redecl, TemplatePatternID);  } @@ -2120,7 +2181,8 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,    auto *DPattern = D->getTemplatedDecl();    auto *ExistingPattern = Existing->getTemplatedDecl();    RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(), -                            DPattern->getKind()); +                            /*MergeWith*/ExistingPattern, DPattern->getKind()); +    if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {      // Merge with any existing definition.      // FIXME: This is duplicated in several places. Refactor. @@ -2128,13 +2190,14 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,          cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl();      if (auto *DDD = DClass->DefinitionData.getNotUpdated()) {        if (auto *ExistingDD = ExistingClass->DefinitionData.getNotUpdated()) { -        MergeDefinitionData(ExistingClass, *DDD); +        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; +        Reader.PendingDefinitions.insert(DClass);        }      }      DClass->DefinitionData = ExistingClass->DefinitionData; @@ -2163,14 +2226,18 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,    T *ExistingCanon = Existing->getCanonicalDecl();    T *DCanon = D->getCanonicalDecl();    if (ExistingCanon != DCanon) { -    assert(DCanon->getGlobalID() == Redecl.getFirstID()); +    assert(DCanon->getGlobalID() == Redecl.getFirstID() && +           "already merged this declaration");      // Have our redeclaration link point back at the canonical declaration      // of the existing declaration, so that this declaration has the      // appropriate canonical declaration.      D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon); +    D->First = ExistingCanon;      // When we merge a namespace, update its pointer to the first namespace. +    // We cannot have loaded any redeclarations of this declaration yet, so +    // there's nothing else that needs to be updated.      if (auto *Namespace = dyn_cast<NamespaceDecl>(D))        Namespace->AnonOrFirstNamespaceAndInline.setPointer(            assert_cast<NamespaceDecl*>(ExistingCanon)); @@ -2181,14 +2248,11 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,            DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),            TemplatePatternID); -    // If this declaration was the canonical declaration, make a note of -    // that. We accept the linear algorithm here because the number of -    // unique canonical declarations of an entity should always be tiny. +    // If this declaration was the canonical declaration, make a note of that.      if (DCanon == D) { -      SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon]; -      if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID()) -            == Merged.end()) -        Merged.push_back(Redecl.getFirstID()); +      Reader.MergedDecls[ExistingCanon].push_back(Redecl.getFirstID()); +      if (Reader.PendingDeclChainsKnown.insert(ExistingCanon).second) +        Reader.PendingDeclChains.push_back(ExistingCanon);      }    }  } @@ -2529,42 +2593,71 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {  /// Find the context in which we should search for previous declarations when  /// looking for declarations to merge. -static DeclContext *getPrimaryContextForMerging(DeclContext *DC) { +DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader, +                                                        DeclContext *DC) {    if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))      return ND->getOriginalNamespace(); -  // There is one tricky case here: if DC is a class with no definition, then -  // we're merging a declaration whose definition is added by an update record, -  // but we've not yet loaded that update record. In this case, we use the -  // canonical declaration for merging until we get a real definition. -  // FIXME: When we add a definition, we may need to move the partial lookup -  // information from the canonical declaration onto the chosen definition. -  if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) -    return RD->getPrimaryContext(); +  if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) { +    // Try to dig out the definition. +    auto *DD = RD->DefinitionData.getNotUpdated(); +    if (!DD) +      DD = RD->getCanonicalDecl()->DefinitionData.getNotUpdated(); + +    // If there's no definition yet, then DC's definition is added by an update +    // record, but we've not yet loaded that update record. In this case, we +    // commit to DC being the canonical definition now, and will fix this when +    // we load the update record. +    if (!DD) { +      DD = new (Reader.Context) struct CXXRecordDecl::DefinitionData(RD); +      RD->IsCompleteDefinition = true; +      RD->DefinitionData = DD; +      RD->getCanonicalDecl()->DefinitionData = DD; + +      // Track that we did this horrible thing so that we can fix it later. +      Reader.PendingFakeDefinitionData.insert( +          std::make_pair(DD, ASTReader::PendingFakeDefinitionKind::Fake)); +    } + +    return DD->Definition; +  }    if (EnumDecl *ED = dyn_cast<EnumDecl>(DC))      return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()                                                        : nullptr; +  // We can see the TU here only if we have no Sema object. In that case, +  // there's no TU scope to look in, so using the DC alone is sufficient. +  if (auto *TU = dyn_cast<TranslationUnitDecl>(DC)) +    return TU; +    return nullptr;  }  ASTDeclReader::FindExistingResult::~FindExistingResult() { +  // Record that we had a typedef name for linkage whether or not we merge +  // with that declaration. +  if (TypedefNameForLinkage) { +    DeclContext *DC = New->getDeclContext()->getRedeclContext(); +    Reader.ImportedTypedefNamesForLinkage.insert( +        std::make_pair(std::make_pair(DC, TypedefNameForLinkage), New)); +    return; +  } +    if (!AddResult || Existing)      return;    DeclarationName Name = New->getDeclName();    DeclContext *DC = New->getDeclContext()->getRedeclContext(); -  if (TypedefNameForLinkage) { -    Reader.ImportedTypedefNamesForLinkage.insert( -        std::make_pair(std::make_pair(DC, TypedefNameForLinkage), New)); -  } else if (!Name) { -    assert(needsAnonymousDeclarationNumber(New)); +  if (needsAnonymousDeclarationNumber(New)) {      setAnonymousDeclForMerging(Reader, New->getLexicalDeclContext(),                                 AnonymousDeclNumber, New); -  } else if (DC->isTranslationUnit() && Reader.SemaObj) { -    Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, Name); -  } else if (DeclContext *MergeDC = getPrimaryContextForMerging(DC)) { +  } else if (DC->isTranslationUnit() && Reader.SemaObj && +             !Reader.getContext().getLangOpts().CPlusPlus) { +    if (Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, Name)) +      Reader.PendingFakeLookupResults[Name.getAsIdentifierInfo()] +            .push_back(New); +  } else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) {      // Add the declaration to its redeclaration context so later merging      // lookups will find it.      MergeDC->makeDeclVisibleInContextImpl(New, /*Internal*/true); @@ -2582,12 +2675,11 @@ static NamedDecl *getDeclForMerging(NamedDecl *Found,    // If we found a typedef declaration that gives a name to some other    // declaration, then we want that inner declaration. Declarations from    // AST files are handled via ImportedTypedefNamesForLinkage. -  if (Found->isFromASTFile()) return 0; -  if (auto *TND = dyn_cast<TypedefNameDecl>(Found)) { -    if (auto *TT = TND->getTypeSourceInfo()->getType()->getAs<TagType>()) -      if (TT->getDecl()->getTypedefNameForAnonDecl() == TND) -        return TT->getDecl(); -  } +  if (Found->isFromASTFile()) +    return 0; + +  if (auto *TND = dyn_cast<TypedefNameDecl>(Found)) +    return TND->getAnonDeclWithTypedefName();    return 0;  } @@ -2608,17 +2700,12 @@ NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader,    // If this is the first time, but we have parsed a declaration of the context,    // build the anonymous declaration list from the parsed declaration.    if (!cast<Decl>(DC)->isFromASTFile()) { -    unsigned Index = 0; -    for (Decl *LexicalD : DC->decls()) { -      auto *ND = dyn_cast<NamedDecl>(LexicalD); -      if (!ND || !needsAnonymousDeclarationNumber(ND)) -        continue; -      if (Previous.size() == Index) +    numberAnonymousDeclsWithin(DC, [&](NamedDecl *ND, unsigned Number) { +      if (Previous.size() == Number)          Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl()));        else -        Previous[Index] = cast<NamedDecl>(ND->getCanonicalDecl()); -      ++Index; -    } +        Previous[Number] = cast<NamedDecl>(ND->getCanonicalDecl()); +    });    }    return Index < Previous.size() ? Previous[Index] : nullptr; @@ -2646,8 +2733,6 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {      // unmergeable contexts.      FindExistingResult Result(Reader, D, /*Existing=*/nullptr,                                AnonymousDeclNumber, TypedefNameForLinkage); -    // FIXME: We may still need to pull in the redeclaration chain; there can -    // be redeclarations via 'decltype'.      Result.suppress();      return Result;    } @@ -2667,16 +2752,16 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {      // was not imported.    } -  if (!Name) { +  if (needsAnonymousDeclarationNumber(D)) {      // This is an anonymous declaration that we may need to merge. Look it up      // in its context by number. -    assert(needsAnonymousDeclarationNumber(D));      if (auto *Existing = getAnonymousDeclForMerging(              Reader, D->getLexicalDeclContext(), AnonymousDeclNumber))        if (isSameEntity(Existing, D))          return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,                                    TypedefNameForLinkage); -  } else if (DC->isTranslationUnit() && Reader.SemaObj) { +  } else if (DC->isTranslationUnit() && Reader.SemaObj && +             !Reader.getContext().getLangOpts().CPlusPlus) {      IdentifierResolver &IdResolver = Reader.SemaObj->IdResolver;      // Temporarily consider the identifier to be up-to-date. We don't want to @@ -2710,7 +2795,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {            return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,                                      TypedefNameForLinkage);      } -  } else if (DeclContext *MergeDC = getPrimaryContextForMerging(DC)) { +  } else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) {      DeclContext::lookup_result R = MergeDC->noload_lookup(Name);      for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) {        if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage)) @@ -2738,20 +2823,47 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {  }  template<typename DeclT> +Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *D) { +  return D->RedeclLink.getLatestNotUpdated(); +} +Decl *ASTDeclReader::getMostRecentDeclImpl(...) { +  llvm_unreachable("getMostRecentDecl on non-redeclarable declaration"); +} + +Decl *ASTDeclReader::getMostRecentDecl(Decl *D) { +  assert(D); + +  switch (D->getKind()) { +#define ABSTRACT_DECL(TYPE) +#define DECL(TYPE, BASE)                               \ +  case Decl::TYPE:                                     \ +    return getMostRecentDeclImpl(cast<TYPE##Decl>(D)); +#include "clang/AST/DeclNodes.inc" +  } +  llvm_unreachable("unknown decl kind"); +} + +Decl *ASTReader::getMostRecentExistingDecl(Decl *D) { +  return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl()); +} + +template<typename DeclT>  void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,                                             Redeclarable<DeclT> *D, -                                           Decl *Previous) { +                                           Decl *Previous, Decl *Canon) {    D->RedeclLink.setPrevious(cast<DeclT>(Previous)); +  D->First = cast<DeclT>(Previous)->First;  }  namespace clang {  template<>  void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,                                             Redeclarable<FunctionDecl> *D, -                                           Decl *Previous) { +                                           Decl *Previous, Decl *Canon) {    FunctionDecl *FD = static_cast<FunctionDecl*>(D);    FunctionDecl *PrevFD = cast<FunctionDecl>(Previous);    FD->RedeclLink.setPrevious(PrevFD); +  FD->First = PrevFD->First;    // If the previous declaration is an inline function declaration, then this    // declaration is too. @@ -2774,16 +2886,17 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,      FD->IsInline = true;    } -  // If this declaration has an unresolved exception specification but the -  // previous declaration had a resolved one, resolve the exception -  // specification now. +  // If we need to propagate an exception specification along the redecl +  // chain, make a note of that so that we can do so later.    auto *FPT = FD->getType()->getAs<FunctionProtoType>();    auto *PrevFPT = PrevFD->getType()->getAs<FunctionProtoType>(); -  if (FPT && PrevFPT && -      isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) && -      !isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType())) { -    Reader.Context.adjustExceptionSpec( -        FD, PrevFPT->getExtProtoInfo().ExceptionSpec); +  if (FPT && PrevFPT) { +    bool IsUnresolved = isUnresolvedExceptionSpec(FPT->getExceptionSpecType()); +    bool WasUnresolved = +        isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType()); +    if (IsUnresolved != WasUnresolved) +      Reader.PendingExceptionSpecUpdates.insert( +          std::make_pair(Canon, IsUnresolved ? PrevFD : FD));    }  }  } @@ -2792,14 +2905,14 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {  }  void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D, -                                       Decl *Previous) { +                                       Decl *Previous, Decl *Canon) {    assert(D && Previous);    switch (D->getKind()) {  #define ABSTRACT_DECL(TYPE) -#define DECL(TYPE, BASE)                                           \ -  case Decl::TYPE:                                                 \ -    attachPreviousDeclImpl(Reader, cast<TYPE##Decl>(D), Previous); \ +#define DECL(TYPE, BASE)                                                  \ +  case Decl::TYPE:                                                        \ +    attachPreviousDeclImpl(Reader, cast<TYPE##Decl>(D), Previous, Canon); \      break;  #include "clang/AST/DeclNodes.inc"    } @@ -2859,29 +2972,6 @@ void ASTReader::markIncompleteDeclChain(Decl *D) {    }  } -ASTReader::MergedDeclsMap::iterator -ASTReader::combineStoredMergedDecls(Decl *Canon, GlobalDeclID CanonID) { -  // If we don't have any stored merged declarations, just look in the -  // merged declarations set. -  StoredMergedDeclsMap::iterator StoredPos = StoredMergedDecls.find(CanonID); -  if (StoredPos == StoredMergedDecls.end()) -    return MergedDecls.find(Canon); - -  // Append the stored merged declarations to the merged declarations set. -  MergedDeclsMap::iterator Pos = MergedDecls.find(Canon); -  if (Pos == MergedDecls.end()) -    Pos = MergedDecls.insert(std::make_pair(Canon, -                                            SmallVector<DeclID, 2>())).first; -  Pos->second.append(StoredPos->second.begin(), StoredPos->second.end()); -  StoredMergedDecls.erase(StoredPos); - -  // Sort and uniquify the set of merged declarations. -  llvm::array_pod_sort(Pos->second.begin(), Pos->second.end()); -  Pos->second.erase(std::unique(Pos->second.begin(), Pos->second.end()), -                    Pos->second.end()); -  return Pos; -} -  /// \brief Read the declaration at the given offset from the AST file.  Decl *ASTReader::ReadDeclRecord(DeclID ID) {    unsigned Index = ID - NUM_PREDEF_DECL_IDS; @@ -3086,6 +3176,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {    case DECL_CXX_BASE_SPECIFIERS:      Error("attempt to read a C++ base-specifier record as a declaration");      return nullptr; +  case DECL_CXX_CTOR_INITIALIZERS: +    Error("attempt to read a C++ ctor initializer record as a declaration"); +    return nullptr;    case DECL_IMPORT:      // Note: last entry of the ImportDecl record is the number of stored source       // locations. @@ -3199,47 +3292,55 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {  }  namespace { -  /// \brief Module visitor class that finds all of the redeclarations of a  -  ///  +  /// \brief Module visitor class that finds all of the redeclarations of a +  /// redeclarable declaration.    class RedeclChainVisitor {      ASTReader &Reader;      SmallVectorImpl<DeclID> &SearchDecls;      llvm::SmallPtrSetImpl<Decl *> &Deserialized;      GlobalDeclID CanonID;      SmallVector<Decl *, 4> Chain; -     +    public:      RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls,                         llvm::SmallPtrSetImpl<Decl *> &Deserialized,                         GlobalDeclID CanonID)        : Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized), -        CanonID(CanonID) {  -      for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I) -        addToChain(Reader.GetDecl(SearchDecls[I])); +        CanonID(CanonID) { +      // Ensure that the canonical ID goes at the start of the chain. +      addToChain(Reader.GetDecl(CanonID));      } -     -    static bool visit(ModuleFile &M, bool Preorder, void *UserData) { -      if (Preorder) -        return false; -       -      return static_cast<RedeclChainVisitor *>(UserData)->visit(M); + +    static ModuleManager::DFSPreorderControl +    visitPreorder(ModuleFile &M, void *UserData) { +      return static_cast<RedeclChainVisitor *>(UserData)->visitPreorder(M);      } -     + +    static bool visitPostorder(ModuleFile &M, void *UserData) { +      return static_cast<RedeclChainVisitor *>(UserData)->visitPostorder(M); +    } +      void addToChain(Decl *D) {        if (!D)          return; -       +        if (Deserialized.erase(D))          Chain.push_back(D);      } -     +      void searchForID(ModuleFile &M, GlobalDeclID GlobalID) {        // Map global ID of the first declaration down to the local ID        // used in this module file.        DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID);        if (!ID)          return; -       + +      // If the search decl was from this module, add it to the chain before any +      // of its redeclarations in this module or users of it, and after any from +      // imported modules. +      if (CanonID != GlobalID && Reader.isDeclIDFromModule(GlobalID, M)) +        addToChain(Reader.GetDecl(GlobalID)); +        // Perform a binary search to find the local redeclarations for this        // declaration (if any).        const LocalRedeclarationsInfo Compare = { ID, 0 }; @@ -3269,8 +3370,36 @@ namespace {        for (unsigned I = 0; I != N; ++I)          addToChain(Reader.GetLocalDecl(M, M.RedeclarationChains[Offset++]));      } -     -    bool visit(ModuleFile &M) { + +    bool needsToVisitImports(ModuleFile &M, GlobalDeclID GlobalID) { +      DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID); +      if (!ID) +        return false; + +      const LocalRedeclarationsInfo Compare = {ID, 0}; +      const LocalRedeclarationsInfo *Result = std::lower_bound( +          M.RedeclarationsMap, +          M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, Compare); +      if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap || +          Result->FirstID != ID) { +        return true; +      } +      unsigned Offset = Result->Offset; +      unsigned N = M.RedeclarationChains[Offset]; +      // We don't need to visit a module or any of its imports if we've already +      // deserialized the redecls from this module. +      return N != 0; +    } + +    ModuleManager::DFSPreorderControl visitPreorder(ModuleFile &M) { +      for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I) { +        if (needsToVisitImports(M, SearchDecls[I])) +          return ModuleManager::Continue; +      } +      return ModuleManager::SkipImports; +    } + +    bool visitPostorder(ModuleFile &M) {        // Visit each of the declarations.        for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)          searchForID(M, SearchDecls[I]); @@ -3285,41 +3414,46 @@ namespace {    };  } -void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { -  Decl *D = GetDecl(ID);   -  Decl *CanonDecl = D->getCanonicalDecl(); -   +void ASTReader::loadPendingDeclChain(Decl *CanonDecl) { +  // The decl might have been merged into something else after being added to +  // our list. If it was, just skip it. +  if (!CanonDecl->isCanonicalDecl()) +    return; +    // Determine the set of declaration IDs we'll be searching for. -  SmallVector<DeclID, 1> SearchDecls; -  GlobalDeclID CanonID = 0; -  if (D == CanonDecl) { -    SearchDecls.push_back(ID); // Always first. -    CanonID = ID; -  } -  MergedDeclsMap::iterator MergedPos = combineStoredMergedDecls(CanonDecl, ID); +  SmallVector<DeclID, 16> SearchDecls; +  GlobalDeclID CanonID = CanonDecl->getGlobalID(); +  if (CanonID) +    SearchDecls.push_back(CanonDecl->getGlobalID()); // Always first. +  MergedDeclsMap::iterator MergedPos = MergedDecls.find(CanonDecl);    if (MergedPos != MergedDecls.end())      SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end()); -   +    // Build up the list of redeclarations.    RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID); -  ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visit, &Visitor); -   +  ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visitPreorder, +                            &RedeclChainVisitor::visitPostorder, &Visitor); +    // Retrieve the chains.    ArrayRef<Decl *> Chain = Visitor.getChain(); -  if (Chain.empty()) +  if (Chain.empty() || (Chain.size() == 1 && Chain[0] == CanonDecl))      return; -     +    // Hook up the chains. -  Decl *MostRecent = CanonDecl->getMostRecentDecl(); +  // +  // FIXME: We have three different dispatches on decl kind here; maybe +  // we should instead generate one loop per kind and dispatch up-front? +  Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); +  if (!MostRecent) +    MostRecent = CanonDecl;    for (unsigned I = 0, N = Chain.size(); I != N; ++I) {      if (Chain[I] == CanonDecl)        continue; -    ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent); +    ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent, CanonDecl);      MostRecent = Chain[I];    } -   -  ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);   +  ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);  }  namespace { @@ -3513,13 +3647,25 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,    while (Idx < Record.size()) {      switch ((DeclUpdateKind)Record[Idx++]) {      case UPD_CXX_ADDED_IMPLICIT_MEMBER: { +      auto *RD = cast<CXXRecordDecl>(D);        // FIXME: If we also have an update record for instantiating the        // definition of D, we need that to happen before we get here.        Decl *MD = Reader.ReadDecl(ModuleFile, Record, Idx);        assert(MD && "couldn't read decl from update record");        // FIXME: We should call addHiddenDecl instead, to add the member        // to its DeclContext. -      cast<CXXRecordDecl>(D)->addedMember(MD); +      RD->addedMember(MD); + +      // If we've added a new special member to a class definition that is not +      // the canonical definition, then we need special member lookups in the +      // canonical definition to also look into our class. +      auto *DD = RD->DefinitionData.getNotUpdated(); +      if (DD && DD->Definition != RD) { +        auto &Merged = Reader.MergedLookups[DD->Definition]; +        // FIXME: Avoid the linear-time scan here. +        if (std::find(Merged.begin(), Merged.end(), RD) == Merged.end()) +          Merged.push_back(RD); +      }        break;      } @@ -3567,13 +3713,12 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,          });        }        FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx)); -      if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) -        std::tie(CD->CtorInitializers, CD->NumCtorInitializers) = -            Reader.ReadCXXCtorInitializers(ModuleFile, Record, Idx); -      if (auto *DD = dyn_cast<CXXDestructorDecl>(FD)) -        // FIXME: Check consistency. -        DD->setOperatorDelete(Reader.ReadDeclAs<FunctionDecl>(ModuleFile, -                                                              Record, Idx)); +      if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) { +        CD->NumCtorInitializers = Record[Idx++]; +        if (CD->NumCtorInitializers) +          CD->CtorInitializers = +              Reader.ReadCXXCtorInitializersRef(F, Record, Idx); +      }        // Store the offset of the body so we can lazily load it later.        Reader.PendingBodies[FD] = GetCurrentCursorOffset();        HasPendingBody = true; @@ -3583,16 +3728,20 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,      case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {        auto *RD = cast<CXXRecordDecl>(D); -      bool HadDefinition = RD->getDefinition(); -      ReadCXXRecordDefinition(RD); +      auto *OldDD = RD->DefinitionData.getNotUpdated(); +      bool HadRealDefinition = +          OldDD && (OldDD->Definition != RD || +                    !Reader.PendingFakeDefinitionData.count(OldDD)); +      ReadCXXRecordDefinition(RD, /*Update*/true); +        // Visible update is handled separately.        uint64_t LexicalOffset = Record[Idx++]; -      if (!HadDefinition && LexicalOffset) { +      if (!HadRealDefinition && LexicalOffset) {          RD->setHasExternalLexicalStorage(true);          Reader.ReadDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor, -                                          std::make_pair(LexicalOffset, 0), -                                          ModuleFile.DeclContextInfos[RD]); -        Reader.PendingDefinitions.insert(RD); +                                      std::make_pair(LexicalOffset, 0), +                                      ModuleFile.DeclContextInfos[RD]); +        Reader.PendingFakeDefinitionData.erase(OldDD);        }        auto TSK = (TemplateSpecializationKind)Record[Idx++]; @@ -3636,24 +3785,36 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,        break;      } +    case UPD_CXX_RESOLVED_DTOR_DELETE: { +      // Set the 'operator delete' directly to avoid emitting another update +      // record. +      auto *Del = Reader.ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx); +      auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl()); +      // FIXME: Check consistency if we have an old and new operator delete. +      if (!First->OperatorDelete) +        First->OperatorDelete = Del; +      break; +    } +      case UPD_CXX_RESOLVED_EXCEPTION_SPEC: { -      // FIXME: This doesn't send the right notifications if there are -      // ASTMutationListeners other than an ASTWriter.        FunctionProtoType::ExceptionSpecInfo ESI;        SmallVector<QualType, 8> ExceptionStorage;        Reader.readExceptionSpec(ModuleFile, ExceptionStorage, ESI, Record, Idx); -      for (auto *Redecl : merged_redecls(D)) { -        auto *FD = cast<FunctionDecl>(Redecl); -        auto *FPT = FD->getType()->castAs<FunctionProtoType>(); -        if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { -          // AST invariant: if any exception spec in the redecl chain is -          // resolved, all are resolved. We don't need to go any further. -          // FIXME: If the exception spec is resolved, check that it matches. -          break; -        } + +      // Update this declaration's exception specification, if needed. +      auto *FD = cast<FunctionDecl>(D); +      auto *FPT = FD->getType()->castAs<FunctionProtoType>(); +      // FIXME: If the exception specification is already present, check that it +      // matches. +      if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {          FD->setType(Reader.Context.getFunctionType(              FPT->getReturnType(), FPT->getParamTypes(),              FPT->getExtProtoInfo().withExceptionSpec(ESI))); + +        // When we get to the end of deserializing, see if there are other decls +        // that we need to propagate this exception specification onto. +        Reader.PendingExceptionSpecUpdates.insert( +            std::make_pair(FD->getCanonicalDecl(), FD));        }        break;      } @@ -3685,10 +3846,30 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,      case UPD_STATIC_LOCAL_NUMBER:        Reader.Context.setStaticLocalNumber(cast<VarDecl>(D), Record[Idx++]);        break; +      case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:        D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(            Reader.Context, ReadSourceRange(Record, Idx)));        break; + +    case UPD_DECL_EXPORTED: +      unsigned SubmoduleID = readSubmoduleID(Record, Idx); +      Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr; +      if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { +        // FIXME: This doesn't send the right notifications if there are +        // ASTMutationListeners other than an ASTWriter. +        Reader.getContext().mergeDefinitionIntoModule(cast<NamedDecl>(D), Owner, +                                                      /*NotifyListeners*/false); +        Reader.PendingMergedDefinitionsToDeduplicate.insert(cast<NamedDecl>(D)); +      } else if (Owner && Owner->NameVisibility != Module::AllVisible) { +        // If Owner is made visible at some later point, make this declaration +        // visible too. +        Reader.HiddenNamesMap[Owner].push_back(D); +      } else { +        // The declaration is now visible. +        D->Hidden = false; +      } +      break;      }    }  } | 
