diff options
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
| -rw-r--r-- | lib/Serialization/ASTWriter.cpp | 1345 | 
1 files changed, 581 insertions, 764 deletions
| diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 6c60d45503de..bf74c8471c3d 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -60,14 +60,14 @@ using namespace clang;  using namespace clang::serialization;  template <typename T, typename Allocator> -static StringRef data(const std::vector<T, Allocator> &v) { +static StringRef bytes(const std::vector<T, Allocator> &v) {    if (v.empty()) return StringRef();    return StringRef(reinterpret_cast<const char*>(&v[0]),                           sizeof(T) * v.size());  }  template <typename T> -static StringRef data(const SmallVectorImpl<T> &v) { +static StringRef bytes(const SmallVectorImpl<T> &v) {    return StringRef(reinterpret_cast<const char*>(v.data()),                           sizeof(T) * v.size());  } @@ -867,6 +867,7 @@ void ASTWriter::WriteBlockInfoBlock() {    RECORD(MODULE_NAME);    RECORD(MODULE_MAP_FILE);    RECORD(IMPORTS); +  RECORD(KNOWN_MODULE_FILES);    RECORD(LANGUAGE_OPTIONS);    RECORD(TARGET_OPTIONS);    RECORD(ORIGINAL_FILE); @@ -892,7 +893,6 @@ void ASTWriter::WriteBlockInfoBlock() {    RECORD(STATISTICS);    RECORD(TENTATIVE_DEFINITIONS);    RECORD(UNUSED_FILESCOPED_DECLS); -  RECORD(LOCALLY_SCOPED_EXTERN_C_DECLS);    RECORD(SELECTOR_OFFSETS);    RECORD(METHOD_POOL);    RECORD(PP_COUNTER_VALUE); @@ -924,11 +924,9 @@ void ASTWriter::WriteBlockInfoBlock() {    RECORD(OBJC_CATEGORIES_MAP);    RECORD(FILE_SORTED_DECLS);    RECORD(IMPORTED_MODULES); -  RECORD(MERGED_DECLARATIONS);    RECORD(LOCAL_REDECLARATIONS);    RECORD(OBJC_CATEGORIES);    RECORD(MACRO_OFFSET); -  RECORD(MACRO_TABLE);    RECORD(LATE_PARSED_TEMPLATE);    RECORD(OPTIMIZE_PRAGMA_OPTIONS); @@ -941,10 +939,12 @@ void ASTWriter::WriteBlockInfoBlock() {    // Preprocessor Block.    BLOCK(PREPROCESSOR_BLOCK); -  RECORD(PP_MACRO_OBJECT_LIKE); +  RECORD(PP_MACRO_DIRECTIVE_HISTORY);    RECORD(PP_MACRO_FUNCTION_LIKE); +  RECORD(PP_MACRO_OBJECT_LIKE); +  RECORD(PP_MODULE_MACRO);    RECORD(PP_TOKEN); -   +    // Decls and Types block.    BLOCK(DECLTYPES_BLOCK);    RECORD(TYPE_EXT_QUAL); @@ -1062,7 +1062,8 @@ void ASTWriter::WriteBlockInfoBlock() {  /// to an absolute path and removing nested './'s.  ///  /// \return \c true if the path was changed. -bool cleanPathForOutput(FileManager &FileMgr, SmallVectorImpl<char> &Path) { +static bool cleanPathForOutput(FileManager &FileMgr, +                               SmallVectorImpl<char> &Path) {    bool Changed = false;    if (!llvm::sys::path::is_absolute(StringRef(Path.data(), Path.size()))) { @@ -1159,12 +1160,17 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,    Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,                              getClangFullRepositoryVersion()); -  // Signature -  Record.clear(); -  Record.push_back(getSignature()); -  Stream.EmitRecord(SIGNATURE, Record); -    if (WritingModule) { +    // For implicit modules we output a signature that we can use to ensure +    // duplicate module builds don't collide in the cache as their output order +    // is non-deterministic. +    // FIXME: Remove this when output is deterministic. +    if (Context.getLangOpts().ImplicitModules) { +      Record.clear(); +      Record.push_back(getSignature()); +      Stream.EmitRecord(SIGNATURE, Record); +    } +      // Module name      BitCodeAbbrev *Abbrev = new BitCodeAbbrev();      Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME)); @@ -1222,20 +1228,28 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,      serialization::ModuleManager &Mgr = Chain->getModuleManager();      Record.clear(); -    for (ModuleManager::ModuleIterator M = Mgr.begin(), MEnd = Mgr.end(); -         M != MEnd; ++M) { +    for (auto *M : Mgr) {        // Skip modules that weren't directly imported. -      if (!(*M)->isDirectlyImported()) +      if (!M->isDirectlyImported())          continue; -      Record.push_back((unsigned)(*M)->Kind); // FIXME: Stable encoding -      AddSourceLocation((*M)->ImportLoc, Record); -      Record.push_back((*M)->File->getSize()); -      Record.push_back((*M)->File->getModificationTime()); -      Record.push_back((*M)->Signature); -      AddPath((*M)->FileName, Record); +      Record.push_back((unsigned)M->Kind); // FIXME: Stable encoding +      AddSourceLocation(M->ImportLoc, Record); +      Record.push_back(M->File->getSize()); +      Record.push_back(M->File->getModificationTime()); +      Record.push_back(M->Signature); +      AddPath(M->FileName, Record);      }      Stream.EmitRecord(IMPORTS, Record); + +    // Also emit a list of known module files that were not imported, +    // but are made available by this module. +    // FIXME: Should we also include a signature here? +    Record.clear(); +    for (auto *E : Mgr.getAdditionalKnownModuleFiles()) +      AddPath(E->getName(), Record); +    if (!Record.empty()) +      Stream.EmitRecord(KNOWN_MODULE_FILES, Record);    }    // Language options. @@ -1341,6 +1355,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,    Record.push_back(HSOpts.UseStandardSystemIncludes);    Record.push_back(HSOpts.UseStandardCXXIncludes);    Record.push_back(HSOpts.UseLibcxx); +  // Write out the specific module cache path that contains the module files. +  AddString(PP.getHeaderSearchInfo().getModuleCachePath(), Record);    Stream.EmitRecord(HEADER_SEARCH_OPTIONS, Record);    // Preprocessor options. @@ -1467,7 +1483,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,    unsigned UserFilesNum = 0;    // Write out all of the input files. -  std::vector<uint32_t> InputFileOffsets; +  std::vector<uint64_t> InputFileOffsets;    for (std::deque<InputFileEntry>::iterator           I = SortedFiles.begin(), E = SortedFiles.end(); I != E; ++I) {      const InputFileEntry &Entry = *I; @@ -1514,7 +1530,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,    Record.push_back(INPUT_FILE_OFFSETS);    Record.push_back(InputFileOffsets.size());    Record.push_back(UserFilesNum); -  Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, data(InputFileOffsets)); +  Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, bytes(InputFileOffsets));  }  //===----------------------------------------------------------------------===// @@ -1756,7 +1772,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {    Record.push_back(NumHeaderSearchEntries);    Record.push_back(TableData.size());    TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end()); -  Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData.str()); +  Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData);    // Free all of the strings we had to duplicate.    for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I) @@ -1909,7 +1925,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,    Record.push_back(SOURCE_LOCATION_OFFSETS);    Record.push_back(SLocEntryOffsets.size());    Record.push_back(SourceMgr.getNextLocalOffset() - 1); // skip dummy -  Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets)); +  Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, bytes(SLocEntryOffsets));    // Write the source location entry preloads array, telling the AST    // reader which source locations entries it should load eagerly. @@ -1956,52 +1972,6 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,  // Preprocessor Serialization  //===----------------------------------------------------------------------===// -namespace { -class ASTMacroTableTrait { -public: -  typedef IdentID key_type; -  typedef key_type key_type_ref; - -  struct Data { -    uint32_t MacroDirectivesOffset; -  }; - -  typedef Data data_type; -  typedef const data_type &data_type_ref; -  typedef unsigned hash_value_type; -  typedef unsigned offset_type; - -  static hash_value_type ComputeHash(IdentID IdID) { -    return llvm::hash_value(IdID); -  } - -  std::pair<unsigned,unsigned> -  static EmitKeyDataLength(raw_ostream& Out, -                           key_type_ref Key, data_type_ref Data) { -    unsigned KeyLen = 4; // IdentID. -    unsigned DataLen = 4; // MacroDirectivesOffset. -    return std::make_pair(KeyLen, DataLen); -  } - -  static void EmitKey(raw_ostream& Out, key_type_ref Key, unsigned KeyLen) { -    using namespace llvm::support; -    endian::Writer<little>(Out).write<uint32_t>(Key); -  } - -  static void EmitData(raw_ostream& Out, key_type_ref Key, data_type_ref Data, -                       unsigned) { -    using namespace llvm::support; -    endian::Writer<little>(Out).write<uint32_t>(Data.MacroDirectivesOffset); -  } -}; -} // end anonymous namespace - -static int compareMacroDirectives( -    const std::pair<const IdentifierInfo *, MacroDirective *> *X, -    const std::pair<const IdentifierInfo *, MacroDirective *> *Y) { -  return X->first->getName().compare(Y->first->getName()); -} -  static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,                                const Preprocessor &PP) {    if (MacroInfo *MI = MD->getMacroInfo()) @@ -2009,10 +1979,6 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,        return true;    if (IsModule) { -    // Re-export any imported directives. -    if (MD->isImported()) -      return false; -      SourceLocation Loc = MD->getLocation();      if (Loc.isInvalid())        return true; @@ -2032,6 +1998,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {      WritePreprocessorDetail(*PPRec);    RecordData Record; +  RecordData ModuleMacroRecord;    // If the preprocessor __COUNTER__ value has been bumped, remember it.    if (PP.getCounterValue() != 0) { @@ -2052,75 +2019,75 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {    // Loop over all the macro directives that are live at the end of the file,    // emitting each to the PP section. -  // Construct the list of macro directives that need to be serialized. -  SmallVector<std::pair<const IdentifierInfo *, MacroDirective *>, 2> -    MacroDirectives; -  for (Preprocessor::macro_iterator -         I = PP.macro_begin(/*IncludeExternalMacros=*/false), -         E = PP.macro_end(/*IncludeExternalMacros=*/false); -       I != E; ++I) { -    MacroDirectives.push_back(std::make_pair(I->first, I->second)); -  } - +  // Construct the list of identifiers with macro directives that need to be +  // serialized. +  SmallVector<const IdentifierInfo *, 128> MacroIdentifiers; +  for (auto &Id : PP.getIdentifierTable()) +    if (Id.second->hadMacroDefinition() && +        (!Id.second->isFromAST() || +         Id.second->hasChangedSinceDeserialization())) +      MacroIdentifiers.push_back(Id.second);    // Sort the set of macro definitions that need to be serialized by the    // name of the macro, to provide a stable ordering. -  llvm::array_pod_sort(MacroDirectives.begin(), MacroDirectives.end(), -                       &compareMacroDirectives); - -  llvm::OnDiskChainedHashTableGenerator<ASTMacroTableTrait> Generator; +  std::sort(MacroIdentifiers.begin(), MacroIdentifiers.end(), +            llvm::less_ptr<IdentifierInfo>());    // Emit the macro directives as a list and associate the offset with the    // identifier they belong to. -  for (unsigned I = 0, N = MacroDirectives.size(); I != N; ++I) { -    const IdentifierInfo *Name = MacroDirectives[I].first; -    uint64_t MacroDirectiveOffset = Stream.GetCurrentBitNo(); -    MacroDirective *MD = MacroDirectives[I].second; - -    // If the macro or identifier need no updates, don't write the macro history -    // for this one. -    // FIXME: Chain the macro history instead of re-writing it. -    if (MD->isFromPCH() && -        Name->isFromAST() && !Name->hasChangedSinceDeserialization()) -      continue; +  for (const IdentifierInfo *Name : MacroIdentifiers) { +    MacroDirective *MD = PP.getLocalMacroDirectiveHistory(Name); +    auto StartOffset = Stream.GetCurrentBitNo();      // Emit the macro directives in reverse source order.      for (; MD; MD = MD->getPrevious()) { +      // Once we hit an ignored macro, we're done: the rest of the chain +      // will all be ignored macros.        if (shouldIgnoreMacro(MD, IsModule, PP)) -        continue; +        break;        AddSourceLocation(MD->getLocation(), Record);        Record.push_back(MD->getKind());        if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) { -        MacroID InfoID = getMacroRef(DefMD->getInfo(), Name); -        Record.push_back(InfoID); -        Record.push_back(DefMD->getOwningModuleID()); -        Record.push_back(DefMD->isAmbiguous()); -      } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) { -        Record.push_back(UndefMD->getOwningModuleID()); -      } else { -        auto *VisMD = cast<VisibilityMacroDirective>(MD); +        Record.push_back(getMacroRef(DefMD->getInfo(), Name)); +      } else if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {          Record.push_back(VisMD->isPublic());        } +    } -      if (MD->isImported()) { -        auto Overrides = MD->getOverriddenModules(); -        Record.push_back(Overrides.size()); -        for (auto Override : Overrides) -          Record.push_back(Override); +    // Write out any exported module macros. +    bool EmittedModuleMacros = false; +    if (IsModule) { +      auto Leafs = PP.getLeafModuleMacros(Name); +      SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end()); +      llvm::DenseMap<ModuleMacro*, unsigned> Visits; +      while (!Worklist.empty()) { +        auto *Macro = Worklist.pop_back_val(); + +        // Emit a record indicating this submodule exports this macro. +        ModuleMacroRecord.push_back( +            getSubmoduleID(Macro->getOwningModule())); +        ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name)); +        for (auto *M : Macro->overrides()) +          ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule())); + +        Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord); +        ModuleMacroRecord.clear(); + +        // Enqueue overridden macros once we've visited all their ancestors. +        for (auto *M : Macro->overrides()) +          if (++Visits[M] == M->getNumOverridingMacros()) +            Worklist.push_back(M); + +        EmittedModuleMacros = true;        }      } -    if (Record.empty()) + +    if (Record.empty() && !EmittedModuleMacros)        continue; +    IdentMacroDirectivesOffsetMap[Name] = StartOffset;      Stream.EmitRecord(PP_MACRO_DIRECTIVE_HISTORY, Record);      Record.clear(); - -    IdentMacroDirectivesOffsetMap[Name] = MacroDirectiveOffset; - -    IdentID NameID = getIdentifierRef(Name); -    ASTMacroTableTrait::Data data; -    data.MacroDirectivesOffset = MacroDirectiveOffset; -    Generator.insert(NameID, data);    }    /// \brief Offsets of each of the macros into the bitstream, indexed by @@ -2196,33 +2163,9 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {    Stream.ExitBlock(); -  // Create the on-disk hash table in a buffer. -  SmallString<4096> MacroTable; -  uint32_t BucketOffset; -  { -    using namespace llvm::support; -    llvm::raw_svector_ostream Out(MacroTable); -    // Make sure that no bucket is at offset 0 -    endian::Writer<little>(Out).write<uint32_t>(0); -    BucketOffset = Generator.Emit(Out); -  } - -  // Write the macro table -  using namespace llvm; -  BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); -  Abbrev->Add(BitCodeAbbrevOp(MACRO_TABLE)); -  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); -  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); -  unsigned MacroTableAbbrev = Stream.EmitAbbrev(Abbrev); - -  Record.push_back(MACRO_TABLE); -  Record.push_back(BucketOffset); -  Stream.EmitRecordWithBlob(MacroTableAbbrev, Record, MacroTable.str()); -  Record.clear(); -    // Write the offsets table for macro IDs.    using namespace llvm; -  Abbrev = new BitCodeAbbrev(); +  auto *Abbrev = new BitCodeAbbrev();    Abbrev->Add(BitCodeAbbrevOp(MACRO_OFFSET));    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID @@ -2234,7 +2177,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {    Record.push_back(MacroOffsets.size());    Record.push_back(FirstMacroID - NUM_PREDEF_MACRO_IDS);    Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, -                            data(MacroOffsets)); +                            bytes(MacroOffsets));  }  void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { @@ -2274,13 +2217,13 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {         (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {      Record.clear(); -    PreprocessedEntityOffsets.push_back(PPEntityOffset((*E)->getSourceRange(), -                                                     Stream.GetCurrentBitNo())); +    PreprocessedEntityOffsets.push_back( +        PPEntityOffset((*E)->getSourceRange(), Stream.GetCurrentBitNo())); -    if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { +    if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(*E)) {        // Record this macro definition's ID.        MacroDefinitions[MD] = NextPreprocessorEntityID; -       +        AddIdentifierRef(MD->getName(), Record);        Stream.EmitRecord(PPD_MACRO_DEFINITION, Record);        continue; @@ -2332,7 +2275,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {      Record.push_back(PPD_ENTITIES_OFFSETS);      Record.push_back(FirstPreprocessorEntityID - NUM_PREDEF_PP_ENTITY_IDS);      Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record, -                              data(PreprocessedEntityOffsets)); +                              bytes(PreprocessedEntityOffsets));    }  } @@ -2369,19 +2312,6 @@ static unsigned getNumberOfModules(Module *Mod) {  }  void ASTWriter::WriteSubmodules(Module *WritingModule) { -  // Determine the dependencies of our module and each of it's submodules. -  // FIXME: This feels like it belongs somewhere else, but there are no -  // other consumers of this information. -  SourceManager &SrcMgr = PP->getSourceManager(); -  ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap(); -  for (const auto *I : Context->local_imports()) { -    if (Module *ImportedFrom -          = ModMap.inferModuleFromLocation(FullSourceLoc(I->getLocation(),  -                                                         SrcMgr))) { -      ImportedFrom->Imports.push_back(I->getImportedModule()); -    } -  } -      // Enter the submodule description block.    Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5); @@ -2509,16 +2439,16 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {      }      // Emit the umbrella header, if there is one. -    if (const FileEntry *UmbrellaHeader = Mod->getUmbrellaHeader()) { +    if (auto UmbrellaHeader = Mod->getUmbrellaHeader()) {        Record.clear();        Record.push_back(SUBMODULE_UMBRELLA_HEADER); -      Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record,  -                                UmbrellaHeader->getName()); -    } else if (const DirectoryEntry *UmbrellaDir = Mod->getUmbrellaDir()) { +      Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, +                                UmbrellaHeader.NameAsWritten); +    } else if (auto UmbrellaDir = Mod->getUmbrellaDir()) {        Record.clear();        Record.push_back(SUBMODULE_UMBRELLA_DIR);        Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,  -                                UmbrellaDir->getName());       +                                UmbrellaDir.NameAsWritten);      }      // Emit the headers. @@ -2566,8 +2496,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {        Record.clear();        for (unsigned I = 0, N = Mod->Exports.size(); I != N; ++I) {          if (Module *Exported = Mod->Exports[I].getPointer()) { -          unsigned ExportedID = SubmoduleIDs[Exported]; -          assert(ExportedID > 0 && "Unknown submodule ID?"); +          unsigned ExportedID = getSubmoduleID(Exported);            Record.push_back(ExportedID);          } else {            Record.push_back(0); @@ -2618,9 +2547,14 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {    }    Stream.ExitBlock(); -   -  assert((NextSubmoduleID - FirstSubmoduleID -            == getNumberOfModules(WritingModule)) && "Wrong # of submodules"); + +  // FIXME: This can easily happen, if we have a reference to a submodule that +  // did not result in us loading a module file for that submodule. For +  // instance, a cross-top-level-module 'conflict' declaration will hit this. +  assert((NextSubmoduleID - FirstSubmoduleID == +          getNumberOfModules(WritingModule)) && +         "Wrong # of submodules; found a reference to a non-local, " +         "non-imported submodule?");  }  serialization::SubmoduleID  @@ -2684,6 +2618,29 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,      Stream.EmitRecord(DIAG_PRAGMA_MAPPINGS, Record);  } +void ASTWriter::WriteCXXCtorInitializersOffsets() { +  if (CXXCtorInitializersOffsets.empty()) +    return; + +  RecordData Record; + +  // Create a blob abbreviation for the C++ ctor initializer offsets. +  using namespace llvm; + +  BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); +  Abbrev->Add(BitCodeAbbrevOp(CXX_CTOR_INITIALIZERS_OFFSETS)); +  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size +  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); +  unsigned CtorInitializersOffsetAbbrev = Stream.EmitAbbrev(Abbrev); + +  // Write the base specifier offsets table. +  Record.clear(); +  Record.push_back(CXX_CTOR_INITIALIZERS_OFFSETS); +  Record.push_back(CXXCtorInitializersOffsets.size()); +  Stream.EmitRecordWithBlob(CtorInitializersOffsetAbbrev, Record, +                            bytes(CXXCtorInitializersOffsets)); +} +  void ASTWriter::WriteCXXBaseSpecifiersOffsets() {    if (CXXBaseSpecifiersOffsets.empty())      return; @@ -2704,7 +2661,7 @@ void ASTWriter::WriteCXXBaseSpecifiersOffsets() {    Record.push_back(CXX_BASE_SPECIFIER_OFFSETS);    Record.push_back(CXXBaseSpecifiersOffsets.size());    Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, -                            data(CXXBaseSpecifiersOffsets)); +                            bytes(CXXBaseSpecifiersOffsets));  }  //===----------------------------------------------------------------------===// @@ -2780,7 +2737,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,      Decls.push_back(std::make_pair(D->getKind(), GetDeclRef(D)));    ++NumLexicalDeclContexts; -  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, data(Decls)); +  Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, bytes(Decls));    return Offset;  } @@ -2799,7 +2756,7 @@ void ASTWriter::WriteTypeDeclOffsets() {    Record.push_back(TYPE_OFFSET);    Record.push_back(TypeOffsets.size());    Record.push_back(FirstTypeID - NUM_PREDEF_TYPE_IDS); -  Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, data(TypeOffsets)); +  Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, bytes(TypeOffsets));    // Write the declaration offsets array    Abbrev = new BitCodeAbbrev(); @@ -2812,22 +2769,25 @@ void ASTWriter::WriteTypeDeclOffsets() {    Record.push_back(DECL_OFFSET);    Record.push_back(DeclOffsets.size());    Record.push_back(FirstDeclID - NUM_PREDEF_DECL_IDS); -  Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets)); +  Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets));  }  void ASTWriter::WriteFileDeclIDsMap() {    using namespace llvm;    RecordData Record; +  SmallVector<std::pair<FileID, DeclIDInFileInfo *>, 64> SortedFileDeclIDs( +      FileDeclIDs.begin(), FileDeclIDs.end()); +  std::sort(SortedFileDeclIDs.begin(), SortedFileDeclIDs.end(), +            llvm::less_first()); +    // Join the vectors of DeclIDs from all files. -  SmallVector<DeclID, 256> FileSortedIDs; -  for (FileDeclIDsTy::iterator -         FI = FileDeclIDs.begin(), FE = FileDeclIDs.end(); FI != FE; ++FI) { -    DeclIDInFileInfo &Info = *FI->second; -    Info.FirstDeclIndex = FileSortedIDs.size(); -    for (LocDeclIDsTy::iterator -           DI = Info.DeclIDs.begin(), DE = Info.DeclIDs.end(); DI != DE; ++DI) -      FileSortedIDs.push_back(DI->second); +  SmallVector<DeclID, 256> FileGroupedDeclIDs; +  for (auto &FileDeclEntry : SortedFileDeclIDs) { +    DeclIDInFileInfo &Info = *FileDeclEntry.second; +    Info.FirstDeclIndex = FileGroupedDeclIDs.size(); +    for (auto &LocDeclEntry : Info.DeclIDs) +      FileGroupedDeclIDs.push_back(LocDeclEntry.second);    }    BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); @@ -2836,8 +2796,8 @@ void ASTWriter::WriteFileDeclIDsMap() {    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);    Record.push_back(FILE_SORTED_DECLS); -  Record.push_back(FileSortedIDs.size()); -  Stream.EmitRecordWithBlob(AbbrevCode, Record, data(FileSortedIDs)); +  Record.push_back(FileGroupedDeclIDs.size()); +  Stream.EmitRecordWithBlob(AbbrevCode, Record, bytes(FileGroupedDeclIDs));  }  void ASTWriter::WriteComments() { @@ -2988,13 +2948,12 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {      // Create the on-disk hash table representation. We walk through every      // selector we've seen and look it up in the method pool.      SelectorOffsets.resize(NextSelectorID - FirstSelectorID); -    for (llvm::DenseMap<Selector, SelectorID>::iterator -             I = SelectorIDs.begin(), E = SelectorIDs.end(); -         I != E; ++I) { -      Selector S = I->first; +    for (auto &SelectorAndID : SelectorIDs) { +      Selector S = SelectorAndID.first; +      SelectorID ID = SelectorAndID.second;        Sema::GlobalMethodPool::iterator F = SemaRef.MethodPool.find(S);        ASTMethodPoolTrait::data_type Data = { -        I->second, +        ID,          ObjCMethodList(),          ObjCMethodList()        }; @@ -3004,7 +2963,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {        }        // Only write this selector if it's not in an existing AST or something        // changed. -      if (Chain && I->second < FirstSelectorID) { +      if (Chain && ID < FirstSelectorID) {          // Selector already exists. Did it change?          bool changed = false;          for (ObjCMethodList *M = &Data.Instance; @@ -3051,7 +3010,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {      Record.push_back(METHOD_POOL);      Record.push_back(BucketOffset);      Record.push_back(NumTableEntries); -    Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool.str()); +    Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool);      // Create a blob abbreviation for the selector table offsets.      Abbrev = new BitCodeAbbrev(); @@ -3067,7 +3026,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {      Record.push_back(SelectorOffsets.size());      Record.push_back(FirstSelectorID - NUM_PREDEF_SELECTOR_IDS);      Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, -                              data(SelectorOffsets)); +                              bytes(SelectorOffsets));    }  } @@ -3082,11 +3041,9 @@ void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {    // Note: this writes out all references even for a dependent AST. But it is    // very tricky to fix, and given that @selector shouldn't really appear in    // headers, probably not worth it. It's not a correctness issue. -  for (DenseMap<Selector, SourceLocation>::iterator S = -       SemaRef.ReferencedSelectors.begin(), -       E = SemaRef.ReferencedSelectors.end(); S != E; ++S) { -    Selector Sel = (*S).first; -    SourceLocation Loc = (*S).second; +  for (auto &SelectorAndLocation : SemaRef.ReferencedSelectors) { +    Selector Sel = SelectorAndLocation.first; +    SourceLocation Loc = SelectorAndLocation.second;      AddSelectorRef(Sel, Record);      AddSourceLocation(Loc, Record);    } @@ -3097,174 +3054,59 @@ void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {  // Identifier Table Serialization  //===----------------------------------------------------------------------===// +/// Determine the declaration that should be put into the name lookup table to +/// represent the given declaration in this module. This is usually D itself, +/// but if D was imported and merged into a local declaration, we want the most +/// recent local declaration instead. The chosen declaration will be the most +/// recent declaration in any module that imports this one. +static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts, +                                        NamedDecl *D) { +  if (!LangOpts.Modules || !D->isFromASTFile()) +    return D; + +  if (Decl *Redecl = D->getPreviousDecl()) { +    // For Redeclarable decls, a prior declaration might be local. +    for (; Redecl; Redecl = Redecl->getPreviousDecl()) { +      if (!Redecl->isFromASTFile()) +        return cast<NamedDecl>(Redecl); +      // If we find a decl from a (chained-)PCH stop since we won't find a +      // local one. +      if (D->getOwningModuleID() == 0) +        break; +    } +  } else if (Decl *First = D->getCanonicalDecl()) { +    // For Mergeable decls, the first decl might be local. +    if (!First->isFromASTFile()) +      return cast<NamedDecl>(First); +  } + +  // All declarations are imported. Our most recent declaration will also be +  // the most recent one in anyone who imports us. +  return D; +} +  namespace {  class ASTIdentifierTableTrait {    ASTWriter &Writer;    Preprocessor &PP;    IdentifierResolver &IdResolver; -  bool IsModule; -  /// \brief Determines whether this is an "interesting" identifier -  /// that needs a full IdentifierInfo structure written into the hash -  /// table. -  bool isInterestingIdentifier(IdentifierInfo *II, MacroDirective *&Macro) { -    if (II->isPoisoned() || +  /// \brief Determines whether this is an "interesting" identifier that needs a +  /// full IdentifierInfo structure written into the hash table. Notably, this +  /// doesn't check whether the name has macros defined; use PublicMacroIterator +  /// to check that. +  bool isInterestingIdentifier(IdentifierInfo *II, uint64_t MacroOffset) { +    if (MacroOffset || +        II->isPoisoned() ||          II->isExtensionToken() ||          II->getObjCOrBuiltinID() ||          II->hasRevertedTokenIDToIdentifier() ||          II->getFETokenInfo<void>())        return true; -    return hadMacroDefinition(II, Macro); -  } - -  bool hadMacroDefinition(IdentifierInfo *II, MacroDirective *&Macro) { -    if (!II->hadMacroDefinition()) -      return false; - -    if (Macro || (Macro = PP.getMacroDirectiveHistory(II))) { -      if (!IsModule) -        return !shouldIgnoreMacro(Macro, IsModule, PP); - -      MacroState State; -      if (getFirstPublicSubmoduleMacro(Macro, State)) -        return true; -    } -      return false;    } -  enum class SubmoduleMacroState { -    /// We've seen nothing about this macro. -    None, -    /// We've seen a public visibility directive. -    Public, -    /// We've either exported a macro for this module or found that the -    /// module's definition of this macro is private. -    Done -  }; -  typedef llvm::DenseMap<SubmoduleID, SubmoduleMacroState> MacroState; - -  MacroDirective * -  getFirstPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) { -    if (MacroDirective *NextMD = getPublicSubmoduleMacro(MD, State)) -      return NextMD; -    return nullptr; -  } - -  MacroDirective * -  getNextPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) { -    if (MacroDirective *NextMD = -            getPublicSubmoduleMacro(MD->getPrevious(), State)) -      return NextMD; -    return nullptr; -  } - -  /// \brief Traverses the macro directives history and returns the next -  /// public macro definition or undefinition that has not been found so far. -  /// -  /// A macro that is defined in submodule A and undefined in submodule B -  /// will still be considered as defined/exported from submodule A. -  MacroDirective *getPublicSubmoduleMacro(MacroDirective *MD, -                                          MacroState &State) { -    if (!MD) -      return nullptr; - -    Optional<bool> IsPublic; -    for (; MD; MD = MD->getPrevious()) { -      // Once we hit an ignored macro, we're done: the rest of the chain -      // will all be ignored macros. -      if (shouldIgnoreMacro(MD, IsModule, PP)) -        break; - -      // If this macro was imported, re-export it. -      if (MD->isImported()) -        return MD; - -      SubmoduleID ModID = getSubmoduleID(MD); -      auto &S = State[ModID]; -      assert(ModID && "found macro in no submodule"); - -      if (S == SubmoduleMacroState::Done) -        continue; - -      if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) { -        // The latest visibility directive for a name in a submodule affects all -        // the directives that come before it. -        if (S == SubmoduleMacroState::None) -          S = VisMD->isPublic() ? SubmoduleMacroState::Public -                                : SubmoduleMacroState::Done; -      } else { -        S = SubmoduleMacroState::Done; -        return MD; -      } -    } - -    return nullptr; -  } - -  ArrayRef<SubmoduleID> -  getOverriddenSubmodules(MacroDirective *MD, -                          SmallVectorImpl<SubmoduleID> &ScratchSpace) { -    assert(!isa<VisibilityMacroDirective>(MD) && -           "only #define and #undef can override"); -    if (MD->isImported()) -      return MD->getOverriddenModules(); - -    ScratchSpace.clear(); -    SubmoduleID ModID = getSubmoduleID(MD); -    for (MD = MD->getPrevious(); MD; MD = MD->getPrevious()) { -      if (shouldIgnoreMacro(MD, IsModule, PP)) -        break; - -      // If this is a definition from a submodule import, that submodule's -      // definition is overridden by the definition or undefinition that we -      // started with. -      if (MD->isImported()) { -        if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) { -          SubmoduleID DefModuleID = DefMD->getInfo()->getOwningModuleID(); -          assert(DefModuleID && "imported macro has no owning module"); -          ScratchSpace.push_back(DefModuleID); -        } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) { -          // If we override a #undef, we override anything that #undef overrides. -          // We don't need to override it, since an active #undef doesn't affect -          // the meaning of a macro. -          auto Overrides = UndefMD->getOverriddenModules(); -          ScratchSpace.insert(ScratchSpace.end(), -                              Overrides.begin(), Overrides.end()); -        } -      } - -      // Stop once we leave the original macro's submodule. -      // -      // Either this submodule #included another submodule of the same -      // module or it just happened to be built after the other module. -      // In the former case, we override the submodule's macro. -      // -      // FIXME: In the latter case, we shouldn't do so, but we can't tell -      // these cases apart. -      // -      // FIXME: We can leave this submodule and re-enter it if it #includes a -      // header within a different submodule of the same module. In such cases -      // the overrides list will be incomplete. -      SubmoduleID DirectiveModuleID = getSubmoduleID(MD); -      if (DirectiveModuleID != ModID) { -        if (DirectiveModuleID && !MD->isImported()) -          ScratchSpace.push_back(DirectiveModuleID); -        break; -      } -    } - -    std::sort(ScratchSpace.begin(), ScratchSpace.end()); -    ScratchSpace.erase(std::unique(ScratchSpace.begin(), ScratchSpace.end()), -                       ScratchSpace.end()); -    return ScratchSpace; -  } - -  SubmoduleID getSubmoduleID(MacroDirective *MD) { -    return Writer.inferSubmoduleIDFromLocation(MD->getLocation()); -  } -  public:    typedef IdentifierInfo* key_type;    typedef key_type  key_type_ref; @@ -3275,9 +3117,9 @@ public:    typedef unsigned hash_value_type;    typedef unsigned offset_type; -  ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,  -                          IdentifierResolver &IdResolver, bool IsModule) -    : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule) { } +  ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP, +                          IdentifierResolver &IdResolver) +      : Writer(Writer), PP(PP), IdResolver(IdResolver) {}    static hash_value_type ComputeHash(const IdentifierInfo* II) {      return llvm::HashString(II->getName()); @@ -3287,25 +3129,12 @@ public:    EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {      unsigned KeyLen = II->getLength() + 1;      unsigned DataLen = 4; // 4 bytes for the persistent ID << 1 -    MacroDirective *Macro = nullptr; -    if (isInterestingIdentifier(II, Macro)) { +    auto MacroOffset = Writer.getMacroDirectivesOffset(II); +    if (isInterestingIdentifier(II, MacroOffset)) {        DataLen += 2; // 2 bytes for builtin ID        DataLen += 2; // 2 bytes for flags -      if (hadMacroDefinition(II, Macro)) { +      if (MacroOffset)          DataLen += 4; // MacroDirectives offset. -        if (IsModule) { -          MacroState State; -          SmallVector<SubmoduleID, 16> Scratch; -          for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, State); -               MD; MD = getNextPublicSubmoduleMacro(MD, State)) { -            DataLen += 4; // MacroInfo ID or ModuleID. -            if (unsigned NumOverrides = -                    getOverriddenSubmodules(MD, Scratch).size()) -              DataLen += 4 * (1 + NumOverrides); -          } -          DataLen += 4; // 0 terminator. -        } -      }        for (IdentifierResolver::iterator D = IdResolver.begin(II),                                       DEnd = IdResolver.end(); @@ -3315,6 +3144,7 @@ public:      using namespace llvm::support;      endian::Writer<little> LE(Out); +    assert((uint16_t)DataLen == DataLen && (uint16_t)KeyLen == KeyLen);      LE.write<uint16_t>(DataLen);      // We emit the key length after the data length so that every      // string is preceded by a 16-bit length. This matches the PTH @@ -3331,25 +3161,13 @@ public:      Out.write(II->getNameStart(), KeyLen);    } -  static void emitMacroOverrides(raw_ostream &Out, -                                 ArrayRef<SubmoduleID> Overridden) { -    if (!Overridden.empty()) { -      using namespace llvm::support; -      endian::Writer<little> LE(Out); -      LE.write<uint32_t>(Overridden.size() | 0x80000000U); -      for (unsigned I = 0, N = Overridden.size(); I != N; ++I) { -        assert(Overridden[I] && "zero module ID for override"); -        LE.write<uint32_t>(Overridden[I]); -      } -    } -  } -    void EmitData(raw_ostream& Out, IdentifierInfo* II,                  IdentID ID, unsigned) {      using namespace llvm::support;      endian::Writer<little> LE(Out); -    MacroDirective *Macro = nullptr; -    if (!isInterestingIdentifier(II, Macro)) { + +    auto MacroOffset = Writer.getMacroDirectivesOffset(II); +    if (!isInterestingIdentifier(II, MacroOffset)) {        LE.write<uint32_t>(ID << 1);        return;      } @@ -3359,77 +3177,29 @@ public:      assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");      LE.write<uint16_t>(Bits);      Bits = 0; -    bool HadMacroDefinition = hadMacroDefinition(II, Macro); +    bool HadMacroDefinition = MacroOffset != 0;      Bits = (Bits << 1) | unsigned(HadMacroDefinition); -    Bits = (Bits << 1) | unsigned(IsModule);      Bits = (Bits << 1) | unsigned(II->isExtensionToken());      Bits = (Bits << 1) | unsigned(II->isPoisoned());      Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());      Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());      LE.write<uint16_t>(Bits); -    if (HadMacroDefinition) { -      LE.write<uint32_t>(Writer.getMacroDirectivesOffset(II)); -      if (IsModule) { -        // Write the IDs of macros coming from different submodules. -        MacroState State; -        SmallVector<SubmoduleID, 16> Scratch; -        for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, State); -             MD; MD = getNextPublicSubmoduleMacro(MD, State)) { -          if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) { -            // FIXME: If this macro directive was created by #pragma pop_macros, -            // or if it was created implicitly by resolving conflicting macros, -            // it may be for a different submodule from the one in the MacroInfo -            // object. If so, we should write out its owning ModuleID. -            MacroID InfoID = Writer.getMacroID(DefMD->getInfo()); -            assert(InfoID); -            LE.write<uint32_t>(InfoID << 1); -          } else { -            auto *UndefMD = cast<UndefMacroDirective>(MD); -            SubmoduleID Mod = UndefMD->isImported() -                                  ? UndefMD->getOwningModuleID() -                                  : getSubmoduleID(UndefMD); -            LE.write<uint32_t>((Mod << 1) | 1); -          } -          emitMacroOverrides(Out, getOverriddenSubmodules(MD, Scratch)); -        } -        LE.write<uint32_t>(0xdeadbeef); -      } -    } +    if (HadMacroDefinition) +      LE.write<uint32_t>(MacroOffset);      // Emit the declaration IDs in reverse order, because the      // IdentifierResolver provides the declarations as they would be      // visible (e.g., the function "stat" would come before the struct -    // "stat"), but the ASTReader adds declarations to the end of the list  -    // (so we need to see the struct "status" before the function "status"). +    // "stat"), but the ASTReader adds declarations to the end of the list +    // (so we need to see the struct "stat" before the function "stat").      // Only emit declarations that aren't from a chained PCH, though. -    SmallVector<Decl *, 16> Decls(IdResolver.begin(II), -                                  IdResolver.end()); -    for (SmallVectorImpl<Decl *>::reverse_iterator D = Decls.rbegin(), -                                                DEnd = Decls.rend(); +    SmallVector<NamedDecl *, 16> Decls(IdResolver.begin(II), IdResolver.end()); +    for (SmallVectorImpl<NamedDecl *>::reverse_iterator D = Decls.rbegin(), +                                                        DEnd = Decls.rend();           D != DEnd; ++D) -      LE.write<uint32_t>(Writer.getDeclID(getMostRecentLocalDecl(*D))); -  } - -  /// \brief Returns the most recent local decl or the given decl if there are -  /// no local ones. The given decl is assumed to be the most recent one. -  Decl *getMostRecentLocalDecl(Decl *Orig) { -    // The only way a "from AST file" decl would be more recent from a local one -    // is if it came from a module. -    if (!PP.getLangOpts().Modules) -      return Orig; - -    // Look for a local in the decl chain. -    for (Decl *D = Orig; D; D = D->getPreviousDecl()) { -      if (!D->isFromASTFile()) -        return D; -      // If we come up a decl from a (chained-)PCH stop since we won't find a -      // local one. -      if (D->getOwningModuleID() == 0) -        break; -    } - -    return Orig; +      LE.write<uint32_t>( +          Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), *D)));    }  };  } // end anonymous namespace @@ -3448,29 +3218,33 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,    // strings.    {      llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; -    ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule); +    ASTIdentifierTableTrait Trait(*this, PP, IdResolver);      // Look for any identifiers that were named while processing the      // headers, but are otherwise not needed. We add these to the hash      // table to enable checking of the predefines buffer in the case      // where the user adds new macro definitions when building the AST      // file. +    SmallVector<const IdentifierInfo *, 128> IIs;      for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),                                  IDEnd = PP.getIdentifierTable().end();           ID != IDEnd; ++ID) -      getIdentifierRef(ID->second); +      IIs.push_back(ID->second); +    // Sort the identifiers lexicographically before getting them references so +    // that their order is stable. +    std::sort(IIs.begin(), IIs.end(), llvm::less_ptr<IdentifierInfo>()); +    for (const IdentifierInfo *II : IIs) +      getIdentifierRef(II);      // Create the on-disk hash table representation. We only store offsets      // for identifiers that appear here for the first time.      IdentifierOffsets.resize(NextIdentID - FirstIdentID); -    for (llvm::DenseMap<const IdentifierInfo *, IdentID>::iterator -           ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end(); -         ID != IDEnd; ++ID) { -      assert(ID->first && "NULL identifier in identifier table"); -      if (!Chain || !ID->first->isFromAST() ||  -          ID->first->hasChangedSinceDeserialization()) -        Generator.insert(const_cast<IdentifierInfo *>(ID->first), ID->second, -                         Trait); +    for (auto IdentIDPair : IdentifierIDs) { +      IdentifierInfo *II = const_cast<IdentifierInfo *>(IdentIDPair.first); +      IdentID ID = IdentIDPair.second; +      assert(II && "NULL identifier in identifier table"); +      if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) +        Generator.insert(II, ID, Trait);      }      // Create the on-disk hash table in a buffer. @@ -3478,7 +3252,6 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,      uint32_t BucketOffset;      {        using namespace llvm::support; -      ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule);        llvm::raw_svector_ostream Out(IdentifierTable);        // Make sure that no bucket is at offset 0        endian::Writer<little>(Out).write<uint32_t>(0); @@ -3496,7 +3269,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,      RecordData Record;      Record.push_back(IDENTIFIER_TABLE);      Record.push_back(BucketOffset); -    Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable.str()); +    Stream.EmitRecordWithBlob(IDTableAbbrev, Record, IdentifierTable);    }    // Write the offsets table for identifier IDs. @@ -3517,38 +3290,13 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,    Record.push_back(IdentifierOffsets.size());    Record.push_back(FirstIdentID - NUM_PREDEF_IDENT_IDS);    Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, -                            data(IdentifierOffsets)); +                            bytes(IdentifierOffsets));  }  //===----------------------------------------------------------------------===//  // DeclContext's Name Lookup Table Serialization  //===----------------------------------------------------------------------===// -/// Determine the declaration that should be put into the name lookup table to -/// represent the given declaration in this module. This is usually D itself, -/// but if D was imported and merged into a local declaration, we want the most -/// recent local declaration instead. The chosen declaration will be the most -/// recent declaration in any module that imports this one. -static NamedDecl *getDeclForLocalLookup(NamedDecl *D) { -  if (!D->isFromASTFile()) -    return D; - -  if (Decl *Redecl = D->getPreviousDecl()) { -    // For Redeclarable decls, a prior declaration might be local. -    for (; Redecl; Redecl = Redecl->getPreviousDecl()) -      if (!Redecl->isFromASTFile()) -        return cast<NamedDecl>(Redecl); -  } else if (Decl *First = D->getCanonicalDecl()) { -    // For Mergeable decls, the first decl might be local. -    if (!First->isFromASTFile()) -      return cast<NamedDecl>(First); -  } - -  // All declarations are imported. Our most recent declaration will also be -  // the most recent one in anyone who imports us. -  return D; -} -  namespace {  // Trait used for the on-disk hash table used in the method pool.  class ASTDeclContextNameLookupTrait { @@ -3666,119 +3414,198 @@ public:      LE.write<uint16_t>(Lookup.size());      for (DeclContext::lookup_iterator I = Lookup.begin(), E = Lookup.end();           I != E; ++I) -      LE.write<uint32_t>(Writer.GetDeclRef(getDeclForLocalLookup(*I))); +      LE.write<uint32_t>( +          Writer.GetDeclRef(getDeclForLocalLookup(Writer.getLangOpts(), *I)));      assert(Out.tell() - Start == DataLen && "Data length is wrong");    }  };  } // end anonymous namespace -template<typename Visitor> -static void visitLocalLookupResults(const DeclContext *ConstDC, -                                    bool NeedToReconcileExternalVisibleStorage, -                                    Visitor AddLookupResult) { +bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result, +                                       DeclContext *DC) { +  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage; +} + +bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result, +                                               DeclContext *DC) { +  for (auto *D : Result.getLookupResult()) +    if (!getDeclForLocalLookup(getLangOpts(), D)->isFromASTFile()) +      return false; + +  return true; +} + +uint32_t +ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC, +                                   llvm::SmallVectorImpl<char> &LookupTable) { +  assert(!ConstDC->HasLazyLocalLexicalLookups && +         !ConstDC->HasLazyExternalLexicalLookups && +         "must call buildLookups first"); +    // FIXME: We need to build the lookups table, which is logically const.    DeclContext *DC = const_cast<DeclContext*>(ConstDC);    assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table"); -  SmallVector<DeclarationName, 16> ExternalNames; +  // Create the on-disk hash table representation. +  llvm::OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> +      Generator; +  ASTDeclContextNameLookupTrait Trait(*this); + +  // The first step is to collect the declaration names which we need to +  // serialize into the name lookup table, and to collect them in a stable +  // order. +  SmallVector<DeclarationName, 16> Names; + +  // We also build up small sets of the constructor and conversion function +  // names which are visible. +  llvm::SmallSet<DeclarationName, 8> ConstructorNameSet, ConversionNameSet; +    for (auto &Lookup : *DC->buildLookup()) { -    if (Lookup.second.hasExternalDecls() || -        NeedToReconcileExternalVisibleStorage) { -      // We don't know for sure what declarations are found by this name, -      // because the external source might have a different set from the set -      // that are in the lookup map, and we can't update it now without -      // risking invalidating our lookup iterator. So add it to a queue to -      // deal with later. -      ExternalNames.push_back(Lookup.first); +    auto &Name = Lookup.first; +    auto &Result = Lookup.second; + +    // If there are no local declarations in our lookup result, we don't +    // need to write an entry for the name at all unless we're rewriting +    // the decl context. If we can't write out a lookup set without +    // performing more deserialization, just skip this entry. +    if (isLookupResultExternal(Result, DC) && !isRewritten(cast<Decl>(DC)) && +        isLookupResultEntirelyExternal(Result, DC))        continue; -    } -    AddLookupResult(Lookup.first, Lookup.second.getLookupResult()); -  } +    // We also skip empty results. If any of the results could be external and +    // the currently available results are empty, then all of the results are +    // external and we skip it above. So the only way we get here with an empty +    // results is when no results could have been external *and* we have +    // external results. +    // +    // FIXME: While we might want to start emitting on-disk entries for negative +    // lookups into a decl context as an optimization, today we *have* to skip +    // them because there are names with empty lookup results in decl contexts +    // which we can't emit in any stable ordering: we lookup constructors and +    // conversion functions in the enclosing namespace scope creating empty +    // results for them. This in almost certainly a bug in Clang's name lookup, +    // but that is likely to be hard or impossible to fix and so we tolerate it +    // here by omitting lookups with empty results. +    if (Lookup.second.getLookupResult().empty()) +      continue; -  // Add the names we needed to defer. Note, this shouldn't add any new decls -  // to the list we need to serialize: any new declarations we find here should -  // be imported from an external source. -  // FIXME: What if the external source isn't an ASTReader? -  for (const auto &Name : ExternalNames) -    AddLookupResult(Name, DC->lookup(Name)); -} - -void ASTWriter::AddUpdatedDeclContext(const DeclContext *DC) { -  if (UpdatedDeclContexts.insert(DC).second && WritingAST) { -    // Ensure we emit all the visible declarations. -    visitLocalLookupResults(DC, DC->NeedToReconcileExternalVisibleStorage, -                            [&](DeclarationName Name, -                                DeclContext::lookup_const_result Result) { -      for (auto *Decl : Result) -        GetDeclRef(getDeclForLocalLookup(Decl)); -    }); +    switch (Lookup.first.getNameKind()) { +    default: +      Names.push_back(Lookup.first); +      break; + +    case DeclarationName::CXXConstructorName: +      assert(isa<CXXRecordDecl>(DC) && +             "Cannot have a constructor name outside of a class!"); +      ConstructorNameSet.insert(Name); +      break; + +    case DeclarationName::CXXConversionFunctionName: +      assert(isa<CXXRecordDecl>(DC) && +             "Cannot have a conversion function name outside of a class!"); +      ConversionNameSet.insert(Name); +      break; +    }    } -} -uint32_t -ASTWriter::GenerateNameLookupTable(const DeclContext *DC, -                                   llvm::SmallVectorImpl<char> &LookupTable) { -  assert(!DC->LookupPtr.getInt() && "must call buildLookups first"); +  // Sort the names into a stable order. +  std::sort(Names.begin(), Names.end()); + +  if (auto *D = dyn_cast<CXXRecordDecl>(DC)) { +    // We need to establish an ordering of constructor and conversion function +    // names, and they don't have an intrinsic ordering. + +    // First we try the easy case by forming the current context's constructor +    // name and adding that name first. This is a very useful optimization to +    // avoid walking the lexical declarations in many cases, and it also +    // handles the only case where a constructor name can come from some other +    // lexical context -- when that name is an implicit constructor merged from +    // another declaration in the redecl chain. Any non-implicit constructor or +    // conversion function which doesn't occur in all the lexical contexts +    // would be an ODR violation. +    auto ImplicitCtorName = Context->DeclarationNames.getCXXConstructorName( +        Context->getCanonicalType(Context->getRecordType(D))); +    if (ConstructorNameSet.erase(ImplicitCtorName)) +      Names.push_back(ImplicitCtorName); + +    // If we still have constructors or conversion functions, we walk all the +    // names in the decl and add the constructors and conversion functions +    // which are visible in the order they lexically occur within the context. +    if (!ConstructorNameSet.empty() || !ConversionNameSet.empty()) +      for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls()) +        if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) { +          auto Name = ChildND->getDeclName(); +          switch (Name.getNameKind()) { +          default: +            continue; + +          case DeclarationName::CXXConstructorName: +            if (ConstructorNameSet.erase(Name)) +              Names.push_back(Name); +            break; + +          case DeclarationName::CXXConversionFunctionName: +            if (ConversionNameSet.erase(Name)) +              Names.push_back(Name); +            break; +          } -  llvm::OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> -      Generator; -  ASTDeclContextNameLookupTrait Trait(*this); +          if (ConstructorNameSet.empty() && ConversionNameSet.empty()) +            break; +        } -  // Create the on-disk hash table representation. -  DeclarationName ConstructorName; -  DeclarationName ConversionName; +    assert(ConstructorNameSet.empty() && "Failed to find all of the visible " +                                         "constructors by walking all the " +                                         "lexical members of the context."); +    assert(ConversionNameSet.empty() && "Failed to find all of the visible " +                                        "conversion functions by walking all " +                                        "the lexical members of the context."); +  } + +  // Next we need to do a lookup with each name into this decl context to fully +  // populate any results from external sources. We don't actually use the +  // results of these lookups because we only want to use the results after all +  // results have been loaded and the pointers into them will be stable. +  for (auto &Name : Names) +    DC->lookup(Name); + +  // Now we need to insert the results for each name into the hash table. For +  // constructor names and conversion function names, we actually need to merge +  // all of the results for them into one list of results each and insert +  // those.    SmallVector<NamedDecl *, 8> ConstructorDecls; -  SmallVector<NamedDecl *, 4> ConversionDecls; +  SmallVector<NamedDecl *, 8> ConversionDecls; -  visitLocalLookupResults(DC, DC->NeedToReconcileExternalVisibleStorage, -                          [&](DeclarationName Name, -                              DeclContext::lookup_result Result) { -    if (Result.empty()) -      return; +  // Now loop over the names, either inserting them or appending for the two +  // special cases. +  for (auto &Name : Names) { +    DeclContext::lookup_result Result = DC->noload_lookup(Name); -    // Different DeclarationName values of certain kinds are mapped to -    // identical serialized keys, because we don't want to use type -    // identifiers in the keys (since type ids are local to the module).      switch (Name.getNameKind()) { +    default: +      Generator.insert(Name, Result, Trait); +      break; +      case DeclarationName::CXXConstructorName: -      // There may be different CXXConstructorName DeclarationName values -      // in a DeclContext because a UsingDecl that inherits constructors -      // has the DeclarationName of the inherited constructors. -      if (!ConstructorName) -        ConstructorName = Name;        ConstructorDecls.append(Result.begin(), Result.end()); -      return; +      break;      case DeclarationName::CXXConversionFunctionName: -      if (!ConversionName) -        ConversionName = Name;        ConversionDecls.append(Result.begin(), Result.end()); -      return; - -    default:        break;      } - -    Generator.insert(Name, Result, Trait); -  }); - -  // Add the constructors. -  if (!ConstructorDecls.empty()) { -    Generator.insert(ConstructorName, -                     DeclContext::lookup_result(ConstructorDecls.begin(), -                                                ConstructorDecls.end()), -                     Trait);    } -  // Add the conversion functions. -  if (!ConversionDecls.empty()) { -    Generator.insert(ConversionName, -                     DeclContext::lookup_result(ConversionDecls.begin(), -                                                ConversionDecls.end()), -                     Trait); -  } +  // Handle our two special cases if we ended up having any. We arbitrarily use +  // the first declaration's name here because the name itself isn't part of +  // the key, only the kind of name is used. +  if (!ConstructorDecls.empty()) +    Generator.insert(ConstructorDecls.front()->getDeclName(), +                     DeclContext::lookup_result(ConstructorDecls), Trait); +  if (!ConversionDecls.empty()) +    Generator.insert(ConversionDecls.front()->getDeclName(), +                     DeclContext::lookup_result(ConversionDecls), Trait);    // Create the on-disk hash table in a buffer.    llvm::raw_svector_ostream Out(LookupTable); @@ -3798,9 +3625,8 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,    if (DC->getPrimaryContext() != DC)      return 0; -  // Since there is no name lookup into functions or methods, don't bother to -  // build a visible-declarations table for these entities. -  if (DC->isFunctionOrMethod()) +  // Skip contexts which don't support name lookup. +  if (!DC->isLookupContext())      return 0;    // If not in C++, we perform name lookup for the translation unit via the @@ -3827,7 +3653,7 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,    Record.push_back(DECL_CONTEXT_VISIBLE);    Record.push_back(BucketOffset);    Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record, -                            LookupTable.str()); +                            LookupTable);    ++NumVisibleDeclContexts;    return Offset;  } @@ -3852,7 +3678,7 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {    Record.push_back(UPDATE_VISIBLE);    Record.push_back(getDeclID(cast<Decl>(DC)));    Record.push_back(BucketOffset); -  Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); +  Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);  }  /// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions. @@ -3902,18 +3728,6 @@ void ASTWriter::WriteRedeclarations() {        }      } -    if (!First->isFromASTFile() && Chain) { -      Decl *FirstFromAST = MostRecent; -      for (Decl *Prev = MostRecent; Prev; Prev = Prev->getPreviousDecl()) { -        if (Prev->isFromASTFile()) -          FirstFromAST = Prev; -      } - -      // FIXME: Do we need to do this for the first declaration from each -      // redeclaration chain that was merged into this one? -      Chain->MergedDecls[FirstFromAST].push_back(getDeclID(First)); -    } -      LocalRedeclChains[Offset] = Size;      // Reverse the set of local redeclarations, so that we store them in @@ -4008,25 +3822,6 @@ void ASTWriter::WriteObjCCategories() {    Stream.EmitRecord(OBJC_CATEGORIES, Categories);  } -void ASTWriter::WriteMergedDecls() { -  if (!Chain || Chain->MergedDecls.empty()) -    return; -   -  RecordData Record; -  for (ASTReader::MergedDeclsMap::iterator I = Chain->MergedDecls.begin(), -                                        IEnd = Chain->MergedDecls.end(); -       I != IEnd; ++I) { -    DeclID CanonID = I->first->isFromASTFile()? I->first->getGlobalID() -                                              : GetDeclRef(I->first); -    assert(CanonID && "Merged declaration not known?"); -     -    Record.push_back(CanonID); -    Record.push_back(I->second.size()); -    Record.append(I->second.begin(), I->second.end()); -  } -  Stream.EmitRecord(MERGED_DECLARATIONS, Record); -} -  void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) {    Sema::LateParsedTemplateMapT &LPTMap = SemaRef.LateParsedTemplateMap; @@ -4034,11 +3829,10 @@ void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) {      return;    RecordData Record; -  for (Sema::LateParsedTemplateMapT::iterator It = LPTMap.begin(), -                                              ItEnd = LPTMap.end(); -       It != ItEnd; ++It) { -    LateParsedTemplate *LPT = It->second; -    AddDeclRef(It->first, Record); +  for (auto LPTMapEntry : LPTMap) { +    const FunctionDecl *FD = LPTMapEntry.first; +    LateParsedTemplate *LPT = LPTMapEntry.second; +    AddDeclRef(FD, Record);      AddDeclRef(LPT->D, Record);      Record.push_back(LPT->Toks.size()); @@ -4175,7 +3969,8 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)        FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID),        CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0),        NumLexicalDeclContexts(0), NumVisibleDeclContexts(0), -      NextCXXBaseSpecifiersID(1), TypeExtQualAbbrev(0), +      NextCXXBaseSpecifiersID(1), NextCXXCtorInitializersID(1), +      TypeExtQualAbbrev(0),        TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0),        DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0),        UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0), @@ -4188,6 +3983,11 @@ ASTWriter::~ASTWriter() {    llvm::DeleteContainerSeconds(FileDeclIDs);  } +const LangOptions &ASTWriter::getLangOpts() const { +  assert(WritingAST && "can't determine lang opts when not writing AST"); +  return Context->getLangOpts(); +} +  void ASTWriter::WriteAST(Sema &SemaRef,                           const std::string &OutputFile,                           Module *WritingModule, StringRef isysroot, @@ -4258,47 +4058,8 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,      DeclIDs[Context.ObjCInstanceTypeDecl] = PREDEF_DECL_OBJC_INSTANCETYPE_ID;    if (Context.BuiltinVaListDecl)      DeclIDs[Context.getBuiltinVaListDecl()] = PREDEF_DECL_BUILTIN_VA_LIST_ID; - -  if (!Chain) { -    // Make sure that we emit IdentifierInfos (and any attached -    // declarations) for builtins. We don't need to do this when we're -    // emitting chained PCH files, because all of the builtins will be -    // in the original PCH file. -    // FIXME: Modules won't like this at all. -    IdentifierTable &Table = PP.getIdentifierTable(); -    SmallVector<const char *, 32> BuiltinNames; -    if (!Context.getLangOpts().NoBuiltin) { -      Context.BuiltinInfo.GetBuiltinNames(BuiltinNames); -    } -    for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I) -      getIdentifierRef(&Table.get(BuiltinNames[I])); -  } - -  // If there are any out-of-date identifiers, bring them up to date. -  if (ExternalPreprocessorSource *ExtSource = PP.getExternalSource()) { -    // Find out-of-date identifiers. -    SmallVector<IdentifierInfo *, 4> OutOfDate; -    for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(), -                                IDEnd = PP.getIdentifierTable().end(); -         ID != IDEnd; ++ID) { -      if (ID->second->isOutOfDate()) -        OutOfDate.push_back(ID->second); -    } - -    // Update the out-of-date identifiers. -    for (unsigned I = 0, N = OutOfDate.size(); I != N; ++I) { -      ExtSource->updateOutOfDateIdentifier(*OutOfDate[I]); -    } -  } - -  // If we saw any DeclContext updates before we started writing the AST file, -  // make sure all visible decls in those DeclContexts are written out. -  if (!UpdatedDeclContexts.empty()) { -    auto OldUpdatedDeclContexts = std::move(UpdatedDeclContexts); -    UpdatedDeclContexts.clear(); -    for (auto *DC : OldUpdatedDeclContexts) -      AddUpdatedDeclContext(DC); -  } +  if (Context.ExternCContext) +    DeclIDs[Context.ExternCContext] = PREDEF_DECL_EXTERN_C_CONTEXT_ID;    // Build a record containing all of the tentative definitions in this file, in    // TentativeDefinitions order.  Generally, this record will be empty for @@ -4322,31 +4083,15 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    // entire table, since later PCH files in a PCH chain are only interested in    // the results at the end of the chain.    RecordData WeakUndeclaredIdentifiers; -  if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { -    for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator -         I = SemaRef.WeakUndeclaredIdentifiers.begin(), -         E = SemaRef.WeakUndeclaredIdentifiers.end(); I != E; ++I) { -      AddIdentifierRef(I->first, WeakUndeclaredIdentifiers); -      AddIdentifierRef(I->second.getAlias(), WeakUndeclaredIdentifiers); -      AddSourceLocation(I->second.getLocation(), WeakUndeclaredIdentifiers); -      WeakUndeclaredIdentifiers.push_back(I->second.getUsed()); -    } +  for (auto &WeakUndeclaredIdentifier : SemaRef.WeakUndeclaredIdentifiers) { +    IdentifierInfo *II = WeakUndeclaredIdentifier.first; +    WeakInfo &WI = WeakUndeclaredIdentifier.second; +    AddIdentifierRef(II, WeakUndeclaredIdentifiers); +    AddIdentifierRef(WI.getAlias(), WeakUndeclaredIdentifiers); +    AddSourceLocation(WI.getLocation(), WeakUndeclaredIdentifiers); +    WeakUndeclaredIdentifiers.push_back(WI.getUsed());    } -  // Build a record containing all of the locally-scoped extern "C" -  // declarations in this header file. Generally, this record will be -  // empty. -  RecordData LocallyScopedExternCDecls; -  // FIXME: This is filling in the AST file in densemap order which is -  // nondeterminstic! -  for (llvm::DenseMap<DeclarationName, NamedDecl *>::iterator -         TD = SemaRef.LocallyScopedExternCDecls.begin(), -         TDEnd = SemaRef.LocallyScopedExternCDecls.end(); -       TD != TDEnd; ++TD) { -    if (!TD->second->isFromASTFile()) -      AddDeclRef(TD->second, LocallyScopedExternCDecls); -  } -      // Build a record containing all of the ext_vector declarations.    RecordData ExtVectorDecls;    AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls); @@ -4366,10 +4111,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)      AddDeclRef(TD, UnusedLocalTypedefNameCandidates); -  // Build a record containing all of dynamic classes declarations. -  RecordData DynamicClasses; -  AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses); -    // Build a record containing all of pending implicit instantiations.    RecordData PendingInstantiations;    for (std::deque<Sema::PendingImplicitInstantiation>::iterator @@ -4414,6 +4155,20 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,      AddSourceLocation(I->second, UndefinedButUsed);    } +  // Build a record containing all delete-expressions that we would like to +  // analyze later in AST. +  RecordData DeleteExprsToAnalyze; + +  for (const auto &DeleteExprsInfo : +       SemaRef.getMismatchingDeleteExpressions()) { +    AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze); +    DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size()); +    for (const auto &DeleteLoc : DeleteExprsInfo.second) { +      AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze); +      DeleteExprsToAnalyze.push_back(DeleteLoc.second); +    } +  } +    // Write the control block    WriteControlBlock(PP, Context, isysroot, OutputFile); @@ -4443,7 +4198,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    Record.clear();    Record.push_back(TU_UPDATE_LEXICAL);    Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, -                            data(NewGlobalDecls)); +                            bytes(NewGlobalDecls));    // And a visible updates block for the translation unit.    Abv = new llvm::BitCodeAbbrev(); @@ -4453,6 +4208,10 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));    UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv);    WriteDeclContextVisibleUpdate(TU); + +  // If we have any extern "C" names, write out a visible update for them. +  if (Context.ExternCContext) +    WriteDeclContextVisibleUpdate(Context.ExternCContext);    // If the translation unit has an anonymous namespace, and we don't already    // have an update block for it, write it as an update block. @@ -4485,16 +4244,21 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    // Make sure all decls associated with an identifier are registered for    // serialization. +  llvm::SmallVector<const IdentifierInfo*, 256> IIs;    for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),                                IDEnd = PP.getIdentifierTable().end();         ID != IDEnd; ++ID) {      const IdentifierInfo *II = ID->second; -    if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) { -      for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), -                                     DEnd = SemaRef.IdResolver.end(); -           D != DEnd; ++D) { -        GetDeclRef(*D); -      } +    if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) +      IIs.push_back(II); +  } +  // Sort the identifiers to visit based on their name. +  std::sort(IIs.begin(), IIs.end(), llvm::less_ptr<IdentifierInfo>()); +  for (const IdentifierInfo *II : IIs) { +    for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), +                                   DEnd = SemaRef.IdResolver.end(); +         D != DEnd; ++D) { +      GetDeclRef(*D);      }    } @@ -4601,6 +4365,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    if (!DeclUpdatesOffsetsRecord.empty())      Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);    WriteCXXBaseSpecifiersOffsets(); +  WriteCXXCtorInitializersOffsets();    WriteFileDeclIDsMap();    WriteSourceManagerBlock(Context.getSourceManager(), PP); @@ -4637,11 +4402,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,      Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,                        WeakUndeclaredIdentifiers); -  // Write the record containing locally-scoped extern "C" definitions. -  if (!LocallyScopedExternCDecls.empty()) -    Stream.EmitRecord(LOCALLY_SCOPED_EXTERN_C_DECLS, -                      LocallyScopedExternCDecls); -    // Write the record containing ext_vector type names.    if (!ExtVectorDecls.empty())      Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls); @@ -4650,10 +4410,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    if (!VTableUses.empty())      Stream.EmitRecord(VTABLE_USES, VTableUses); -  // Write the record containing dynamic classes declarations. -  if (!DynamicClasses.empty()) -    Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses); -    // Write the record containing potentially unused local typedefs.    if (!UnusedLocalTypedefNameCandidates.empty())      Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES, @@ -4682,7 +4438,10 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    // Write the undefined internal functions and variables, and inline functions.    if (!UndefinedButUsed.empty())      Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed); -   + +  if (!DeleteExprsToAnalyze.empty()) +    Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze); +    // Write the visible updates to DeclContexts.    for (auto *DC : UpdatedDeclContexts)      WriteDeclContextVisibleUpdate(DC); @@ -4720,7 +4479,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,          // FIXME: If the module has macros imported then later has declarations          // imported, this location won't be the right one as a location for the          // declaration imports. -        AddSourceLocation(Import.M->MacroVisibilityLoc, ImportedModules); +        AddSourceLocation(PP.getModuleImportLoc(Import.M), ImportedModules);        }        Stream.EmitRecord(IMPORTED_MODULES, ImportedModules); @@ -4729,7 +4488,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    WriteDeclReplacementsBlock();    WriteRedeclarations(); -  WriteMergedDecls();    WriteObjCCategories();    WriteLateParsedTemplates(SemaRef);    if(!WritingModule) @@ -4784,7 +4542,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {        case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {          auto *RD = cast<CXXRecordDecl>(D); -        AddUpdatedDeclContext(RD->getPrimaryContext()); +        UpdatedDeclContexts.insert(RD->getPrimaryContext());          AddCXXDefinitionData(RD, Record);          Record.push_back(WriteDeclContextLexicalBlock(              *Context, const_cast<CXXRecordDecl *>(RD))); @@ -4828,6 +4586,10 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {          break;        } +      case UPD_CXX_RESOLVED_DTOR_DELETE: +        AddDeclRef(Update.getDecl(), Record); +        break; +        case UPD_CXX_RESOLVED_EXCEPTION_SPEC:          addExceptionSpec(              *this, @@ -4846,10 +4608,15 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {        case UPD_STATIC_LOCAL_NUMBER:          Record.push_back(Update.getNumber());          break; +        case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:          AddSourceRange(D->getAttr<OMPThreadPrivateDeclAttr>()->getRange(),                         Record);          break; + +      case UPD_DECL_EXPORTED: +        Record.push_back(getSubmoduleID(Update.getModule())); +        break;        }      } @@ -4859,8 +4626,6 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {        Record.push_back(Def->isInlined());        AddSourceLocation(Def->getInnerLocStart(), Record);        AddFunctionDefinition(Def, Record); -      if (auto *DD = dyn_cast<CXXDestructorDecl>(Def)) -        Record.push_back(GetDeclRef(DD->getOperatorDelete()));      }      OffsetsRecord.push_back(GetDeclRef(D)); @@ -4868,11 +4633,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {      Stream.EmitRecord(DECL_UPDATES, Record); -    // Flush any statements that were written as part of this update record. -    FlushStmts(); - -    // Flush C++ base specifiers, if there are any. -    FlushCXXBaseSpecifiers(); +    FlushPendingAfterDecl();    }  } @@ -4953,8 +4714,7 @@ MacroID ASTWriter::getMacroID(MacroInfo *MI) {  }  uint64_t ASTWriter::getMacroDirectivesOffset(const IdentifierInfo *Name) { -  assert(IdentMacroDirectivesOffsetMap[Name] && "not set!"); -  return IdentMacroDirectivesOffsetMap[Name]; +  return IdentMacroDirectivesOffsetMap.lookup(Name);  }  void ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) { @@ -4984,8 +4744,16 @@ void ASTWriter::AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record    AddDeclRef(Temp->getDestructor(), Record);  } +void ASTWriter::AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits, +                                          RecordDataImpl &Record) { +  assert(!Inits.empty() && "Empty ctor initializer sets are not recorded"); +  CXXCtorInitializersToWrite.push_back( +      QueuedCXXCtorInitializers(NextCXXCtorInitializersID, Inits)); +  Record.push_back(NextCXXCtorInitializersID++); +} +  void ASTWriter::AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, -                                      CXXBaseSpecifier const *BasesEnd, +                                        CXXBaseSpecifier const *BasesEnd,                                          RecordDataImpl &Record) {    assert(Bases != BasesEnd && "Empty base-specifier sets are not recorded");    CXXBaseSpecifiersToWrite.push_back( @@ -5060,46 +4828,40 @@ void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) {    Record.push_back(GetOrCreateTypeID(T));  } -TypeID ASTWriter::GetOrCreateTypeID( QualType T) { -  assert(Context); -  return MakeTypeID(*Context, T, -              std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this)); -} - -TypeID ASTWriter::getTypeID(QualType T) const { +TypeID ASTWriter::GetOrCreateTypeID(QualType T) {    assert(Context); -  return MakeTypeID(*Context, T, -              std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this)); -} +  return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx { +    if (T.isNull()) +      return TypeIdx(); +    assert(!T.getLocalFastQualifiers()); -TypeIdx ASTWriter::GetOrCreateTypeIdx(QualType T) { -  if (T.isNull()) -    return TypeIdx(); -  assert(!T.getLocalFastQualifiers()); +    TypeIdx &Idx = TypeIdxs[T]; +    if (Idx.getIndex() == 0) { +      if (DoneWritingDeclsAndTypes) { +        assert(0 && "New type seen after serializing all the types to emit!"); +        return TypeIdx(); +      } -  TypeIdx &Idx = TypeIdxs[T]; -  if (Idx.getIndex() == 0) { -    if (DoneWritingDeclsAndTypes) { -      assert(0 && "New type seen after serializing all the types to emit!"); -      return TypeIdx(); +      // We haven't seen this type before. Assign it a new ID and put it +      // into the queue of types to emit. +      Idx = TypeIdx(NextTypeID++); +      DeclTypesToEmit.push(T);      } - -    // We haven't seen this type before. Assign it a new ID and put it -    // into the queue of types to emit. -    Idx = TypeIdx(NextTypeID++); -    DeclTypesToEmit.push(T); -  } -  return Idx; +    return Idx; +  });  } -TypeIdx ASTWriter::getTypeIdx(QualType T) const { -  if (T.isNull()) -    return TypeIdx(); -  assert(!T.getLocalFastQualifiers()); +TypeID ASTWriter::getTypeID(QualType T) const { +  assert(Context); +  return MakeTypeID(*Context, T, [&](QualType T) -> TypeIdx { +    if (T.isNull()) +      return TypeIdx(); +    assert(!T.getLocalFastQualifiers()); -  TypeIdxMap::const_iterator I = TypeIdxs.find(T); -  assert(I != TypeIdxs.end() && "Type not emitted!"); -  return I->second; +    TypeIdxMap::const_iterator I = TypeIdxs.find(T); +    assert(I != TypeIdxs.end() && "Type not emitted!"); +    return I->second; +  });  }  void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { @@ -5234,13 +4996,10 @@ unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) {    // already done so.    auto It = AnonymousDeclarationNumbers.find(D);    if (It == AnonymousDeclarationNumbers.end()) { -    unsigned Index = 0; -    for (Decl *LexicalD : D->getLexicalDeclContext()->decls()) { -      auto *ND = dyn_cast<NamedDecl>(LexicalD); -      if (!ND || !needsAnonymousDeclarationNumber(ND)) -        continue; -      AnonymousDeclarationNumbers[ND] = Index++; -    } +    auto *DC = D->getLexicalDeclContext(); +    numberAnonymousDeclsWithin(DC, [&](const NamedDecl *ND, unsigned Number) { +      AnonymousDeclarationNumbers[ND] = Number; +    });      It = AnonymousDeclarationNumbers.find(D);      assert(It != AnonymousDeclarationNumbers.end() && @@ -5555,7 +5314,8 @@ void ASTWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,  void ASTWriter::FlushCXXBaseSpecifiers() {    RecordData Record; -  for (unsigned I = 0, N = CXXBaseSpecifiersToWrite.size(); I != N; ++I) { +  unsigned N = CXXBaseSpecifiersToWrite.size(); +  for (unsigned I = 0; I != N; ++I) {      Record.clear();      // Record the offset of this base-specifier set. @@ -5579,6 +5339,8 @@ void ASTWriter::FlushCXXBaseSpecifiers() {      FlushStmts();    } +  assert(N == CXXBaseSpecifiersToWrite.size() && +         "added more base specifiers while writing base specifiers");    CXXBaseSpecifiersToWrite.clear();  } @@ -5620,6 +5382,36 @@ void ASTWriter::AddCXXCtorInitializers(    }  } +void ASTWriter::FlushCXXCtorInitializers() { +  RecordData Record; + +  unsigned N = CXXCtorInitializersToWrite.size(); +  (void)N; // Silence unused warning in non-assert builds. +  for (auto &Init : CXXCtorInitializersToWrite) { +    Record.clear(); + +    // Record the offset of this mem-initializer list. +    unsigned Index = Init.ID - 1; +    if (Index == CXXCtorInitializersOffsets.size()) +      CXXCtorInitializersOffsets.push_back(Stream.GetCurrentBitNo()); +    else { +      if (Index > CXXCtorInitializersOffsets.size()) +        CXXCtorInitializersOffsets.resize(Index + 1); +      CXXCtorInitializersOffsets[Index] = Stream.GetCurrentBitNo(); +    } + +    AddCXXCtorInitializers(Init.Inits.data(), Init.Inits.size(), Record); +    Stream.EmitRecord(serialization::DECL_CXX_CTOR_INITIALIZERS, Record); + +    // Flush any expressions that were written as part of the initializers. +    FlushStmts(); +  } + +  assert(N == CXXCtorInitializersToWrite.size() && +         "added more ctor initializers while writing ctor initializers"); +  CXXCtorInitializersToWrite.clear(); +} +  void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) {    auto &Data = D->data();    Record.push_back(Data.IsLambda); @@ -5725,6 +5517,8 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) {    Chain = Reader; +  // Note, this will get called multiple times, once one the reader starts up +  // and again each time it's done reading a PCH or module.    FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls();    FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes();    FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); @@ -5772,7 +5566,7 @@ void ASTWriter::SelectorRead(SelectorID ID, Selector S) {  }  void ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID, -                                    MacroDefinition *MD) { +                                    MacroDefinitionRecord *MD) {    assert(MacroDefinitions.find(MD) == MacroDefinitions.end());    MacroDefinitions[MD] = ID;  } @@ -5809,7 +5603,7 @@ void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {    assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");    assert(!WritingAST && "Already writing the AST!"); -  AddUpdatedDeclContext(DC); +  UpdatedDeclContexts.insert(DC);    UpdatingVisibleDecls.push_back(D);  } @@ -5863,21 +5657,36 @@ void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,  }  void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) { -  assert(!WritingAST && "Already writing the AST!"); -  FD = FD->getCanonicalDecl(); -  if (!FD->isFromASTFile()) -    return; // Not a function declared in PCH and defined outside. - -  DeclUpdates[FD].push_back(UPD_CXX_RESOLVED_EXCEPTION_SPEC); +  assert(!DoneWritingDeclsAndTypes && "Already done writing updates!"); +  if (!Chain) return; +  Chain->forEachFormerlyCanonicalImportedDecl(FD, [&](const Decl *D) { +    // If we don't already know the exception specification for this redecl +    // chain, add an update record for it. +    if (isUnresolvedExceptionSpec(cast<FunctionDecl>(D) +                                      ->getType() +                                      ->castAs<FunctionProtoType>() +                                      ->getExceptionSpecType())) +      DeclUpdates[D].push_back(UPD_CXX_RESOLVED_EXCEPTION_SPEC); +  });  }  void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {    assert(!WritingAST && "Already writing the AST!"); -  FD = FD->getCanonicalDecl(); -  if (!FD->isFromASTFile()) -    return; // Not a function declared in PCH and defined outside. +  if (!Chain) return; +  Chain->forEachFormerlyCanonicalImportedDecl(FD, [&](const Decl *D) { +    DeclUpdates[D].push_back( +        DeclUpdate(UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType)); +  }); +} -  DeclUpdates[FD].push_back(DeclUpdate(UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType)); +void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD, +                                       const FunctionDecl *Delete) { +  assert(!WritingAST && "Already writing the AST!"); +  assert(Delete && "Not given an operator delete"); +  if (!Chain) return; +  Chain->forEachFormerlyCanonicalImportedDecl(DD, [&](const Decl *D) { +    DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_RESOLVED_DTOR_DELETE, Delete)); +  });  }  void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { @@ -5894,8 +5703,7 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {    if (!D->isFromASTFile())      return; -  DeclUpdates[D].push_back( -      DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION)); +  DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));  }  void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { @@ -5951,3 +5759,12 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {    DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE));  } + +void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { +  assert(!WritingAST && "Already writing the AST!"); +  assert(D->isHidden() && "expected a hidden declaration"); +  if (!D->isFromASTFile()) +    return; + +  DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_EXPORTED, M)); +} | 
