diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 | 
| commit | 06d4ba388873e6d1cfa9cd715a8935ecc8cd2097 (patch) | |
| tree | 3eb853da77d46cc77c4b017525a422f9ddb1385b /lib/Serialization | |
| parent | 30d791273d07fac9c0c1641a0731191bca6e8606 (diff) | |
Diffstat (limited to 'lib/Serialization')
| -rw-r--r-- | lib/Serialization/ASTCommon.cpp | 18 | ||||
| -rw-r--r-- | lib/Serialization/ASTCommon.h | 13 | ||||
| -rw-r--r-- | lib/Serialization/ASTReader.cpp | 1341 | ||||
| -rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 630 | ||||
| -rw-r--r-- | lib/Serialization/ASTReaderInternals.h | 11 | ||||
| -rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 195 | ||||
| -rw-r--r-- | lib/Serialization/ASTWriter.cpp | 883 | ||||
| -rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 160 | ||||
| -rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 140 | ||||
| -rw-r--r-- | lib/Serialization/GlobalModuleIndex.cpp | 25 | ||||
| -rw-r--r-- | lib/Serialization/Module.cpp | 2 | ||||
| -rw-r--r-- | lib/Serialization/ModuleManager.cpp | 84 | 
12 files changed, 2397 insertions, 1105 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index ad046ffa277a..13393225b60e 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -12,6 +12,7 @@  //===----------------------------------------------------------------------===//  #include "ASTCommon.h" +#include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclObjC.h"  #include "clang/Basic/IdentifierTable.h"  #include "clang/Serialization/ASTDeserializationListener.h" @@ -150,7 +151,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {    switch (static_cast<Decl::Kind>(Kind)) {    case Decl::TranslationUnit: // Special case of a "merged" declaration.    case Decl::Namespace: -  case Decl::NamespaceAlias: // FIXME: Not yet redeclarable, but will be. +  case Decl::NamespaceAlias:    case Decl::Typedef:    case Decl::TypeAlias:    case Decl::Enum: @@ -188,8 +189,6 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {    case Decl::MSProperty:    case Decl::ObjCIvar:    case Decl::ObjCAtDefsField: -  case Decl::ImplicitParam: -  case Decl::ParmVar:    case Decl::NonTypeTemplateParm:    case Decl::TemplateTemplateParm:    case Decl::Using: @@ -212,7 +211,20 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {    case Decl::Import:    case Decl::OMPThreadPrivate:      return false; + +  // These indirectly derive from Redeclarable<T> but are not actually +  // redeclarable. +  case Decl::ImplicitParam: +  case Decl::ParmVar: +    return false;    }    llvm_unreachable("Unhandled declaration kind");  } + +bool serialization::needsAnonymousDeclarationNumber(const NamedDecl *D) { +  if (D->getDeclName() || !isa<CXXRecordDecl>(D->getLexicalDeclContext())) +    return false; +  return isa<TagDecl>(D) || isa<FieldDecl>(D); +} + diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h index c7669749260b..38a0ff5fbd4e 100644 --- a/lib/Serialization/ASTCommon.h +++ b/lib/Serialization/ASTCommon.h @@ -11,8 +11,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SERIALIZATION_LIB_AST_COMMON_H -#define LLVM_CLANG_SERIALIZATION_LIB_AST_COMMON_H +#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTCOMMON_H +#define LLVM_CLANG_LIB_SERIALIZATION_ASTCOMMON_H  #include "clang/AST/ASTContext.h"  #include "clang/Serialization/ASTBitCodes.h" @@ -25,14 +25,15 @@ enum DeclUpdateKind {    UPD_CXX_ADDED_IMPLICIT_MEMBER,    UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,    UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, +  UPD_CXX_ADDED_FUNCTION_DEFINITION,    UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER, -  UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION,    UPD_CXX_INSTANTIATED_CLASS_DEFINITION,    UPD_CXX_RESOLVED_EXCEPTION_SPEC,    UPD_CXX_DEDUCED_RETURN_TYPE,    UPD_DECL_MARKED_USED,    UPD_MANGLING_NUMBER, -  UPD_STATIC_LOCAL_NUMBER +  UPD_STATIC_LOCAL_NUMBER, +  UPD_DECL_MARKED_OPENMP_THREADPRIVATE  };  TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT); @@ -80,6 +81,10 @@ const DeclContext *getDefinitiveDeclContext(const DeclContext *DC);  /// \brief Determine whether the given declaration kind is redeclarable.  bool isRedeclarableDeclKind(unsigned Kind); +/// \brief Determine whether the given declaration needs an anonymous +/// declaration number. +bool needsAnonymousDeclarationNumber(const NamedDecl *D); +  } // namespace serialization  } // namespace clang diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index ae41654904c6..416164ebb7d2 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -80,10 +80,14 @@ void ChainedASTReaderListener::ReadModuleMapFile(StringRef ModuleMapPath) {    First->ReadModuleMapFile(ModuleMapPath);    Second->ReadModuleMapFile(ModuleMapPath);  } -bool ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts, -                                                   bool Complain) { -  return First->ReadLanguageOptions(LangOpts, Complain) || -         Second->ReadLanguageOptions(LangOpts, Complain); +bool +ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts, +                                              bool Complain, +                                              bool AllowCompatibleDifferences) { +  return First->ReadLanguageOptions(LangOpts, Complain, +                                    AllowCompatibleDifferences) || +         Second->ReadLanguageOptions(LangOpts, Complain, +                                     AllowCompatibleDifferences);  }  bool  ChainedASTReaderListener::ReadTargetOptions(const TargetOptions &TargetOpts, @@ -155,11 +159,14 @@ ASTReaderListener::~ASTReaderListener() {}  /// language options.  ///  /// \param Diags If non-NULL, diagnostics will be emitted via this engine. +/// \param AllowCompatibleDifferences If true, differences between compatible +///        language options will be permitted.  ///  /// \returns true if the languagae options mis-match, false otherwise.  static bool checkLanguageOptions(const LangOptions &LangOpts,                                   const LangOptions &ExistingLangOpts, -                                 DiagnosticsEngine *Diags) { +                                 DiagnosticsEngine *Diags, +                                 bool AllowCompatibleDifferences = true) {  #define LANGOPT(Name, Bits, Default, Description)                 \    if (ExistingLangOpts.Name != LangOpts.Name) {                   \      if (Diags)                                                    \ @@ -184,6 +191,14 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,      return true;                                               \    } +#define COMPATIBLE_LANGOPT(Name, Bits, Default, Description)  \ +  if (!AllowCompatibleDifferences)                            \ +    LANGOPT(Name, Bits, Default, Description) + +#define COMPATIBLE_ENUM_LANGOPT(Name, Bits, Default, Description)  \ +  if (!AllowCompatibleDifferences)                                 \ +    ENUM_LANGOPT(Name, Bits, Default, Description) +  #define BENIGN_LANGOPT(Name, Bits, Default, Description)  #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)  #include "clang/Basic/LangOptions.def" @@ -278,10 +293,12 @@ static bool checkTargetOptions(const TargetOptions &TargetOpts,  bool  PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts, -                                  bool Complain) { +                                  bool Complain, +                                  bool AllowCompatibleDifferences) {    const LangOptions &ExistingLangOpts = PP.getLangOpts();    return checkLanguageOptions(LangOpts, ExistingLangOpts, -                              Complain? &Reader.Diags : nullptr); +                              Complain ? &Reader.Diags : nullptr, +                              AllowCompatibleDifferences);  }  bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts, @@ -389,14 +406,14 @@ bool PCHValidator::ReadDiagnosticOptions(    // If the original import came from a file explicitly generated by the user,    // don't check the diagnostic mappings.    // FIXME: currently this is approximated by checking whether this is not a -  // module import. +  // module import of an implicitly-loaded module file.    // Note: ModuleMgr.rbegin() may not be the current module, but it must be in    // the transitive closure of its imports, since unrelated modules cannot be    // imported until after this module finishes validation.    ModuleFile *TopImport = *ModuleMgr.rbegin();    while (!TopImport->ImportedBy.empty())      TopImport = TopImport->ImportedBy[0]; -  if (TopImport->Kind != MK_Module) +  if (TopImport->Kind != MK_ImplicitModule)      return false;    StringRef ModuleName = TopImport->ModuleName; @@ -543,8 +560,7 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,        continue;      SuggestedPredefines += "#include \""; -    SuggestedPredefines += -      HeaderSearch::NormalizeDashIncludePath(File, FileMgr); +    SuggestedPredefines += File;      SuggestedPredefines += "\"\n";    } @@ -556,8 +572,7 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,        continue;      SuggestedPredefines += "#__include_macros \""; -    SuggestedPredefines += -      HeaderSearch::NormalizeDashIncludePath(File, FileMgr); +    SuggestedPredefines += File;      SuggestedPredefines += "\"\n##\n";    } @@ -635,14 +650,14 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,    Result.ID = Reader.getGlobalSelectorID(        F, endian::readNext<uint32_t, little, unaligned>(d)); -  unsigned NumInstanceMethodsAndBits = -      endian::readNext<uint16_t, little, unaligned>(d); -  unsigned NumFactoryMethodsAndBits = -      endian::readNext<uint16_t, little, unaligned>(d); -  Result.InstanceBits = NumInstanceMethodsAndBits & 0x3; -  Result.FactoryBits = NumFactoryMethodsAndBits & 0x3; -  unsigned NumInstanceMethods = NumInstanceMethodsAndBits >> 2; -  unsigned NumFactoryMethods = NumFactoryMethodsAndBits >> 2; +  unsigned FullInstanceBits = endian::readNext<uint16_t, little, unaligned>(d); +  unsigned FullFactoryBits = endian::readNext<uint16_t, little, unaligned>(d); +  Result.InstanceBits = FullInstanceBits & 0x3; +  Result.InstanceHasMoreThanOneDecl = (FullInstanceBits >> 2) & 0x1; +  Result.FactoryBits = FullFactoryBits & 0x3; +  Result.FactoryHasMoreThanOneDecl = (FullFactoryBits >> 2) & 0x1; +  unsigned NumInstanceMethods = FullInstanceBits >> 3; +  unsigned NumFactoryMethods = FullFactoryBits >> 3;    // Load instance methods    for (unsigned I = 0; I != NumInstanceMethods; ++I) { @@ -774,15 +789,16 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,      DataLen -= 4;      SmallVector<uint32_t, 8> LocalMacroIDs;      if (hasSubmoduleMacros) { -      while (uint32_t LocalMacroID = -                 endian::readNext<uint32_t, little, unaligned>(d)) { +      while (true) { +        uint32_t LocalMacroID = +            endian::readNext<uint32_t, little, unaligned>(d);          DataLen -= 4; +        if (LocalMacroID == 0xdeadbeef) break;          LocalMacroIDs.push_back(LocalMacroID);        } -      DataLen -= 4;      } -    if (F.Kind == MK_Module) { +    if (F.Kind == MK_ImplicitModule || F.Kind == MK_ExplicitModule) {        // Macro definitions are stored from newest to oldest, so reverse them        // before registering them.        llvm::SmallVector<unsigned, 8> MacroSizes; @@ -1013,7 +1029,7 @@ void ASTReader::Error(unsigned DiagID,  /// \brief Read the line table in the source manager block.  /// \returns true if there was an error.  bool ASTReader::ParseLineTable(ModuleFile &F, -                               SmallVectorImpl<uint64_t> &Record) { +                               const RecordData &Record) {    unsigned Idx = 0;    LineTableInfo &LineTable = SourceMgr.getLineTable(); @@ -1021,10 +1037,7 @@ bool ASTReader::ParseLineTable(ModuleFile &F,    std::map<int, int> FileIDs;    for (int I = 0, N = Record[Idx++]; I != N; ++I) {      // Extract the file name -    unsigned FilenameLen = Record[Idx++]; -    std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen); -    Idx += FilenameLen; -    MaybeAddSystemRootToFilename(F, Filename); +    auto Filename = ReadPath(F, Record, Idx);      FileIDs[I] = LineTable.getLineTableFilenameID(Filename);    } @@ -1225,9 +1238,9 @@ bool ASTReader::ReadSLocEntry(int ID) {          return true;        } -      llvm::MemoryBuffer *Buffer +      std::unique_ptr<llvm::MemoryBuffer> Buffer          = llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), File->getName()); -      SourceMgr.overrideFileContents(File, Buffer); +      SourceMgr.overrideFileContents(File, std::move(Buffer));      }      break; @@ -1239,7 +1252,8 @@ bool ASTReader::ReadSLocEntry(int ID) {      SrcMgr::CharacteristicKind        FileCharacter = (SrcMgr::CharacteristicKind)Record[2];      SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]); -    if (IncludeLoc.isInvalid() && F->Kind == MK_Module) { +    if (IncludeLoc.isInvalid() && +        (F->Kind == MK_ImplicitModule || F->Kind == MK_ExplicitModule)) {        IncludeLoc = getImportLocation(F);      }      unsigned Code = SLocEntryCursor.ReadCode(); @@ -1252,10 +1266,10 @@ bool ASTReader::ReadSLocEntry(int ID) {        return true;      } -    llvm::MemoryBuffer *Buffer -      = llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name); -    SourceMgr.createFileID(Buffer, FileCharacter, ID, BaseOffset + Offset, -                           IncludeLoc); +    std::unique_ptr<llvm::MemoryBuffer> Buffer = +        llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name); +    SourceMgr.createFileID(std::move(Buffer), FileCharacter, ID, +                           BaseOffset + Offset, IncludeLoc);      break;    } @@ -1285,7 +1299,7 @@ std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) {    // Find which module file this entry lands in.    ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second; -  if (M->Kind != MK_Module) +  if (M->Kind != MK_ImplicitModule && M->Kind != MK_ExplicitModule)      return std::make_pair(SourceLocation(), "");    // FIXME: Can we map this down to a particular submodule? That would be @@ -1466,11 +1480,11 @@ ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const  unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) {    return llvm::hash_combine(ikey.Size, ikey.ModTime);  } -     +  HeaderFileInfoTrait::internal_key_type   HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) {    internal_key_type ikey = { FE->getSize(), FE->getModificationTime(), -                             FE->getName() }; +                             FE->getName(), /*Imported*/false };    return ikey;  } @@ -1478,14 +1492,24 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) {    if (a.Size != b.Size || a.ModTime != b.ModTime)      return false; -  if (strcmp(a.Filename, b.Filename) == 0) +  if (llvm::sys::path::is_absolute(a.Filename) && +      strcmp(a.Filename, b.Filename) == 0)      return true;    // Determine whether the actual files are equivalent.    FileManager &FileMgr = Reader.getFileManager(); -  const FileEntry *FEA = FileMgr.getFile(a.Filename); -  const FileEntry *FEB = FileMgr.getFile(b.Filename); -  return (FEA && FEA == FEB); +  auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* { +    if (!Key.Imported) +      return FileMgr.getFile(Key.Filename); + +    std::string Resolved = Key.Filename; +    Reader.ResolveImportedPath(M, Resolved); +    return FileMgr.getFile(Resolved); +  }; + +  const FileEntry *FEA = GetFile(a); +  const FileEntry *FEB = GetFile(b); +  return FEA && FEA == FEB;  }  std::pair<unsigned, unsigned> @@ -1503,6 +1527,7 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {    ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d));    ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d));    ikey.Filename = (const char *)d; +  ikey.Imported = true;    return ikey;  } @@ -1542,7 +1567,14 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,        FileManager &FileMgr = Reader.getFileManager();        ModuleMap &ModMap =            Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); -      ModMap.addHeader(Mod, FileMgr.getFile(key.Filename), HFI.getHeaderRole()); +      // FIXME: This information should be propagated through the +      // SUBMODULE_HEADER etc records rather than from here. +      // FIXME: We don't ever mark excluded headers. +      std::string Filename = key.Filename; +      if (key.Imported) +        Reader.ResolveImportedPath(M, Filename); +      Module::Header H = { key.Filename, FileMgr.getFile(Filename) }; +      ModMap.addHeader(Mod, H, HFI.getHeaderRole());      }    } @@ -1732,10 +1764,12 @@ struct ASTReader::ModuleMacroInfo {      return llvm::makeArrayRef(Overrides + 1, *Overrides);    } -  DefMacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const { +  MacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const {      if (!MI) -      return nullptr; -    return PP.AllocateDefMacroDirective(MI, ImportLoc, /*isImported=*/true); +      return PP.AllocateUndefMacroDirective(ImportLoc, SubModID, +                                            getOverriddenSubmodules()); +    return PP.AllocateDefMacroDirective(MI, ImportLoc, SubModID, +                                        getOverriddenSubmodules());    }  }; @@ -1772,7 +1806,8 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,                                      const PendingMacroInfo &PMInfo) {    assert(II); -  if (PMInfo.M->Kind != MK_Module) { +  if (PMInfo.M->Kind != MK_ImplicitModule && +      PMInfo.M->Kind != MK_ExplicitModule) {      installPCHMacroDirectives(II, *PMInfo.M,                                PMInfo.PCHMacroData.MacroDirectivesOffset);      return; @@ -1790,13 +1825,13 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,      // install if we make this module visible.      HiddenNamesMap[Owner].HiddenMacros.insert(std::make_pair(II, MMI));    } else { -    installImportedMacro(II, MMI, Owner, /*FromFinalization*/false); +    installImportedMacro(II, MMI, Owner);    }  }  void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,                                            ModuleFile &M, uint64_t Offset) { -  assert(M.Kind != MK_Module); +  assert(M.Kind != MK_ImplicitModule && M.Kind != MK_ExplicitModule);    BitstreamCursor &Cursor = M.MacroCursor;    SavedStreamPosition SavedPosition(Cursor); @@ -1828,23 +1863,36 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,      case MacroDirective::MD_Define: {        GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]);        MacroInfo *MI = getMacro(GMacID); -      bool isImported = Record[Idx++]; -      bool isAmbiguous = Record[Idx++]; +      SubmoduleID ImportedFrom = Record[Idx++]; +      bool IsAmbiguous = Record[Idx++]; +      llvm::SmallVector<unsigned, 4> Overrides; +      if (ImportedFrom) { +        Overrides.insert(Overrides.end(), +                         &Record[Idx] + 1, &Record[Idx] + 1 + Record[Idx]); +        Idx += Overrides.size() + 1; +      }        DefMacroDirective *DefMD = -          PP.AllocateDefMacroDirective(MI, Loc, isImported); -      DefMD->setAmbiguous(isAmbiguous); +          PP.AllocateDefMacroDirective(MI, Loc, ImportedFrom, Overrides); +      DefMD->setAmbiguous(IsAmbiguous);        MD = DefMD;        break;      } -    case MacroDirective::MD_Undefine: -      MD = PP.AllocateUndefMacroDirective(Loc); +    case MacroDirective::MD_Undefine: { +      SubmoduleID ImportedFrom = Record[Idx++]; +      llvm::SmallVector<unsigned, 4> Overrides; +      if (ImportedFrom) { +        Overrides.insert(Overrides.end(), +                         &Record[Idx] + 1, &Record[Idx] + 1 + Record[Idx]); +        Idx += Overrides.size() + 1; +      } +      MD = PP.AllocateUndefMacroDirective(Loc, ImportedFrom, Overrides);        break; -    case MacroDirective::MD_Visibility: { +    } +    case MacroDirective::MD_Visibility:        bool isPublic = Record[Idx++];        MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic);        break;      } -    }      if (!Latest)        Latest = MD; @@ -1877,19 +1925,27 @@ static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI,  }  void ASTReader::removeOverriddenMacros(IdentifierInfo *II, +                                       SourceLocation ImportLoc,                                         AmbiguousMacros &Ambig,                                         ArrayRef<SubmoduleID> Overrides) {    for (unsigned OI = 0, ON = Overrides.size(); OI != ON; ++OI) {      SubmoduleID OwnerID = Overrides[OI];      // If this macro is not yet visible, remove it from the hidden names list. +    // It won't be there if we're in the middle of making the owner visible.      Module *Owner = getSubmodule(OwnerID); -    HiddenNames &Hidden = HiddenNamesMap[Owner]; -    HiddenMacrosMap::iterator HI = Hidden.HiddenMacros.find(II); -    if (HI != Hidden.HiddenMacros.end()) { -      auto SubOverrides = HI->second->getOverriddenSubmodules(); -      Hidden.HiddenMacros.erase(HI); -      removeOverriddenMacros(II, Ambig, SubOverrides); +    auto HiddenIt = HiddenNamesMap.find(Owner); +    if (HiddenIt != HiddenNamesMap.end()) { +      HiddenNames &Hidden = HiddenIt->second; +      HiddenMacrosMap::iterator HI = Hidden.HiddenMacros.find(II); +      if (HI != Hidden.HiddenMacros.end()) { +        // Register the macro now so we don't lose it when we re-export. +        PP.appendMacroDirective(II, HI->second->import(PP, ImportLoc)); + +        auto SubOverrides = HI->second->getOverriddenSubmodules(); +        Hidden.HiddenMacros.erase(HI); +        removeOverriddenMacros(II, ImportLoc, Ambig, SubOverrides); +      }      }      // If this macro is already in our list of conflicts, remove it from there. @@ -1903,6 +1959,7 @@ void ASTReader::removeOverriddenMacros(IdentifierInfo *II,  ASTReader::AmbiguousMacros *  ASTReader::removeOverriddenMacros(IdentifierInfo *II, +                                  SourceLocation ImportLoc,                                    ArrayRef<SubmoduleID> Overrides) {    MacroDirective *Prev = PP.getMacroDirective(II);    if (!Prev && Overrides.empty()) @@ -1915,7 +1972,7 @@ ASTReader::removeOverriddenMacros(IdentifierInfo *II,      AmbiguousMacros &Ambig = AmbiguousMacroDefs[II];      Ambig.push_back(PrevDef); -    removeOverriddenMacros(II, Ambig, Overrides); +    removeOverriddenMacros(II, ImportLoc, Ambig, Overrides);      if (!Ambig.empty())        return &Ambig; @@ -1927,7 +1984,7 @@ ASTReader::removeOverriddenMacros(IdentifierInfo *II,      if (PrevDef)        Ambig.push_back(PrevDef); -    removeOverriddenMacros(II, Ambig, Overrides); +    removeOverriddenMacros(II, ImportLoc, Ambig, Overrides);      if (!Ambig.empty()) {        AmbiguousMacros &Result = AmbiguousMacroDefs[II]; @@ -1941,11 +1998,11 @@ ASTReader::removeOverriddenMacros(IdentifierInfo *II,  }  void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI, -                                     Module *Owner, bool FromFinalization) { +                                     Module *Owner) {    assert(II && Owner);    SourceLocation ImportLoc = Owner->MacroVisibilityLoc; -  if (ImportLoc.isInvalid() && !FromFinalization) { +  if (ImportLoc.isInvalid()) {      // FIXME: If we made macros from this module visible but didn't provide a      // source location for the import, we don't have a location for the macro.      // Use the location at which the containing module file was first imported @@ -1955,18 +2012,16 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,    }    AmbiguousMacros *Prev = -      removeOverriddenMacros(II, MMI->getOverriddenSubmodules()); +      removeOverriddenMacros(II, ImportLoc, MMI->getOverriddenSubmodules());    // Create a synthetic macro definition corresponding to the import (or null    // if this was an undefinition of the macro). -  DefMacroDirective *MD = MMI->import(PP, ImportLoc); +  MacroDirective *Imported = MMI->import(PP, ImportLoc); +  DefMacroDirective *MD = dyn_cast<DefMacroDirective>(Imported);    // If there's no ambiguity, just install the macro.    if (!Prev) { -    if (MD) -      PP.appendMacroDirective(II, MD); -    else -      PP.appendMacroDirective(II, PP.AllocateUndefMacroDirective(ImportLoc)); +    PP.appendMacroDirective(II, Imported);      return;    }    assert(!Prev->empty()); @@ -1974,10 +2029,14 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,    if (!MD) {      // We imported a #undef that didn't remove all prior definitions. The most      // recent prior definition remains, and we install it in the place of the -    // imported directive. +    // imported directive, as if by a local #pragma pop_macro.      MacroInfo *NewMI = Prev->back()->getInfo();      Prev->pop_back(); -    MD = PP.AllocateDefMacroDirective(NewMI, ImportLoc, /*Imported*/true); +    MD = PP.AllocateDefMacroDirective(NewMI, ImportLoc); + +    // Install our #undef first so that we don't lose track of it. We'll replace +    // this with whichever macro definition ends up winning. +    PP.appendMacroDirective(II, Imported);    }    // We're introducing a macro definition that creates or adds to an ambiguity. @@ -2035,14 +2094,14 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {    off_t StoredSize;    time_t StoredTime;    bool Overridden; -   +    assert(Record[0] == ID && "Bogus stored ID or offset");    StoredSize = static_cast<off_t>(Record[1]);    StoredTime = static_cast<time_t>(Record[2]);    Overridden = static_cast<bool>(Record[3]);    Filename = Blob; -  MaybeAddSystemRootToFilename(F, Filename); -   +  ResolveImportedPath(F, Filename); +    InputFileInfo R = { std::move(Filename), StoredSize, StoredTime, Overridden };    return R;  } @@ -2128,12 +2187,23 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {    bool IsOutOfDate = false;    // For an overridden file, there is nothing to validate. -  if (!Overridden && (StoredSize != File->getSize() -#if !defined(LLVM_ON_WIN32) +  if (!Overridden && // +      (StoredSize != File->getSize() || +#if defined(LLVM_ON_WIN32) +       false +#else         // In our regression testing, the Windows file system seems to         // have inconsistent modification times that sometimes         // erroneously trigger this error-handling path. -       || StoredTime != File->getModificationTime() +       // +       // This also happens in networked file systems, so disable this +       // check if validation is disabled or if we have an explicitly +       // built PCM file. +       // +       // FIXME: Should we also do this for PCH files? They could also +       // reasonably get shared across a network during a distributed build. +       (StoredTime != File->getModificationTime() && !DisableValidation && +        F.Kind != MK_ExplicitModule)  #endif         )) {      if (Complain) { @@ -2169,46 +2239,22 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {    return IF;  } -const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) { -  ModuleFile &M = ModuleMgr.getPrimaryModule(); -  std::string Filename = filenameStrRef; -  MaybeAddSystemRootToFilename(M, Filename); -  const FileEntry *File = FileMgr.getFile(Filename); -  if (File == nullptr && !M.OriginalDir.empty() && !CurrentDir.empty() && -      M.OriginalDir != CurrentDir) { -    std::string resolved = resolveFileRelativeToOriginalDir(Filename, -                                                            M.OriginalDir, -                                                            CurrentDir); -    if (!resolved.empty()) -      File = FileMgr.getFile(resolved); -  } - -  return File; +/// \brief If we are loading a relocatable PCH or module file, and the filename +/// is not an absolute path, add the system or module root to the beginning of +/// the file name. +void ASTReader::ResolveImportedPath(ModuleFile &M, std::string &Filename) { +  // Resolve relative to the base directory, if we have one. +  if (!M.BaseDirectory.empty()) +    return ResolveImportedPath(Filename, M.BaseDirectory);  } -/// \brief If we are loading a relocatable PCH file, and the filename is -/// not an absolute path, add the system root to the beginning of the file -/// name. -void ASTReader::MaybeAddSystemRootToFilename(ModuleFile &M, -                                             std::string &Filename) { -  // If this is not a relocatable PCH file, there's nothing to do. -  if (!M.RelocatablePCH) -    return; - +void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) {    if (Filename.empty() || llvm::sys::path::is_absolute(Filename))      return; -  if (isysroot.empty()) { -    // If no system root was given, default to '/' -    Filename.insert(Filename.begin(), '/'); -    return; -  } - -  unsigned Length = isysroot.size(); -  if (isysroot[Length - 1] != '/') -    Filename.insert(Filename.begin(), '/'); - -  Filename.insert(Filename.begin(), isysroot.begin(), isysroot.end()); +  SmallString<128> Buffer; +  llvm::sys::path::append(Buffer, Prefix, Filename); +  Filename.assign(Buffer.begin(), Buffer.end());  }  ASTReader::ASTReadResult @@ -2223,8 +2269,16 @@ ASTReader::ReadControlBlock(ModuleFile &F,      return Failure;    } +  // Should we allow the configuration of the module file to differ from the +  // configuration of the current translation unit in a compatible way? +  // +  // FIXME: Allow this for files explicitly specified with -include-pch too. +  bool AllowCompatibleConfigurationMismatch = F.Kind == MK_ExplicitModule; +    // Read all of the records and blocks in the control block.    RecordData Record; +  unsigned NumInputs = 0; +  unsigned NumUserInputs = 0;    while (1) {      llvm::BitstreamEntry Entry = Stream.advance(); @@ -2237,15 +2291,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,        const HeaderSearchOptions &HSOpts =            PP.getHeaderSearchInfo().getHeaderSearchOpts(); -      // All user input files reside at the index range [0, Record[1]), and -      // system input files reside at [Record[1], Record[0]). -      // Record is the one from INPUT_FILE_OFFSETS. -      unsigned NumInputs = Record[0]; -      unsigned NumUserInputs = Record[1]; - -      if (!DisableValidation && -          (ValidateSystemInputs || !HSOpts.ModulesValidateOncePerBuildSession || -           F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp)) { +      // All user input files reside at the index range [0, NumUserInputs), and +      // system input files reside at [NumUserInputs, NumInputs). +      if (!DisableValidation) {          bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;          // If we are reading a module, we will create a verification timestamp, @@ -2254,7 +2302,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,          unsigned N = NumUserInputs;          if (ValidateSystemInputs || -            (HSOpts.ModulesValidateOncePerBuildSession && F.Kind == MK_Module)) +            (HSOpts.ModulesValidateOncePerBuildSession && +             F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp && +             F.Kind == MK_ImplicitModule))            N = NumInputs;          for (unsigned I = 0; I < N; ++I) { @@ -2324,6 +2374,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,        }        F.RelocatablePCH = Record[4]; +      // Relative paths in a relocatable PCH are relative to our sysroot. +      if (F.RelocatablePCH) +        F.BaseDirectory = isysroot.empty() ? "/" : isysroot;        const std::string &CurBranch = getClangFullRepositoryVersion();        StringRef ASTBranch = Blob; @@ -2335,6 +2388,11 @@ ASTReader::ReadControlBlock(ModuleFile &F,        break;      } +    case SIGNATURE: +      assert((!F.Signature || F.Signature == Record[0]) && "signature changed"); +      F.Signature = Record[0]; +      break; +      case IMPORTS: {        // Load each of the imported PCH files.         unsigned Idx = 0, N = Record.size(); @@ -2348,14 +2406,12 @@ ASTReader::ReadControlBlock(ModuleFile &F,              SourceLocation::getFromRawEncoding(Record[Idx++]);          off_t StoredSize = (off_t)Record[Idx++];          time_t StoredModTime = (time_t)Record[Idx++]; -        unsigned Length = Record[Idx++]; -        SmallString<128> ImportedFile(Record.begin() + Idx, -                                      Record.begin() + Idx + Length); -        Idx += Length; +        ASTFileSignature StoredSignature = Record[Idx++]; +        auto ImportedFile = ReadPath(F, Record, Idx);          // Load the AST file.          switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded, -                           StoredSize, StoredModTime, +                           StoredSize, StoredModTime, StoredSignature,                             ClientLoadCapabilities)) {          case Failure: return Failure;            // If we have to ignore the dependency, we'll have to ignore this too. @@ -2372,8 +2428,10 @@ ASTReader::ReadControlBlock(ModuleFile &F,      case LANGUAGE_OPTIONS: {        bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; +      // FIXME: The &F == *ModuleMgr.begin() check is wrong for modules.        if (Listener && &F == *ModuleMgr.begin() && -          ParseLanguageOptions(Record, Complain, *Listener) && +          ParseLanguageOptions(Record, Complain, *Listener, +                               AllowCompatibleConfigurationMismatch) &&            !DisableValidation && !AllowConfigurationMismatch)          return ConfigurationMismatch;        break; @@ -2391,6 +2449,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,      case DIAGNOSTIC_OPTIONS: {        bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0;        if (Listener && &F == *ModuleMgr.begin() && +          !AllowCompatibleConfigurationMismatch &&            ParseDiagnosticOptions(Record, Complain, *Listener) &&            !DisableValidation)          return OutOfDate; @@ -2400,6 +2459,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,      case FILE_SYSTEM_OPTIONS: {        bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;        if (Listener && &F == *ModuleMgr.begin() && +          !AllowCompatibleConfigurationMismatch &&            ParseFileSystemOptions(Record, Complain, *Listener) &&            !DisableValidation && !AllowConfigurationMismatch)          return ConfigurationMismatch; @@ -2409,6 +2469,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,      case HEADER_SEARCH_OPTIONS: {        bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;        if (Listener && &F == *ModuleMgr.begin() && +          !AllowCompatibleConfigurationMismatch &&            ParseHeaderSearchOptions(Record, Complain, *Listener) &&            !DisableValidation && !AllowConfigurationMismatch)          return ConfigurationMismatch; @@ -2418,6 +2479,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,      case PREPROCESSOR_OPTIONS: {        bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;        if (Listener && &F == *ModuleMgr.begin() && +          !AllowCompatibleConfigurationMismatch &&            ParsePreprocessorOptions(Record, Complain, *Listener,                                     SuggestedPredefines) &&            !DisableValidation && !AllowConfigurationMismatch) @@ -2429,7 +2491,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,        F.OriginalSourceFileID = FileID::get(Record[0]);        F.ActualOriginalSourceFileName = Blob;        F.OriginalSourceFileName = F.ActualOriginalSourceFileName; -      MaybeAddSystemRootToFilename(F, F.OriginalSourceFileName); +      ResolveImportedPath(F, F.OriginalSourceFileName);        break;      case ORIGINAL_FILE_ID: @@ -2446,46 +2508,43 @@ ASTReader::ReadControlBlock(ModuleFile &F,          Listener->ReadModuleName(F.ModuleName);        break; -    case MODULE_MAP_FILE: -      F.ModuleMapPath = Blob; - -      // Try to resolve ModuleName in the current header search context and -      // verify that it is found in the same module map file as we saved. If the -      // top-level AST file is a main file, skip this check because there is no -      // usable header search context. +    case MODULE_DIRECTORY: {        assert(!F.ModuleName.empty() && -             "MODULE_NAME should come before MOUDLE_MAP_FILE"); -      if (F.Kind == MK_Module && -          (*ModuleMgr.begin())->Kind != MK_MainFile) { -        Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName); -        if (!M) { -          assert(ImportedBy && "top-level import should be verified"); -          if ((ClientLoadCapabilities & ARR_Missing) == 0) -            Diag(diag::err_imported_module_not_found) -              << F.ModuleName << ImportedBy->FileName; -          return Missing; -        } - -        const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath); -        if (StoredModMap == nullptr || StoredModMap != M->ModuleMap) { -          assert(M->ModuleMap && "found module is missing module map file"); -          assert(M->Name == F.ModuleName && "found module with different name"); -          assert(ImportedBy && "top-level import should be verified"); -          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) -            Diag(diag::err_imported_module_modmap_changed) -              << F.ModuleName << ImportedBy->FileName -              << M->ModuleMap->getName() << F.ModuleMapPath; -          return OutOfDate; +             "MODULE_DIRECTORY found before MODULE_NAME"); +      // If we've already loaded a module map file covering this module, we may +      // have a better path for it (relative to the current build). +      Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName); +      if (M && M->Directory) { +        // If we're implicitly loading a module, the base directory can't +        // change between the build and use. +        if (F.Kind != MK_ExplicitModule) { +          const DirectoryEntry *BuildDir = +              PP.getFileManager().getDirectory(Blob); +          if (!BuildDir || BuildDir != M->Directory) { +            if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) +              Diag(diag::err_imported_module_relocated) +                  << F.ModuleName << Blob << M->Directory->getName(); +            return OutOfDate; +          }          } +        F.BaseDirectory = M->Directory->getName(); +      } else { +        F.BaseDirectory = Blob;        } +      break; +    } -      if (Listener) -        Listener->ReadModuleMapFile(F.ModuleMapPath); +    case MODULE_MAP_FILE: +      if (ASTReadResult Result = +              ReadModuleMapFileBlock(Record, F, ImportedBy, ClientLoadCapabilities)) +        return Result;        break;      case INPUT_FILE_OFFSETS: +      NumInputs = Record[0]; +      NumUserInputs = Record[1];        F.InputFileOffsets = (const uint32_t *)Blob.data(); -      F.InputFilesLoaded.resize(Record[0]); +      F.InputFilesLoaded.resize(NumInputs);        break;      }    } @@ -2628,7 +2687,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {          F.TypeRemap.insertOrReplace(            std::make_pair(LocalBaseTypeIndex,                            F.BaseTypeIndex - LocalBaseTypeIndex)); -         +          TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes);        }        break; @@ -2658,7 +2717,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {          // Introduce the global -> local mapping for declarations within this          // module.          F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID; -         +          DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls);        }        break; @@ -2687,7 +2746,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {          auto *DC = cast<DeclContext>(D);          DC->getPrimaryContext()->setHasExternalVisibleStorage(true);          auto *&LookupTable = F.DeclContextInfos[DC].NameLookupTableData; -        // FIXME: There should never be an existing lookup table.          delete LookupTable;          LookupTable = Table;        } else @@ -2729,8 +2787,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {          F.IdentifierRemap.insertOrReplace(            std::make_pair(LocalBaseIdentifierID,                           F.BaseIdentifierID - LocalBaseIdentifierID)); -         -        IdentifiersLoaded.resize(IdentifiersLoaded.size()  + +        IdentifiersLoaded.resize(IdentifiersLoaded.size()                                   + F.LocalNumIdentifiers);        }        break; @@ -2823,7 +2881,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {            std::make_pair(LocalBaseSelectorID,                           F.BaseSelectorID - LocalBaseSelectorID)); -        SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors);         +        SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors);        }        break;      } @@ -2904,19 +2962,16 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {        }        // Continuous range maps we may be updating in our module. -      ContinuousRangeMap<uint32_t, int, 2>::Builder SLocRemap(F.SLocRemap); -      ContinuousRangeMap<uint32_t, int, 2>::Builder  -        IdentifierRemap(F.IdentifierRemap); -      ContinuousRangeMap<uint32_t, int, 2>::Builder -        MacroRemap(F.MacroRemap); -      ContinuousRangeMap<uint32_t, int, 2>::Builder -        PreprocessedEntityRemap(F.PreprocessedEntityRemap); -      ContinuousRangeMap<uint32_t, int, 2>::Builder  -        SubmoduleRemap(F.SubmoduleRemap); -      ContinuousRangeMap<uint32_t, int, 2>::Builder  -        SelectorRemap(F.SelectorRemap); -      ContinuousRangeMap<uint32_t, int, 2>::Builder DeclRemap(F.DeclRemap); -      ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap); +      typedef ContinuousRangeMap<uint32_t, int, 2>::Builder +          RemapBuilder; +      RemapBuilder SLocRemap(F.SLocRemap); +      RemapBuilder IdentifierRemap(F.IdentifierRemap); +      RemapBuilder MacroRemap(F.MacroRemap); +      RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap); +      RemapBuilder SubmoduleRemap(F.SubmoduleRemap); +      RemapBuilder SelectorRemap(F.SelectorRemap); +      RemapBuilder DeclRemap(F.DeclRemap); +      RemapBuilder TypeRemap(F.TypeRemap);        while(Data < DataEnd) {          using namespace llvm::support; @@ -2946,26 +3001,23 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {          uint32_t TypeIndexOffset =              endian::readNext<uint32_t, little, unaligned>(Data); -        // Source location offset is mapped to OM->SLocEntryBaseOffset. -        SLocRemap.insert(std::make_pair(SLocOffset, -          static_cast<int>(OM->SLocEntryBaseOffset - SLocOffset))); -        IdentifierRemap.insert( -          std::make_pair(IdentifierIDOffset,  -                         OM->BaseIdentifierID - IdentifierIDOffset)); -        MacroRemap.insert(std::make_pair(MacroIDOffset, -                                         OM->BaseMacroID - MacroIDOffset)); -        PreprocessedEntityRemap.insert( -          std::make_pair(PreprocessedEntityIDOffset,  -            OM->BasePreprocessedEntityID - PreprocessedEntityIDOffset)); -        SubmoduleRemap.insert(std::make_pair(SubmoduleIDOffset,  -                                      OM->BaseSubmoduleID - SubmoduleIDOffset)); -        SelectorRemap.insert(std::make_pair(SelectorIDOffset,  -                               OM->BaseSelectorID - SelectorIDOffset)); -        DeclRemap.insert(std::make_pair(DeclIDOffset,  -                                        OM->BaseDeclID - DeclIDOffset)); -         -        TypeRemap.insert(std::make_pair(TypeIndexOffset,  -                                    OM->BaseTypeIndex - TypeIndexOffset)); +        uint32_t None = std::numeric_limits<uint32_t>::max(); + +        auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset, +                             RemapBuilder &Remap) { +          if (Offset != None) +            Remap.insert(std::make_pair(Offset, +                                        static_cast<int>(BaseOffset - Offset))); +        }; +        mapOffset(SLocOffset, OM->SLocEntryBaseOffset, SLocRemap); +        mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap); +        mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap); +        mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID, +                  PreprocessedEntityRemap); +        mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap); +        mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap); +        mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap); +        mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap);          // Global -> local mappings.          F.GlobalToLocalDeclIDs[OM] = DeclIDOffset; @@ -3206,7 +3258,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {        break;      case IMPORTED_MODULES: { -      if (F.Kind != MK_Module) { +      if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule) {          // If we aren't loading a module (which has its own exports), make          // all of the imported modules visible.          // FIXME: Deal with macros-only imports. @@ -3287,10 +3339,110 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {        }        OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);        break; + +    case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES: +      for (unsigned I = 0, N = Record.size(); I != N; ++I) +        UnusedLocalTypedefNameCandidates.push_back( +            getGlobalDeclID(F, Record[I])); +      break;      }    }  } +ASTReader::ASTReadResult +ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, +                                  const ModuleFile *ImportedBy, +                                  unsigned ClientLoadCapabilities) { +  unsigned Idx = 0; +  F.ModuleMapPath = ReadPath(F, Record, Idx); + +  if (F.Kind == MK_ExplicitModule) { +    // For an explicitly-loaded module, we don't care whether the original +    // module map file exists or matches. +    return Success; +  } + +  // Try to resolve ModuleName in the current header search context and +  // verify that it is found in the same module map file as we saved. If the +  // top-level AST file is a main file, skip this check because there is no +  // usable header search context. +  assert(!F.ModuleName.empty() && +         "MODULE_NAME should come before MODULE_MAP_FILE"); +  if (F.Kind == MK_ImplicitModule && +      (*ModuleMgr.begin())->Kind != MK_MainFile) { +    // An implicitly-loaded module file should have its module listed in some +    // module map file that we've already loaded. +    Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName); +    auto &Map = PP.getHeaderSearchInfo().getModuleMap(); +    const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr; +    if (!ModMap) { +      assert(ImportedBy && "top-level import should be verified"); +      if ((ClientLoadCapabilities & ARR_Missing) == 0) +        Diag(diag::err_imported_module_not_found) << F.ModuleName << F.FileName +                                                  << ImportedBy->FileName +                                                  << F.ModuleMapPath; +      return Missing; +    } + +    assert(M->Name == F.ModuleName && "found module with different name"); + +    // Check the primary module map file. +    const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath); +    if (StoredModMap == nullptr || StoredModMap != ModMap) { +      assert(ModMap && "found module is missing module map file"); +      assert(ImportedBy && "top-level import should be verified"); +      if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) +        Diag(diag::err_imported_module_modmap_changed) +          << F.ModuleName << ImportedBy->FileName +          << ModMap->getName() << F.ModuleMapPath; +      return OutOfDate; +    } + +    llvm::SmallPtrSet<const FileEntry *, 1> AdditionalStoredMaps; +    for (unsigned I = 0, N = Record[Idx++]; I < N; ++I) { +      // FIXME: we should use input files rather than storing names. +      std::string Filename = ReadPath(F, Record, Idx); +      const FileEntry *F = +          FileMgr.getFile(Filename, false, false); +      if (F == nullptr) { +        if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) +          Error("could not find file '" + Filename +"' referenced by AST file"); +        return OutOfDate; +      } +      AdditionalStoredMaps.insert(F); +    } + +    // Check any additional module map files (e.g. module.private.modulemap) +    // that are not in the pcm. +    if (auto *AdditionalModuleMaps = Map.getAdditionalModuleMapFiles(M)) { +      for (const FileEntry *ModMap : *AdditionalModuleMaps) { +        // Remove files that match +        // Note: SmallPtrSet::erase is really remove +        if (!AdditionalStoredMaps.erase(ModMap)) { +          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) +            Diag(diag::err_module_different_modmap) +              << F.ModuleName << /*new*/0 << ModMap->getName(); +          return OutOfDate; +        } +      } +    } + +    // Check any additional module map files that are in the pcm, but not +    // found in header search. Cases that match are already removed. +    for (const FileEntry *ModMap : AdditionalStoredMaps) { +      if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) +        Diag(diag::err_module_different_modmap) +          << F.ModuleName << /*not new*/1 << ModMap->getName(); +      return OutOfDate; +    } +  } + +  if (Listener) +    Listener->ReadModuleMapFile(F.ModuleMapPath); +  return Success; +} + +  /// \brief Move the given method to the back of the global list of methods.  static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {    // Find the entry for this selector in the method pool. @@ -3305,7 +3457,7 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {    bool Found = false;    for (ObjCMethodList *List = &Start; List; List = List->getNext()) {      if (!Found) { -      if (List->Method == Method) { +      if (List->getMethod() == Method) {          Found = true;        } else {          // Keep searching. @@ -3314,9 +3466,9 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {      }      if (List->getNext()) -      List->Method = List->getNext()->Method; +      List->setMethod(List->getNext()->getMethod());      else -      List->Method = Method; +      List->setMethod(Method);    }  } @@ -3336,8 +3488,13 @@ void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner,    assert((FromFinalization || Owner->NameVisibility >= Module::MacrosVisible) &&           "nothing to make visible?"); -  for (const auto &Macro : Names.HiddenMacros) -    installImportedMacro(Macro.first, Macro.second, Owner, FromFinalization); +  for (const auto &Macro : Names.HiddenMacros) { +    if (FromFinalization) +      PP.appendMacroDirective(Macro.first, +                              Macro.second->import(PP, SourceLocation())); +    else +      installImportedMacro(Macro.first, Macro.second, Owner); +  }  }  void ASTReader::makeModuleVisible(Module *Mod, @@ -3385,7 +3542,7 @@ void ASTReader::makeModuleVisible(Module *Mod,      for (SmallVectorImpl<Module *>::iterator             I = Exports.begin(), E = Exports.end(); I != E; ++I) {        Module *Exported = *I; -      if (Visited.insert(Exported)) +      if (Visited.insert(Exported).second)          Stack.push_back(Exported);      } @@ -3435,10 +3592,9 @@ bool ASTReader::isGlobalIndexUnavailable() const {  static void updateModuleTimestamp(ModuleFile &MF) {    // Overwrite the timestamp file contents so that file's mtime changes.    std::string TimestampFilename = MF.getTimestampFilename(); -  std::string ErrorInfo; -  llvm::raw_fd_ostream OS(TimestampFilename.c_str(), ErrorInfo, -                          llvm::sys::fs::F_Text); -  if (!ErrorInfo.empty()) +  std::error_code EC; +  llvm::raw_fd_ostream OS(TimestampFilename, EC, llvm::sys::fs::F_Text); +  if (EC)      return;    OS << "Timestamp file\n";  } @@ -3460,7 +3616,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,    SmallVector<ImportedModule, 4> Loaded;    switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,                                                  /*ImportedBy=*/nullptr, Loaded, -                                                0, 0, +                                                0, 0, 0,                                                  ClientLoadCapabilities)) {    case Failure:    case Missing: @@ -3618,7 +3774,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,      // in the filesystem).      for (unsigned I = 0, N = Loaded.size(); I != N; ++I) {        ImportedModule &M = Loaded[I]; -      if (M.Mod->Kind == MK_Module) { +      if (M.Mod->Kind == MK_ImplicitModule) {          updateModuleTimestamp(*M.Mod);        }      } @@ -3627,6 +3783,8 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,    return Success;  } +static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile); +  ASTReader::ASTReadResult  ASTReader::ReadASTCore(StringRef FileName,                         ModuleKind Type, @@ -3634,12 +3792,14 @@ ASTReader::ReadASTCore(StringRef FileName,                         ModuleFile *ImportedBy,                         SmallVectorImpl<ImportedModule> &Loaded,                         off_t ExpectedSize, time_t ExpectedModTime, +                       ASTFileSignature ExpectedSignature,                         unsigned ClientLoadCapabilities) {    ModuleFile *M;    std::string ErrorStr;    ModuleManager::AddModuleResult AddResult      = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy,                            getGeneration(), ExpectedSize, ExpectedModTime, +                          ExpectedSignature, readASTFileSignature,                            M, ErrorStr);    switch (AddResult) { @@ -3651,7 +3811,7 @@ ASTReader::ReadASTCore(StringRef FileName,      break;    case ModuleManager::Missing: -    // The module file was missing; if the client handle handle, that, return +    // The module file was missing; if the client can handle that, return      // it.      if (ClientLoadCapabilities & ARR_Missing)        return Missing; @@ -3690,7 +3850,7 @@ ASTReader::ReadASTCore(StringRef FileName,    ModuleFile &F = *M;    BitstreamCursor &Stream = F.Stream; -  Stream.init(F.StreamFile); +  Stream.init(&F.StreamFile);    F.SizeInBits = F.Buffer->getBufferSize() * 8;    // Sniff for the signature. @@ -3937,6 +4097,34 @@ static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) {    }  } +static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile){ +  BitstreamCursor Stream(StreamFile); +  if (Stream.Read(8) != 'C' || +      Stream.Read(8) != 'P' || +      Stream.Read(8) != 'C' || +      Stream.Read(8) != 'H') { +    return 0; +  } + +  // Scan for the CONTROL_BLOCK_ID block. +  if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) +    return 0; + +  // Scan for SIGNATURE inside the control block. +  ASTReader::RecordData Record; +  while (1) { +    llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); +    if (Entry.Kind == llvm::BitstreamEntry::EndBlock || +        Entry.Kind != llvm::BitstreamEntry::Record) +      return 0; + +    Record.clear(); +    StringRef Blob; +    if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob)) +      return Record[0]; +  } +} +  /// \brief Retrieve the name of the original source file name  /// directly from the AST file, without actually loading the AST  /// file. @@ -3944,20 +4132,18 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,                                               FileManager &FileMgr,                                               DiagnosticsEngine &Diags) {    // Open the AST file. -  std::string ErrStr; -  std::unique_ptr<llvm::MemoryBuffer> Buffer; -  Buffer.reset(FileMgr.getBufferForFile(ASTFileName, &ErrStr)); +  auto Buffer = FileMgr.getBufferForFile(ASTFileName);    if (!Buffer) { -    Diags.Report(diag::err_fe_unable_to_read_pch_file) << ASTFileName << ErrStr; +    Diags.Report(diag::err_fe_unable_to_read_pch_file) +        << ASTFileName << Buffer.getError().message();      return std::string();    }    // Initialize the stream    llvm::BitstreamReader StreamFile; -  BitstreamCursor Stream; -  StreamFile.init((const unsigned char *)Buffer->getBufferStart(), -                  (const unsigned char *)Buffer->getBufferEnd()); -  Stream.init(StreamFile); +  StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(), +                  (const unsigned char *)(*Buffer)->getBufferEnd()); +  BitstreamCursor Stream(StreamFile);    // Sniff for the signature.    if (Stream.Read(8) != 'C' || @@ -4012,9 +4198,10 @@ namespace {      {      } -    bool ReadLanguageOptions(const LangOptions &LangOpts, -                             bool Complain) override { -      return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr); +    bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, +                             bool AllowCompatibleDifferences) override { +      return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr, +                                  AllowCompatibleDifferences);      }      bool ReadTargetOptions(const TargetOptions &TargetOpts,                             bool Complain) override { @@ -4033,19 +4220,16 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,                                          FileManager &FileMgr,                                          ASTReaderListener &Listener) {    // Open the AST file. -  std::string ErrStr; -  std::unique_ptr<llvm::MemoryBuffer> Buffer; -  Buffer.reset(FileMgr.getBufferForFile(Filename, &ErrStr)); +  auto Buffer = FileMgr.getBufferForFile(Filename);    if (!Buffer) {      return true;    }    // Initialize the stream    llvm::BitstreamReader StreamFile; -  BitstreamCursor Stream; -  StreamFile.init((const unsigned char *)Buffer->getBufferStart(), -                  (const unsigned char *)Buffer->getBufferEnd()); -  Stream.init(StreamFile); +  StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(), +                  (const unsigned char *)(*Buffer)->getBufferEnd()); +  BitstreamCursor Stream(StreamFile);    // Sniff for the signature.    if (Stream.Read(8) != 'C' || @@ -4061,6 +4245,7 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,    bool NeedsInputFiles = Listener.needsInputFileVisitation();    bool NeedsSystemInputFiles = Listener.needsSystemInputFileVisitation(); +  bool NeedsImports = Listener.needsImportVisitation();    BitstreamCursor InputFilesCursor;    if (NeedsInputFiles) {      InputFilesCursor = Stream; @@ -4083,6 +4268,7 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,    // Scan for ORIGINAL_FILE inside the control block.    RecordData Record; +  std::string ModuleDir;    while (1) {      llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();      if (Entry.Kind == llvm::BitstreamEntry::EndBlock) @@ -4107,11 +4293,19 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,      case MODULE_NAME:        Listener.ReadModuleName(Blob);        break; -    case MODULE_MAP_FILE: -      Listener.ReadModuleMapFile(Blob); +    case MODULE_DIRECTORY: +      ModuleDir = Blob;        break; +    case MODULE_MAP_FILE: { +      unsigned Idx = 0; +      auto Path = ReadString(Record, Idx); +      ResolveImportedPath(Path, ModuleDir); +      Listener.ReadModuleMapFile(Path); +      break; +    }      case LANGUAGE_OPTIONS: -      if (ParseLanguageOptions(Record, false, Listener)) +      if (ParseLanguageOptions(Record, false, Listener, +                               /*AllowCompatibleConfigurationMismatch*/false))          return true;        break; @@ -4168,7 +4362,10 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,          switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {          case INPUT_FILE:            bool Overridden = static_cast<bool>(Record[3]); -          shouldContinue = Listener.visitInputFile(Blob, isSystemFile, Overridden); +          std::string Filename = Blob; +          ResolveImportedPath(Filename, ModuleDir); +          shouldContinue = +              Listener.visitInputFile(Filename, isSystemFile, Overridden);            break;          }          if (!shouldContinue) @@ -4177,6 +4374,21 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,        break;      } +    case IMPORTS: { +      if (!NeedsImports) +        break; + +      unsigned Idx = 0, N = Record.size(); +      while (Idx < N) { +        // Read information about the AST file. +        Idx += 5; // ImportLoc, Size, ModTime, Signature +        std::string Filename = ReadString(Record, Idx); +        ResolveImportedPath(Filename, ModuleDir); +        Listener.visitImport(Filename); +      } +      break; +    } +      default:        // No other validation to perform.        break; @@ -4224,21 +4436,30 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {      // Read a record.      StringRef Blob;      Record.clear(); -    switch (F.Stream.readRecord(Entry.ID, Record, &Blob)) { +    auto Kind = F.Stream.readRecord(Entry.ID, Record, &Blob); + +    if ((Kind == SUBMODULE_METADATA) != First) { +      Error("submodule metadata record should be at beginning of block"); +      return Failure; +    } +    First = false; + +    // Submodule information is only valid if we have a current module. +    // FIXME: Should we error on these cases? +    if (!CurrentModule && Kind != SUBMODULE_METADATA && +        Kind != SUBMODULE_DEFINITION) +      continue; + +    switch (Kind) {      default:  // Default behavior: ignore.        break; -       -    case SUBMODULE_DEFINITION: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } +    case SUBMODULE_DEFINITION: {        if (Record.size() < 8) {          Error("malformed module definition");          return Failure;        } -       +        StringRef Name = Blob;        unsigned Idx = 0;        SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[Idx++]); @@ -4253,20 +4474,17 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {        bool ConfigMacrosExhaustive = Record[Idx++];        Module *ParentModule = nullptr; -      const FileEntry *ModuleMap = nullptr; -      if (Parent) { +      if (Parent)          ParentModule = getSubmodule(Parent); -        ModuleMap = ParentModule->ModuleMap; -      } - -      if (!F.ModuleMapPath.empty()) -        ModuleMap = FileMgr.getFile(F.ModuleMapPath);        // Retrieve this (sub)module from the module map, creating it if        // necessary. -      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, ModuleMap, -                                                IsFramework,  +      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, IsFramework,                                                  IsExplicit).first; + +      // FIXME: set the definition loc for CurrentModule, or call +      // ModMap.setInferredModuleAllowedBy() +        SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;        if (GlobalIndex >= SubmodulesLoaded.size() ||            SubmodulesLoaded[GlobalIndex]) { @@ -4311,14 +4529,6 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {      }      case SUBMODULE_UMBRELLA_HEADER: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -              if (const FileEntry *Umbrella = PP.getFileManager().getFile(Blob)) {          if (!CurrentModule->getUmbrellaHeader())            ModMap.setUmbrellaHeader(CurrentModule, Umbrella); @@ -4331,73 +4541,26 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {        break;      } -    case SUBMODULE_HEADER: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -       -      // We lazily associate headers with their modules via the HeaderInfoTable. -      // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead -      // of complete filenames or remove it entirely. -      break;       -    } - -    case SUBMODULE_EXCLUDED_HEADER: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -       -      // We lazily associate headers with their modules via the HeaderInfoTable. +    case SUBMODULE_HEADER: +    case SUBMODULE_EXCLUDED_HEADER: +    case SUBMODULE_PRIVATE_HEADER: +      // We lazily associate headers with their modules via the HeaderInfo table.        // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead        // of complete filenames or remove it entirely. -      break;       -    } - -    case SUBMODULE_PRIVATE_HEADER: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } +      break; -      if (!CurrentModule) -        break; -       -      // We lazily associate headers with their modules via the HeaderInfoTable. -      // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead -      // of complete filenames or remove it entirely. -      break;       -    } +    case SUBMODULE_TEXTUAL_HEADER: +    case SUBMODULE_PRIVATE_TEXTUAL_HEADER: +      // FIXME: Textual headers are not marked in the HeaderInfo table. Load +      // them here. +      break;      case SUBMODULE_TOPHEADER: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -        CurrentModule->addTopHeaderFilename(Blob);        break;      }      case SUBMODULE_UMBRELLA_DIR: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } -       -      if (!CurrentModule) -        break; -              if (const DirectoryEntry *Umbrella                                    = PP.getFileManager().getDirectory(Blob)) {          if (!CurrentModule->getUmbrellaDir()) @@ -4412,12 +4575,6 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {      }      case SUBMODULE_METADATA: { -      if (!First) { -        Error("submodule metadata record not at beginning of block"); -        return Failure; -      } -      First = false; -              F.BaseSubmoduleID = getTotalNumSubmodules();        F.LocalNumSubmodules = Record[0];        unsigned LocalBaseSubmoduleID = Record[1]; @@ -4431,21 +4588,13 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {          F.SubmoduleRemap.insertOrReplace(            std::make_pair(LocalBaseSubmoduleID,                           F.BaseSubmoduleID - LocalBaseSubmoduleID)); -         +          SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules); -      }       +      }        break;      }      case SUBMODULE_IMPORTS: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } -       -      if (!CurrentModule) -        break; -              for (unsigned Idx = 0; Idx != Record.size(); ++Idx) {          UnresolvedModuleRef Unresolved;          Unresolved.File = &F; @@ -4459,14 +4608,6 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {      }      case SUBMODULE_EXPORTS: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } -       -      if (!CurrentModule) -        break; -              for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {          UnresolvedModuleRef Unresolved;          Unresolved.File = &F; @@ -4483,53 +4624,21 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {        break;      }      case SUBMODULE_REQUIRES: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -        CurrentModule->addRequirement(Blob, Record[0], Context.getLangOpts(),                                      Context.getTargetInfo());        break;      }      case SUBMODULE_LINK_LIBRARY: -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -        CurrentModule->LinkLibraries.push_back(                                           Module::LinkLibrary(Blob, Record[0]));        break;      case SUBMODULE_CONFIG_MACRO: -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -        CurrentModule->ConfigMacros.push_back(Blob.str());        break;      case SUBMODULE_CONFLICT: { -      if (First) { -        Error("missing submodule metadata record at beginning of block"); -        return Failure; -      } - -      if (!CurrentModule) -        break; -        UnresolvedModuleRef Unresolved;        Unresolved.File = &F;        Unresolved.Mod = CurrentModule; @@ -4553,7 +4662,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {  /// \returns true if the listener deems the file unacceptable, false otherwise.  bool ASTReader::ParseLanguageOptions(const RecordData &Record,                                       bool Complain, -                                     ASTReaderListener &Listener) { +                                     ASTReaderListener &Listener, +                                     bool AllowCompatibleDifferences) {    LangOptions LangOpts;    unsigned Idx = 0;  #define LANGOPT(Name, Bits, Default, Description) \ @@ -4561,7 +4671,8 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record,  #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \    LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++]));  #include "clang/Basic/LangOptions.def" -#define SANITIZER(NAME, ID) LangOpts.Sanitize.ID = Record[Idx++]; +#define SANITIZER(NAME, ID)                                                    \ +  LangOpts.Sanitize.set(SanitizerKind::ID, Record[Idx++]);  #include "clang/Basic/Sanitizers.def"    ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++]; @@ -4581,7 +4692,8 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record,    }    LangOpts.CommentOpts.ParseAllComments = Record[Idx++]; -  return Listener.ReadLanguageOptions(LangOpts, Complain); +  return Listener.ReadLanguageOptions(LangOpts, Complain, +                                      AllowCompatibleDifferences);  }  bool ASTReader::ParseTargetOptions(const RecordData &Record, @@ -5235,17 +5347,19 @@ QualType ASTReader::readTypeRecord(unsigned Index) {                                          /*produces*/ Record[5]);      unsigned Idx = 6; -    unsigned NumParams = Record[Idx++]; -    SmallVector<QualType, 16> ParamTypes; -    for (unsigned I = 0; I != NumParams; ++I) -      ParamTypes.push_back(readType(*Loc.F, Record, Idx));      EPI.Variadic = Record[Idx++];      EPI.HasTrailingReturn = Record[Idx++];      EPI.TypeQuals = Record[Idx++];      EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);      SmallVector<QualType, 8> ExceptionStorage; -    readExceptionSpec(*Loc.F, ExceptionStorage, EPI, Record, Idx); +    readExceptionSpec(*Loc.F, ExceptionStorage, EPI.ExceptionSpec, Record, Idx); + +    unsigned NumParams = Record[Idx++]; +    SmallVector<QualType, 16> ParamTypes; +    for (unsigned I = 0; I != NumParams; ++I) +      ParamTypes.push_back(readType(*Loc.F, Record, Idx)); +      return Context.getFunctionType(ResultType, ParamTypes, EPI);    } @@ -5414,13 +5528,18 @@ QualType ASTReader::readTypeRecord(unsigned Index) {      QualType TST = readType(*Loc.F, Record, Idx); // probably derivable      // FIXME: ASTContext::getInjectedClassNameType is not currently suitable      // for AST reading, too much interdependencies. -    const Type *T; -    if (const Type *Existing = D->getTypeForDecl()) -      T = Existing; -    else if (auto *Prev = D->getPreviousDecl()) -      T = Prev->getTypeForDecl(); -    else +    const Type *T = nullptr; +    for (auto *DI = D; DI; DI = DI->getPreviousDecl()) { +      if (const Type *Existing = DI->getTypeForDecl()) { +        T = Existing; +        break; +      } +    } +    if (!T) {        T = new (Context, TypeAlignment) InjectedClassNameType(D, TST); +      for (auto *DI = D; DI; DI = DI->getPreviousDecl()) +        DI->setTypeForDecl(T); +    }      return QualType(T, 0);    } @@ -5508,24 +5627,22 @@ QualType ASTReader::readTypeRecord(unsigned Index) {  void ASTReader::readExceptionSpec(ModuleFile &ModuleFile,                                    SmallVectorImpl<QualType> &Exceptions, -                                  FunctionProtoType::ExtProtoInfo &EPI, +                                  FunctionProtoType::ExceptionSpecInfo &ESI,                                    const RecordData &Record, unsigned &Idx) {    ExceptionSpecificationType EST =        static_cast<ExceptionSpecificationType>(Record[Idx++]); -  EPI.ExceptionSpecType = EST; +  ESI.Type = EST;    if (EST == EST_Dynamic) { -    EPI.NumExceptions = Record[Idx++]; -    for (unsigned I = 0; I != EPI.NumExceptions; ++I) +    for (unsigned I = 0, N = Record[Idx++]; I != N; ++I)        Exceptions.push_back(readType(ModuleFile, Record, Idx)); -    EPI.Exceptions = Exceptions.data(); +    ESI.Exceptions = Exceptions;    } else if (EST == EST_ComputedNoexcept) { -    EPI.NoexceptExpr = ReadExpr(ModuleFile); +    ESI.NoexceptExpr = ReadExpr(ModuleFile);    } else if (EST == EST_Uninstantiated) { -    EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx); -    EPI.ExceptionSpecTemplate = -        ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx); +    ESI.SourceDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx); +    ESI.SourceTemplate = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);    } else if (EST == EST_Unevaluated) { -    EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx); +    ESI.SourceDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);    }  } @@ -5976,18 +6093,10 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {    const DeclContext *DC = D->getDeclContext()->getRedeclContext(); -  // Recursively ensure that the decl context itself is complete -  // (in particular, this matters if the decl context is a namespace). -  // -  // FIXME: This should be performed by lookup instead of here. -  cast<Decl>(DC)->getMostRecentDecl(); -    // If this is a named declaration, complete it by looking it up    // within its context.    // -  // FIXME: We don't currently handle the cases where we can't do this; -  // merging a class definition that contains unnamed entities should merge -  // those entities. Likewise, merging a function definition should merge +  // FIXME: Merging a function definition should merge    // all mergeable entities within it.    if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||        isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) { @@ -6000,6 +6109,9 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {            updateOutOfDateIdentifier(*II);        } else          DC->lookup(Name); +    } else if (needsAnonymousDeclarationNumber(cast<NamedDecl>(D))) { +      // FIXME: It'd be nice to do something a bit more targeted here. +      D->getDeclContext()->decls_begin();      }    }  } @@ -6345,13 +6457,13 @@ namespace {    /// declaration context.    class DeclContextNameLookupVisitor {      ASTReader &Reader; -    SmallVectorImpl<const DeclContext *> &Contexts; +    ArrayRef<const DeclContext *> Contexts;      DeclarationName Name;      SmallVectorImpl<NamedDecl *> &Decls;    public: -    DeclContextNameLookupVisitor(ASTReader &Reader,  -                                 SmallVectorImpl<const DeclContext *> &Contexts,  +    DeclContextNameLookupVisitor(ASTReader &Reader, +                                 ArrayRef<const DeclContext *> Contexts,                                   DeclarationName Name,                                   SmallVectorImpl<NamedDecl *> &Decls)        : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls) { } @@ -6364,9 +6476,9 @@ namespace {        // this context in this module.        ModuleFile::DeclContextInfosMap::iterator Info;        bool FoundInfo = false; -      for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) { -        Info = M.DeclContextInfos.find(This->Contexts[I]); -        if (Info != M.DeclContextInfos.end() &&  +      for (auto *DC : This->Contexts) { +        Info = M.DeclContextInfos.find(DC); +        if (Info != M.DeclContextInfos.end() &&              Info->second.NameLookupTableData) {            FoundInfo = true;            break; @@ -6375,7 +6487,7 @@ namespace {        if (!FoundInfo)          return false; -       +        // Look for this name within this module.        ASTDeclContextNameLookupTable *LookupTable =          Info->second.NameLookupTableData; @@ -6396,9 +6508,11 @@ namespace {            // currently read before reading its name. The lookup is triggered by            // building that decl (likely indirectly), and so it is later in the            // sense of "already existing" and can be ignored here. +          // FIXME: This should not happen; deserializing declarations should +          // not perform lookups since that can lead to deserialization cycles.            continue;          } -       +          // Record this declaration.          FoundAnything = true;          This->Decls.push_back(ND); @@ -6438,15 +6552,17 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,    if (!Name)      return false; +  Deserializing LookupResults(this); +    SmallVector<NamedDecl *, 64> Decls; -   +    // Compute the declaration contexts we need to look into. Multiple such    // declaration contexts occur when two declaration contexts from disjoint    // modules get merged, e.g., when two namespaces with the same name are     // independently defined in separate modules.    SmallVector<const DeclContext *, 2> Contexts;    Contexts.push_back(DC); -   +    if (DC->isNamespace()) {      auto Merged = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));      if (Merged != MergedDecls.end()) { @@ -6454,24 +6570,45 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,          Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));      }    } -  if (isa<CXXRecordDecl>(DC)) { -    auto Merged = MergedLookups.find(DC); -    if (Merged != MergedLookups.end()) -      Contexts.insert(Contexts.end(), Merged->second.begin(), -                      Merged->second.end()); -  } -  DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls); +  auto LookUpInContexts = [&](ArrayRef<const DeclContext*> Contexts) { +    DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls); -  // If we can definitively determine which module file to look into, -  // only look there. Otherwise, look in all module files. -  ModuleFile *Definitive; -  if (Contexts.size() == 1 && -      (Definitive = getDefinitiveModuleFileFor(DC, *this))) { -    DeclContextNameLookupVisitor::visit(*Definitive, &Visitor); -  } else { -    ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor); +    // If we can definitively determine which module file to look into, +    // only look there. Otherwise, look in all module files. +    ModuleFile *Definitive; +    if (Contexts.size() == 1 && +        (Definitive = getDefinitiveModuleFileFor(Contexts[0], *this))) { +      DeclContextNameLookupVisitor::visit(*Definitive, &Visitor); +    } else { +      ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor); +    } +  }; + +  LookUpInContexts(Contexts); + +  // If this might be an implicit special member function, then also search +  // all merged definitions of the surrounding class. We need to search them +  // individually, because finding an entity in one of them doesn't imply that +  // we can't find a different entity in another one. +  if (isa<CXXRecordDecl>(DC)) { +    auto Kind = Name.getNameKind(); +    if (Kind == DeclarationName::CXXConstructorName || +        Kind == DeclarationName::CXXDestructorName || +        (Kind == DeclarationName::CXXOperatorName && +         Name.getCXXOverloadedOperator() == OO_Equal)) { +      auto Merged = MergedLookups.find(DC); +      if (Merged != MergedLookups.end()) { +        for (unsigned I = 0; I != Merged->second.size(); ++I) { +          LookUpInContexts(Merged->second[I]); +          // We might have just added some more merged lookups. If so, our +          // iterator is now invalid, so grab a fresh one before continuing. +          Merged = MergedLookups.find(DC); +        } +      } +    }    } +    ++NumVisibleDeclContextsRead;    SetExternalVisibleDeclsForName(DC, Name, Decls);    return !Decls.empty(); @@ -6786,11 +6923,11 @@ void ASTReader::InitializeSema(Sema &S) {    // Makes sure any declarations that were deserialized "too early"    // still get added to the identifier's declaration chains. -  for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) { -    pushExternalDeclIntoScope(PreloadedDecls[I], -                              PreloadedDecls[I]->getDeclName()); +  for (uint64_t ID : PreloadedDeclIDs) { +    NamedDecl *D = cast<NamedDecl>(GetDecl(ID)); +    pushExternalDeclIntoScope(D, D->getDeclName());    } -  PreloadedDecls.clear(); +  PreloadedDeclIDs.clear();    // FIXME: What happens if these are changed by a module import?    if (!FPPragmaOptions.empty()) { @@ -6924,15 +7061,18 @@ namespace clang { namespace serialization {      unsigned PriorGeneration;      unsigned InstanceBits;      unsigned FactoryBits; +    bool InstanceHasMoreThanOneDecl; +    bool FactoryHasMoreThanOneDecl;      SmallVector<ObjCMethodDecl *, 4> InstanceMethods;      SmallVector<ObjCMethodDecl *, 4> FactoryMethods;    public: -    ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel,  +    ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel,                            unsigned PriorGeneration) -      : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration), -        InstanceBits(0), FactoryBits(0) { } -     +        : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration), +          InstanceBits(0), FactoryBits(0), InstanceHasMoreThanOneDecl(false), +          FactoryHasMoreThanOneDecl(false) {} +      static bool visit(ModuleFile &M, void *UserData) {        ReadMethodPoolVisitor *This          = static_cast<ReadMethodPoolVisitor *>(UserData); @@ -6966,6 +7106,8 @@ namespace clang { namespace serialization {        This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());        This->InstanceBits = Data.InstanceBits;        This->FactoryBits = Data.FactoryBits; +      This->InstanceHasMoreThanOneDecl = Data.InstanceHasMoreThanOneDecl; +      This->FactoryHasMoreThanOneDecl = Data.FactoryHasMoreThanOneDecl;        return true;      } @@ -6981,6 +7123,10 @@ namespace clang { namespace serialization {      unsigned getInstanceBits() const { return InstanceBits; }      unsigned getFactoryBits() const { return FactoryBits; } +    bool instanceHasMoreThanOneDecl() const { +      return InstanceHasMoreThanOneDecl; +    } +    bool factoryHasMoreThanOneDecl() const { return FactoryHasMoreThanOneDecl; }    };  } } // end namespace clang::serialization @@ -7015,11 +7161,17 @@ void ASTReader::ReadMethodPool(Selector Sel) {    Sema &S = *getSema();    Sema::GlobalMethodPool::iterator Pos      = S.MethodPool.insert(std::make_pair(Sel, Sema::GlobalMethods())).first; -   -  addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first); -  addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second); +    Pos->second.first.setBits(Visitor.getInstanceBits()); +  Pos->second.first.setHasMoreThanOneDecl(Visitor.instanceHasMoreThanOneDecl());    Pos->second.second.setBits(Visitor.getFactoryBits()); +  Pos->second.second.setHasMoreThanOneDecl(Visitor.factoryHasMoreThanOneDecl()); + +  // Add methods to the global pool *after* setting hasMoreThanOneDecl, since +  // when building a module we keep every method individually and may need to +  // update hasMoreThanOneDecl as we add the methods. +  addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first); +  addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);  }  void ASTReader::ReadKnownNamespaces( @@ -7095,6 +7247,18 @@ void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {    DynamicClasses.clear();  } +void ASTReader::ReadUnusedLocalTypedefNameCandidates( +    llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) { +  for (unsigned I = 0, N = UnusedLocalTypedefNameCandidates.size(); I != N; +       ++I) { +    TypedefNameDecl *D = dyn_cast_or_null<TypedefNameDecl>( +        GetDecl(UnusedLocalTypedefNameCandidates[I])); +    if (D) +      Decls.insert(D); +  } +  UnusedLocalTypedefNameCandidates.clear(); +} +  void   ASTReader::ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl *> &Decls) {    for (unsigned I = 0, N = LocallyScopedExternCDecls.size(); I != N; ++I) { @@ -7230,24 +7394,26 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,    }    for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) { -    NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I])); -    if (SemaObj) { -      // If we're simply supposed to record the declarations, do so now. -      if (Decls) { -        Decls->push_back(D); -        continue; -      } - -      // Introduce this declaration into the translation-unit scope -      // and add it to the declaration chain for this identifier, so -      // that (unqualified) name lookup will find it. -      pushExternalDeclIntoScope(D, II); -    } else { +    if (!SemaObj) {        // Queue this declaration so that it will be added to the        // translation unit scope and identifier's declaration chain        // once a Sema object is known. -      PreloadedDecls.push_back(D); +      PreloadedDeclIDs.push_back(DeclIDs[I]); +      continue;      } + +    NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I])); + +    // If we're simply supposed to record the declarations, do so now. +    if (Decls) { +      Decls->push_back(D); +      continue; +    } + +    // Introduce this declaration into the translation-unit scope +    // and add it to the declaration chain for this identifier, so +    // that (unqualified) name lookup will find it. +    pushExternalDeclIntoScope(D, II);    }  } @@ -7584,8 +7750,7 @@ ASTReader::ReadTemplateArgument(ModuleFile &F,      return TemplateArgument(readType(F, Record, Idx));    case TemplateArgument::Declaration: {      ValueDecl *D = ReadDeclAs<ValueDecl>(F, Record, Idx); -    bool ForReferenceParam = Record[Idx++]; -    return TemplateArgument(D, ForReferenceParam); +    return TemplateArgument(D, readType(F, Record, Idx));    }    case TemplateArgument::NullPtr:      return TemplateArgument(readType(F, Record, Idx), /*isNullPtr*/true); @@ -7806,6 +7971,12 @@ ASTReader::ReadNestedNameSpecifier(ModuleFile &F,        // No associated value, and there can't be a prefix.        break;      } + +    case NestedNameSpecifier::Super: { +      CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx); +      NNS = NestedNameSpecifier::SuperSpecifier(Context, RD); +      break; +    }      }      Prev = NNS;    } @@ -7862,9 +8033,16 @@ ASTReader::ReadNestedNameSpecifierLoc(ModuleFile &F, const RecordData &Record,        Builder.MakeGlobal(Context, ColonColonLoc);        break;      } + +    case NestedNameSpecifier::Super: { +      CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx); +      SourceRange Range = ReadSourceRange(F, Record, Idx); +      Builder.MakeSuper(Context, RD, Range.getBegin(), Range.getEnd()); +      break; +    }      }    } -   +    return Builder.getWithLocInContext(Context);  } @@ -7906,6 +8084,13 @@ std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) {    return Result;  } +std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record, +                                unsigned &Idx) { +  std::string Filename = ReadString(Record, Idx); +  ResolveImportedPath(F, Filename); +  return Filename; +} +  VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record,                                            unsigned &Idx) {    unsigned Major = Record[Idx++]; @@ -8008,6 +8193,14 @@ void ASTReader::ReadComments() {    }  } +void ASTReader::getInputFiles(ModuleFile &F, +                             SmallVectorImpl<serialization::InputFile> &Files) { +  for (unsigned I = 0, E = F.InputFilesLoaded.size(); I != E; ++I) { +    unsigned ID = I+1; +    Files.push_back(getInputFile(F, ID)); +  } +} +  std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {    // If we know the owning module, use it.    if (Module *M = D->getOwningModule()) @@ -8025,7 +8218,7 @@ void ASTReader::finishPendingActions() {    while (!PendingIdentifierInfos.empty() ||           !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||           !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() || -         !PendingUpdateRecords.empty() || !PendingOdrMergeChecks.empty()) { +         !PendingUpdateRecords.empty()) {      // If any identifiers with corresponding top-level declarations have      // been loaded, load those declarations now.      typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> > @@ -8073,14 +8266,16 @@ void ASTReader::finishPendingActions() {        for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;             ++IDIdx) {          const PendingMacroInfo &Info = GlobalIDs[IDIdx]; -        if (Info.M->Kind != MK_Module) +        if (Info.M->Kind != MK_ImplicitModule && +            Info.M->Kind != MK_ExplicitModule)            resolvePendingMacro(II, Info);        }        // Handle module imports.        for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;             ++IDIdx) {          const PendingMacroInfo &Info = GlobalIDs[IDIdx]; -        if (Info.M->Kind == MK_Module) +        if (Info.M->Kind == MK_ImplicitModule || +            Info.M->Kind == MK_ExplicitModule)            resolvePendingMacro(II, Info);        }      } @@ -8097,110 +8292,36 @@ void ASTReader::finishPendingActions() {      }      // Perform any pending declaration updates. -    // -    // Don't do this if we have known-incomplete redecl chains: it relies on -    // being able to walk redeclaration chains. -    while (PendingDeclChains.empty() && !PendingUpdateRecords.empty()) { +    while (!PendingUpdateRecords.empty()) {        auto Update = PendingUpdateRecords.pop_back_val();        ReadingKindTracker ReadingKind(Read_Decl, *this);        loadDeclUpdateRecords(Update.first, Update.second);      } - -    // Trigger the import of the full definition of each class that had any -    // odr-merging problems, so we can produce better diagnostics for them. -    for (auto &Merge : PendingOdrMergeFailures) { -      Merge.first->buildLookup(); -      Merge.first->decls_begin(); -      Merge.first->bases_begin(); -      Merge.first->vbases_begin(); -      for (auto *RD : Merge.second) { -        RD->decls_begin(); -        RD->bases_begin(); -        RD->vbases_begin(); -      } -    } - -    // For each declaration from a merged context, check that the canonical -    // definition of that context also contains a declaration of the same -    // entity. -    while (!PendingOdrMergeChecks.empty()) { -      NamedDecl *D = PendingOdrMergeChecks.pop_back_val(); - -      // FIXME: Skip over implicit declarations for now. This matters for things -      // like implicitly-declared special member functions. This isn't entirely -      // correct; we can end up with multiple unmerged declarations of the same -      // implicit entity. -      if (D->isImplicit()) -        continue; - -      DeclContext *CanonDef = D->getDeclContext(); -      DeclContext::lookup_result R = CanonDef->lookup(D->getDeclName()); - -      bool Found = false; -      const Decl *DCanon = D->getCanonicalDecl(); - -      llvm::SmallVector<const NamedDecl*, 4> Candidates; -      for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); -           !Found && I != E; ++I) { -        for (auto RI : (*I)->redecls()) { -          if (RI->getLexicalDeclContext() == CanonDef) { -            // This declaration is present in the canonical definition. If it's -            // in the same redecl chain, it's the one we're looking for. -            if (RI->getCanonicalDecl() == DCanon) -              Found = true; -            else -              Candidates.push_back(cast<NamedDecl>(RI)); -            break; -          } -        } -      } - -      if (!Found) { -        D->setInvalidDecl(); - -        std::string CanonDefModule = -            getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef)); -        Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl) -          << D << getOwningModuleNameForDiagnostic(D) -          << CanonDef << CanonDefModule.empty() << CanonDefModule; - -        if (Candidates.empty()) -          Diag(cast<Decl>(CanonDef)->getLocation(), -               diag::note_module_odr_violation_no_possible_decls) << D; -        else { -          for (unsigned I = 0, N = Candidates.size(); I != N; ++I) -            Diag(Candidates[I]->getLocation(), -                 diag::note_module_odr_violation_possible_decl) -              << Candidates[I]; -        } - -        DiagnosedOdrMergeFailures.insert(CanonDef); -      } -    }    }    // If we deserialized any C++ or Objective-C class definitions, any    // Objective-C protocol definitions, or any redeclarable templates, make sure    // that all redeclarations point to the definitions. Note that this can only     // happen now, after the redeclaration chains have been fully wired. -  for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(), -                                           DEnd = PendingDefinitions.end(); -       D != DEnd; ++D) { -    if (TagDecl *TD = dyn_cast<TagDecl>(*D)) { +  for (Decl *D : PendingDefinitions) { +    if (TagDecl *TD = dyn_cast<TagDecl>(D)) {        if (const TagType *TagT = dyn_cast<TagType>(TD->getTypeForDecl())) {          // Make sure that the TagType points at the definition.          const_cast<TagType*>(TagT)->decl = TD;        } -      if (auto RD = dyn_cast<CXXRecordDecl>(*D)) { -        for (auto R : RD->redecls()) +      if (auto RD = dyn_cast<CXXRecordDecl>(D)) { +        for (auto R : RD->redecls()) { +          assert((R == D) == R->isThisDeclarationADefinition() && +                 "declaration thinks it's the definition but it isn't");            cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData; +        }        }        continue;      } -    if (auto ID = dyn_cast<ObjCInterfaceDecl>(*D)) { +    if (auto ID = dyn_cast<ObjCInterfaceDecl>(D)) {        // Make sure that the ObjCInterfaceType points at the definition.        const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))          ->Decl = ID; @@ -8211,14 +8332,14 @@ void ASTReader::finishPendingActions() {        continue;      } -    if (auto PD = dyn_cast<ObjCProtocolDecl>(*D)) { +    if (auto PD = dyn_cast<ObjCProtocolDecl>(D)) {        for (auto R : PD->redecls())          R->Data = PD->Data;        continue;      } -    auto RTD = cast<RedeclarableTemplateDecl>(*D)->getCanonicalDecl(); +    auto RTD = cast<RedeclarableTemplateDecl>(D)->getCanonicalDecl();      for (auto R : RTD->redecls())        R->Common = RTD->Common;    } @@ -8243,10 +8364,108 @@ void ASTReader::finishPendingActions() {        MD->setLazyBody(PB->second);    }    PendingBodies.clear(); +} + +void ASTReader::diagnoseOdrViolations() { +  if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty()) +    return; + +  // Trigger the import of the full definition of each class that had any +  // odr-merging problems, so we can produce better diagnostics for them. +  // These updates may in turn find and diagnose some ODR failures, so take +  // ownership of the set first. +  auto OdrMergeFailures = std::move(PendingOdrMergeFailures); +  PendingOdrMergeFailures.clear(); +  for (auto &Merge : OdrMergeFailures) { +    Merge.first->buildLookup(); +    Merge.first->decls_begin(); +    Merge.first->bases_begin(); +    Merge.first->vbases_begin(); +    for (auto *RD : Merge.second) { +      RD->decls_begin(); +      RD->bases_begin(); +      RD->vbases_begin(); +    } +  } + +  // For each declaration from a merged context, check that the canonical +  // definition of that context also contains a declaration of the same +  // entity. +  // +  // Caution: this loop does things that might invalidate iterators into +  // PendingOdrMergeChecks. Don't turn this into a range-based for loop! +  while (!PendingOdrMergeChecks.empty()) { +    NamedDecl *D = PendingOdrMergeChecks.pop_back_val(); + +    // FIXME: Skip over implicit declarations for now. This matters for things +    // like implicitly-declared special member functions. This isn't entirely +    // correct; we can end up with multiple unmerged declarations of the same +    // implicit entity. +    if (D->isImplicit()) +      continue; + +    DeclContext *CanonDef = D->getDeclContext(); + +    bool Found = false; +    const Decl *DCanon = D->getCanonicalDecl(); + +    for (auto RI : D->redecls()) { +      if (RI->getLexicalDeclContext() == CanonDef) { +        Found = true; +        break; +      } +    } +    if (Found) +      continue; + +    llvm::SmallVector<const NamedDecl*, 4> Candidates; +    DeclContext::lookup_result R = CanonDef->lookup(D->getDeclName()); +    for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); +         !Found && I != E; ++I) { +      for (auto RI : (*I)->redecls()) { +        if (RI->getLexicalDeclContext() == CanonDef) { +          // This declaration is present in the canonical definition. If it's +          // in the same redecl chain, it's the one we're looking for. +          if (RI->getCanonicalDecl() == DCanon) +            Found = true; +          else +            Candidates.push_back(cast<NamedDecl>(RI)); +          break; +        } +      } +    } + +    if (!Found) { +      // The AST doesn't like TagDecls becoming invalid after they've been +      // completed. We only really need to mark FieldDecls as invalid here. +      if (!isa<TagDecl>(D)) +        D->setInvalidDecl(); + +      std::string CanonDefModule = +          getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef)); +      Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl) +        << D << getOwningModuleNameForDiagnostic(D) +        << CanonDef << CanonDefModule.empty() << CanonDefModule; + +      if (Candidates.empty()) +        Diag(cast<Decl>(CanonDef)->getLocation(), +             diag::note_module_odr_violation_no_possible_decls) << D; +      else { +        for (unsigned I = 0, N = Candidates.size(); I != N; ++I) +          Diag(Candidates[I]->getLocation(), +               diag::note_module_odr_violation_possible_decl) +            << Candidates[I]; +      } + +      DiagnosedOdrMergeFailures.insert(CanonDef); +    } +  }    // Issue any pending ODR-failure diagnostics. -  for (auto &Merge : PendingOdrMergeFailures) { -    if (!DiagnosedOdrMergeFailures.insert(Merge.first)) +  for (auto &Merge : OdrMergeFailures) { +    // If we've already pointed out a specific problem with this class, don't +    // bother issuing a general "something's different" diagnostic. +    if (!DiagnosedOdrMergeFailures.insert(Merge.first).second)        continue;      bool Diagnosed = false; @@ -8282,7 +8501,6 @@ void ASTReader::finishPendingActions() {          << Merge.first;      }    } -  PendingOdrMergeFailures.clear();  }  void ASTReader::FinishedDeserializing() { @@ -8295,10 +8513,13 @@ void ASTReader::FinishedDeserializing() {    }    --NumCurrentElementsDeserializing; -  if (NumCurrentElementsDeserializing == 0 && Consumer) { +  if (NumCurrentElementsDeserializing == 0) { +    diagnoseOdrViolations(); +      // We are not in recursive loading, so it's safe to pass the "interesting"      // decls to the consumer. -    PassInterestingDeclsToConsumer(); +    if (Consumer) +      PassInterestingDeclsToConsumer();    }  } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 9ed1bf97ec7a..a783183d2ef6 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -43,6 +43,9 @@ namespace clang {      const RecordData &Record;      unsigned &Idx;      TypeID TypeIDForTypeDecl; +    unsigned AnonymousDeclNumber; +    GlobalDeclID NamedDeclForTagDecl; +    IdentifierInfo *TypedefNameForLinkage;      bool HasPendingBody; @@ -106,6 +109,12 @@ namespace clang {      void MergeDefinitionData(CXXRecordDecl *D,                               struct CXXRecordDecl::DefinitionData &NewDD); +    static NamedDecl *getAnonymousDeclForMerging(ASTReader &Reader, +                                                 DeclContext *DC, +                                                 unsigned Index); +    static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC, +                                           unsigned Index, NamedDecl *D); +      /// \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. @@ -134,7 +143,7 @@ namespace clang {        ~RedeclarableResult() {          if (FirstID && Owning && isRedeclarableDeclKind(DeclKind) && -            Reader.PendingDeclChainsKnown.insert(FirstID)) +            Reader.PendingDeclChainsKnown.insert(FirstID).second)            Reader.PendingDeclChains.push_back(FirstID);        } @@ -158,50 +167,59 @@ namespace clang {        NamedDecl *New;        NamedDecl *Existing;        mutable bool AddResult; -       + +      unsigned AnonymousDeclNumber; +      IdentifierInfo *TypedefNameForLinkage; +        void operator=(FindExistingResult&) LLVM_DELETED_FUNCTION; -       +      public:        FindExistingResult(ASTReader &Reader) -        : Reader(Reader), New(nullptr), Existing(nullptr), AddResult(false) {} +          : Reader(Reader), New(nullptr), Existing(nullptr), AddResult(false), +            AnonymousDeclNumber(0), TypedefNameForLinkage(0) {} + +      FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing, +                         unsigned AnonymousDeclNumber, +                         IdentifierInfo *TypedefNameForLinkage) +          : Reader(Reader), New(New), Existing(Existing), AddResult(true), +            AnonymousDeclNumber(AnonymousDeclNumber), +            TypedefNameForLinkage(TypedefNameForLinkage) {} -      FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing) -        : Reader(Reader), New(New), Existing(Existing), AddResult(true) { } -              FindExistingResult(const FindExistingResult &Other) -        : Reader(Other.Reader), New(Other.New), Existing(Other.Existing),  -          AddResult(Other.AddResult) -      { +          : Reader(Other.Reader), New(Other.New), Existing(Other.Existing), +            AddResult(Other.AddResult), +            AnonymousDeclNumber(Other.AnonymousDeclNumber), +            TypedefNameForLinkage(Other.TypedefNameForLinkage) {          Other.AddResult = false;        } -       +        ~FindExistingResult(); -       +        /// \brief Suppress the addition of this result into the known set of        /// names.        void suppress() { AddResult = false; } -       +        operator NamedDecl*() const { return Existing; } -       +        template<typename T>        operator T*() const { return dyn_cast_or_null<T>(Existing); }      }; -     +      FindExistingResult findExisting(NamedDecl *D); -     +    public: -    ASTDeclReader(ASTReader &Reader, ModuleFile &F, -                  DeclID thisDeclID, -                  unsigned RawLocation, -                  const RecordData &Record, unsigned &Idx) -      : Reader(Reader), F(F), ThisDeclID(thisDeclID), -        RawLocation(RawLocation), Record(Record), Idx(Idx), -        TypeIDForTypeDecl(0), HasPendingBody(false) { } +    ASTDeclReader(ASTReader &Reader, ModuleFile &F, DeclID thisDeclID, +                  unsigned RawLocation, const RecordData &Record, unsigned &Idx) +        : Reader(Reader), F(F), ThisDeclID(thisDeclID), +          RawLocation(RawLocation), Record(Record), Idx(Idx), +          TypeIDForTypeDecl(0), NamedDeclForTagDecl(0), +          TypedefNameForLinkage(nullptr), HasPendingBody(false) {}      template <typename DeclT> -    static void attachPreviousDeclImpl(Redeclarable<DeclT> *D, Decl *Previous); -    static void attachPreviousDeclImpl(...); -    static void attachPreviousDecl(Decl *D, Decl *previous); +    static void attachPreviousDeclImpl(ASTReader &Reader, +                                       Redeclarable<DeclT> *D, Decl *Previous); +    static void attachPreviousDeclImpl(ASTReader &Reader, ...); +    static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous);      template <typename DeclT>      static void attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest); @@ -233,7 +251,7 @@ namespace clang {      void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);      void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);      void VisitTypeDecl(TypeDecl *TD); -    void VisitTypedefNameDecl(TypedefNameDecl *TD); +    RedeclarableResult VisitTypedefNameDecl(TypedefNameDecl *TD);      void VisitTypedefDecl(TypedefDecl *TD);      void VisitTypeAliasDecl(TypeAliasDecl *TD);      void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); @@ -359,6 +377,12 @@ void ASTDeclReader::Visit(Decl *D) {    if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {      // We have a fully initialized TypeDecl. Read its type now.      TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull()); + +    // If this is a tag declaration with a typedef name for linkage, it's safe +    // to load that typedef now. +    if (NamedDeclForTagDecl) +      cast<TagDecl>(D)->NamedDeclOrQualifier = +          cast<NamedDecl>(Reader.GetDecl(NamedDeclForTagDecl));    } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {      // if we have a fully initialized TypeDecl, we can safely read its type now.      ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull(); @@ -446,6 +470,8 @@ 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++];  }  void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { @@ -455,7 +481,8 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {    TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);  } -void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { +ASTDeclReader::RedeclarableResult +ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {    RedeclarableResult Redecl = VisitRedeclarable(TD);    VisitTypeDecl(TD);    TypeSourceInfo *TInfo = GetTypeSourceInfo(Record, Idx); @@ -464,15 +491,21 @@ void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {      TD->setModedTypeSourceInfo(TInfo, modedT);    } else      TD->setTypeSourceInfo(TInfo); -  mergeRedeclarable(TD, Redecl); +  return Redecl;  }  void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) { -  VisitTypedefNameDecl(TD); +  RedeclarableResult Redecl = VisitTypedefNameDecl(TD); +  mergeRedeclarable(TD, Redecl);  }  void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) { -  VisitTypedefNameDecl(TD); +  RedeclarableResult Redecl = VisitTypedefNameDecl(TD); +  if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>(Record, Idx)) +    // Merged when we merge the template. +    TD->setDescribedAliasTemplate(Template); +  else +    mergeRedeclarable(TD, Redecl);  }  ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) { @@ -481,18 +514,32 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {    TD->IdentifierNamespace = Record[Idx++];    TD->setTagKind((TagDecl::TagKind)Record[Idx++]); -  TD->setCompleteDefinition(Record[Idx++]); +  if (!isa<CXXRecordDecl>(TD)) +    TD->setCompleteDefinition(Record[Idx++]);    TD->setEmbeddedInDeclarator(Record[Idx++]);    TD->setFreeStanding(Record[Idx++]);    TD->setCompleteDefinitionRequired(Record[Idx++]);    TD->setRBraceLoc(ReadSourceLocation(Record, Idx)); -  if (Record[Idx++]) { // hasExtInfo +  switch (Record[Idx++]) { +  case 0: +    break; +  case 1: { // ExtInfo      TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();      ReadQualifierInfo(*Info, Record, Idx);      TD->NamedDeclOrQualifier = Info; -  } else -    TD->NamedDeclOrQualifier = ReadDeclAs<NamedDecl>(Record, Idx); +    break; +  } +  case 2: // TypedefNameForAnonDecl +    NamedDeclForTagDecl = ReadDeclID(Record, Idx); +    TypedefNameForLinkage = Reader.GetIdentifierInfo(F, Record, Idx); +    break; +  case 3: // DeclaratorForAnonDecl +    NamedDeclForTagDecl = ReadDeclID(Record, Idx); +    break; +  default: +    llvm_unreachable("unexpected tag info kind"); +  }    if (!isa<CXXRecordDecl>(TD))      mergeRedeclarable(TD, Redecl); @@ -953,8 +1000,15 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {    VisitDeclaratorDecl(FD);    FD->Mutable = Record[Idx++];    if (int BitWidthOrInitializer = Record[Idx++]) { -    FD->InitializerOrBitWidth.setInt(BitWidthOrInitializer - 1); -    FD->InitializerOrBitWidth.setPointer(Reader.ReadExpr(F)); +    FD->InitStorage.setInt( +          static_cast<FieldDecl::InitStorageKind>(BitWidthOrInitializer - 1)); +    if (FD->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) { +      // Read captured variable length array. +      FD->InitStorage.setPointer( +          Reader.readType(F, Record, Idx).getAsOpaquePtr()); +    } else { +      FD->InitStorage.setPointer(Reader.ReadExpr(F)); +    }    }    if (!FD->getDeclName()) {      if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>(Record, Idx)) @@ -1140,7 +1194,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {      // 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_Module) +    if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule)        D->setAnonymousNamespace(Anon);    } else {      // Link this namespace back to the first declaration, which has already @@ -1152,11 +1206,13 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {  }  void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { +  RedeclarableResult Redecl = VisitRedeclarable(D);    VisitNamedDecl(D);    D->NamespaceLoc = ReadSourceLocation(Record, Idx);    D->IdentLoc = ReadSourceLocation(Record, Idx);    D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);    D->Namespace = ReadDeclAs<NamedDecl>(Record, Idx); +  mergeRedeclarable(D, Redecl);  }  void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { @@ -1168,6 +1224,7 @@ void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {    D->setTypename(Record[Idx++]);    if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>(Record, Idx))      Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern); +  mergeMergeable(D);  }  void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { @@ -1195,6 +1252,7 @@ void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {    D->setUsingLoc(ReadSourceLocation(Record, Idx));    D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);    ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx); +  mergeMergeable(D);  }  void ASTDeclReader::VisitUnresolvedUsingTypenameDecl( @@ -1202,6 +1260,7 @@ void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(    VisitTypeDecl(D);    D->TypenameLocation = ReadSourceLocation(Record, Idx);    D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); +  mergeMergeable(D);  }  void ASTDeclReader::ReadCXXDefinitionData( @@ -1279,6 +1338,7 @@ void ASTDeclReader::ReadCXXDefinitionData(        LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record[Idx++]);        switch (Kind) {        case LCK_This: +      case LCK_VLAType:          *ToCapture++ = Capture(Loc, IsImplicit, Kind, nullptr,SourceLocation());          break;        case LCK_ByCopy: @@ -1300,8 +1360,11 @@ void ASTDeclReader::MergeDefinitionData(    // If the new definition has new special members, let the name lookup    // code know that it needs to look in the new definition too. -  if ((MergeDD.DeclaredSpecialMembers & ~DD.DeclaredSpecialMembers) && -      DD.Definition != MergeDD.Definition) { +  // +  // 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) {      Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition);      DD.Definition->setHasExternalVisibleStorage();    } @@ -1493,12 +1556,19 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {  void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {    VisitFunctionDecl(D); +    unsigned NumOverridenMethods = Record[Idx++]; -  while (NumOverridenMethods--) { -    // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod, -    // MD may be initializing. -    if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx)) -      Reader.getContext().addOverriddenMethod(D, MD); +  if (D->isCanonicalDecl()) { +    while (NumOverridenMethods--) { +      // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod, +      // MD may be initializing. +      if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx)) +        Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl()); +    } +  } else { +    // We don't care about which declarations this used to override; we get +    // the relevant information from the canonical declaration. +    Idx += NumOverridenMethods;    }  } @@ -2015,6 +2085,8 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,    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 @@ -2075,6 +2147,9 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,                               Result);    if (auto *DVar = dyn_cast<VarDecl>(DPattern))      return mergeRedeclarable(DVar, cast<VarDecl>(ExistingPattern), Result); +  if (auto *DAlias = dyn_cast<TypeAliasDecl>(DPattern)) +    return mergeRedeclarable(DAlias, cast<TypedefNameDecl>(ExistingPattern), +                             Result);    llvm_unreachable("merged an unknown kind of redeclarable template");  } @@ -2199,7 +2274,8 @@ static bool isConsumerInterestedIn(Decl *D, bool HasBody) {    if (isa<FileScopeAsmDecl>(D) ||         isa<ObjCProtocolDecl>(D) ||         isa<ObjCImplDecl>(D) || -      isa<ImportDecl>(D)) +      isa<ImportDecl>(D) || +      isa<OMPThreadPrivateDecl>(D))      return true;    if (VarDecl *Var = dyn_cast<VarDecl>(D))      return Var->isFileVarDecl() && @@ -2269,6 +2345,53 @@ static bool isSameTemplateParameter(const NamedDecl *X,                                       TY->getTemplateParameters());  } +static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) { +  if (auto *NS = X->getAsNamespace()) +    return NS; +  if (auto *NAS = X->getAsNamespaceAlias()) +    return NAS->getNamespace(); +  return nullptr; +} + +static bool isSameQualifier(const NestedNameSpecifier *X, +                            const NestedNameSpecifier *Y) { +  if (auto *NSX = getNamespace(X)) { +    auto *NSY = getNamespace(Y); +    if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl()) +      return false; +  } else if (X->getKind() != Y->getKind()) +    return false; + +  // FIXME: For namespaces and types, we're permitted to check that the entity +  // is named via the same tokens. We should probably do so. +  switch (X->getKind()) { +  case NestedNameSpecifier::Identifier: +    if (X->getAsIdentifier() != Y->getAsIdentifier()) +      return false; +    break; +  case NestedNameSpecifier::Namespace: +  case NestedNameSpecifier::NamespaceAlias: +    // We've already checked that we named the same namespace. +    break; +  case NestedNameSpecifier::TypeSpec: +  case NestedNameSpecifier::TypeSpecWithTemplate: +    if (X->getAsType()->getCanonicalTypeInternal() != +        Y->getAsType()->getCanonicalTypeInternal()) +      return false; +    break; +  case NestedNameSpecifier::Global: +  case NestedNameSpecifier::Super: +    return true; +  } + +  // Recurse into earlier portion of NNS, if any. +  auto *PX = X->getPrefix(); +  auto *PY = Y->getPrefix(); +  if (PX && PY) +    return isSameQualifier(PX, PY); +  return !PX && !PY; +} +  /// \brief Determine whether two template parameter lists are similar enough  /// that they may be used in declarations of the same template.  static bool isSameTemplateParameterList(const TemplateParameterList *X, @@ -2286,10 +2409,10 @@ static bool isSameTemplateParameterList(const TemplateParameterList *X,  /// \brief Determine whether the two declarations refer to the same entity.  static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {    assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!"); -   +    if (X == Y)      return true; -   +    // Must be in the same context.    if (!X->getDeclContext()->getRedeclContext()->Equals(           Y->getDeclContext()->getRedeclContext())) @@ -2301,11 +2424,11 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {      if (TypedefNameDecl *TypedefY = dyn_cast<TypedefNameDecl>(Y))        return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(),                                              TypedefY->getUnderlyingType()); -   +    // Must have the same kind.    if (X->getKind() != Y->getKind())      return false; -     +    // Objective-C classes and protocols with the same name always match.    if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X))      return true; @@ -2327,8 +2450,8 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {    }    // Functions with the same type and linkage match. -  // FIXME: This needs to cope with function template specializations, -  // merging of prototyped/non-prototyped functions, etc. +  // FIXME: This needs to cope with merging of prototyped/non-prototyped +  // functions, etc.    if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) {      FunctionDecl *FuncY = cast<FunctionDecl>(Y);      return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) && @@ -2361,7 +2484,6 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {    // Fields with the same name and the same type match.    if (FieldDecl *FDX = dyn_cast<FieldDecl>(X)) {      FieldDecl *FDY = cast<FieldDecl>(Y); -    // FIXME: Diagnose if the types don't match.      // FIXME: Also check the bitwidth is odr-equivalent, if any.      return X->getASTContext().hasSameType(FDX->getType(), FDY->getType());    } @@ -2377,6 +2499,30 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {      return USX->getTargetDecl() == USY->getTargetDecl();    } +  // Using declarations with the same qualifier match. (We already know that +  // the name matches.) +  if (auto *UX = dyn_cast<UsingDecl>(X)) { +    auto *UY = cast<UsingDecl>(Y); +    return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && +           UX->hasTypename() == UY->hasTypename() && +           UX->isAccessDeclaration() == UY->isAccessDeclaration(); +  } +  if (auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) { +    auto *UY = cast<UnresolvedUsingValueDecl>(Y); +    return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && +           UX->isAccessDeclaration() == UY->isAccessDeclaration(); +  } +  if (auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) +    return isSameQualifier( +        UX->getQualifier(), +        cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier()); + +  // Namespace alias definitions with the same target match. +  if (auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) { +    auto *NAY = cast<NamespaceAliasDecl>(Y); +    return NAX->getNamespace()->Equals(NAY->getNamespace()); +  } +    // FIXME: Many other cases to implement.    return false;  } @@ -2387,8 +2533,14 @@ static DeclContext *getPrimaryContextForMerging(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->getDefinition(); +    return RD->getPrimaryContext();    if (EnumDecl *ED = dyn_cast<EnumDecl>(DC))      return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition() @@ -2401,9 +2553,17 @@ ASTDeclReader::FindExistingResult::~FindExistingResult() {    if (!AddResult || Existing)      return; +  DeclarationName Name = New->getDeclName();    DeclContext *DC = New->getDeclContext()->getRedeclContext(); -  if (DC->isTranslationUnit() && Reader.SemaObj) { -    Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, New->getDeclName()); +  if (TypedefNameForLinkage) { +    Reader.ImportedTypedefNamesForLinkage.insert( +        std::make_pair(std::make_pair(DC, TypedefNameForLinkage), New)); +  } else if (!Name) { +    assert(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)) {      // Add the declaration to its redeclaration context so later merging      // lookups will find it. @@ -2411,11 +2571,81 @@ ASTDeclReader::FindExistingResult::~FindExistingResult() {    }  } +/// Find the declaration that should be merged into, given the declaration found +/// by name lookup. If we're merging an anonymous declaration within a typedef, +/// we need a matching typedef, and we merge with the type inside it. +static NamedDecl *getDeclForMerging(NamedDecl *Found, +                                    bool IsTypedefNameForLinkage) { +  if (!IsTypedefNameForLinkage) +    return 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(); +  } + +  return 0; +} + +NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader, +                                                     DeclContext *DC, +                                                     unsigned Index) { +  // If the lexical context has been merged, look into the now-canonical +  // definition. +  if (auto *Merged = Reader.MergedDeclContexts.lookup(DC)) +    DC = Merged; + +  // If we've seen this before, return the canonical declaration. +  auto &Previous = Reader.AnonymousDeclarationsForMerging[DC]; +  if (Index < Previous.size() && Previous[Index]) +    return Previous[Index]; + +  // 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) +        Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl())); +      else +        Previous[Index] = cast<NamedDecl>(ND->getCanonicalDecl()); +      ++Index; +    } +  } + +  return Index < Previous.size() ? Previous[Index] : nullptr; +} + +void ASTDeclReader::setAnonymousDeclForMerging(ASTReader &Reader, +                                               DeclContext *DC, unsigned Index, +                                               NamedDecl *D) { +  if (auto *Merged = Reader.MergedDeclContexts.lookup(DC)) +    DC = Merged; + +  auto &Previous = Reader.AnonymousDeclarationsForMerging[DC]; +  if (Index >= Previous.size()) +    Previous.resize(Index + 1); +  if (!Previous[Index]) +    Previous[Index] = D; +} +  ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { -  DeclarationName Name = D->getDeclName(); -  if (!Name) { -    // Don't bother trying to find unnamed declarations. -    FindExistingResult Result(Reader, D, /*Existing=*/nullptr); +  DeclarationName Name = TypedefNameForLinkage ? TypedefNameForLinkage +                                               : D->getDeclName(); + +  if (!Name && !needsAnonymousDeclarationNumber(D)) { +    // Don't bother trying to find unnamed declarations that are in +    // 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(); @@ -2426,7 +2656,27 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {    // necessary merging already.    DeclContext *DC = D->getDeclContext()->getRedeclContext(); -  if (DC->isTranslationUnit() && Reader.SemaObj) { +  if (TypedefNameForLinkage) { +    auto It = Reader.ImportedTypedefNamesForLinkage.find( +        std::make_pair(DC, TypedefNameForLinkage)); +    if (It != Reader.ImportedTypedefNamesForLinkage.end()) +      if (isSameEntity(It->second, D)) +        return FindExistingResult(Reader, D, It->second, AnonymousDeclNumber, +                                  TypedefNameForLinkage); +    // Go on to check in other places in case an existing typedef name +    // was not imported. +  } + +  if (!Name) { +    // 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) {      IdentifierResolver &IdResolver = Reader.SemaObj->IdResolver;      // Temporarily consider the identifier to be up-to-date. We don't want to @@ -2455,14 +2705,18 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {      for (IdentifierResolver::iterator I = IdResolver.begin(Name),                                      IEnd = IdResolver.end();           I != IEnd; ++I) { -      if (isSameEntity(*I, D)) -        return FindExistingResult(Reader, D, *I); +      if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage)) +        if (isSameEntity(Existing, D)) +          return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, +                                    TypedefNameForLinkage);      }    } else if (DeclContext *MergeDC = getPrimaryContextForMerging(DC)) {      DeclContext::lookup_result R = MergeDC->noload_lookup(Name);      for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) { -      if (isSameEntity(*I, D)) -        return FindExistingResult(Reader, D, *I); +      if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage)) +        if (isSameEntity(Existing, D)) +          return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, +                                    TypedefNameForLinkage);      }    } else {      // Not in a mergeable context. @@ -2474,29 +2728,78 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {    //    // FIXME: We should do something similar if we merge two definitions of the    // same template specialization into the same CXXRecordDecl. -  if (Reader.MergedDeclContexts.count(D->getLexicalDeclContext())) +  auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext()); +  if (MergedDCIt != Reader.MergedDeclContexts.end() && +      MergedDCIt->second == D->getDeclContext())      Reader.PendingOdrMergeChecks.push_back(D); -  return FindExistingResult(Reader, D, /*Existing=*/nullptr); +  return FindExistingResult(Reader, D, /*Existing=*/nullptr, +                            AnonymousDeclNumber, TypedefNameForLinkage);  }  template<typename DeclT> -void ASTDeclReader::attachPreviousDeclImpl(Redeclarable<DeclT> *D, +void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, +                                           Redeclarable<DeclT> *D,                                             Decl *Previous) {    D->RedeclLink.setPrevious(cast<DeclT>(Previous));  } -void ASTDeclReader::attachPreviousDeclImpl(...) { +namespace clang { +template<> +void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, +                                           Redeclarable<FunctionDecl> *D, +                                           Decl *Previous) { +  FunctionDecl *FD = static_cast<FunctionDecl*>(D); +  FunctionDecl *PrevFD = cast<FunctionDecl>(Previous); + +  FD->RedeclLink.setPrevious(PrevFD); + +  // If the previous declaration is an inline function declaration, then this +  // declaration is too. +  if (PrevFD->IsInline != FD->IsInline) { +    // FIXME: [dcl.fct.spec]p4: +    //   If a function with external linkage is declared inline in one +    //   translation unit, it shall be declared inline in all translation +    //   units in which it appears. +    // +    // Be careful of this case: +    // +    // module A: +    //   template<typename T> struct X { void f(); }; +    //   template<typename T> inline void X<T>::f() {} +    // +    // module B instantiates the declaration of X<int>::f +    // module C instantiates the definition of X<int>::f +    // +    // If module B and C are merged, we do not have a violation of this rule. +    FD->IsInline = true; +  } + +  // If this declaration has an unresolved exception specification but the +  // previous declaration had a resolved one, resolve the exception +  // specification now. +  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); +  } +} +} +void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {    llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");  } -void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *Previous) { +void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D, +                                       Decl *Previous) {    assert(D && Previous);    switch (D->getKind()) {  #define ABSTRACT_DECL(TYPE) -#define DECL(TYPE, BASE)                                   \ -  case Decl::TYPE:                                         \ -    attachPreviousDeclImpl(cast<TYPE##Decl>(D), Previous); \ +#define DECL(TYPE, BASE)                                           \ +  case Decl::TYPE:                                                 \ +    attachPreviousDeclImpl(Reader, cast<TYPE##Decl>(D), Previous); \      break;  #include "clang/AST/DeclNodes.inc"    } @@ -2514,32 +2817,6 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *Previous) {    // be too.    if (Previous->Used)      D->Used = true; - -  // If the previous declaration is an inline function declaration, then this -  // declaration is too. -  if (auto *FD = dyn_cast<FunctionDecl>(D)) { -    if (cast<FunctionDecl>(Previous)->IsInline != FD->IsInline) { -      // FIXME: [dcl.fct.spec]p4: -      //   If a function with external linkage is declared inline in one -      //   translation unit, it shall be declared inline in all translation -      //   units in which it appears. -      // -      // Be careful of this case: -      // -      // module A: -      //   template<typename T> struct X { void f(); }; -      //   template<typename T> inline void X<T>::f() {} -      // -      // module B instantiates the declaration of X<int>::f -      // module C instantiates the definition of X<int>::f -      // -      // If module B and C are merged, we do not have a violation of this rule. -      // -      //if (!FD->IsInline || Previous->getOwningModule()) -      //  Diag(FD->getLocation(), diag::err_odr_differing_inline); -      FD->IsInline = true; -    } -  }  }  template<typename DeclT> @@ -2593,11 +2870,11 @@ ASTReader::combineStoredMergedDecls(Decl *Canon, GlobalDeclID CanonID) {    // 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,  +    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()), @@ -2927,13 +3204,13 @@ namespace {    class RedeclChainVisitor {      ASTReader &Reader;      SmallVectorImpl<DeclID> &SearchDecls; -    llvm::SmallPtrSet<Decl *, 16> &Deserialized; +    llvm::SmallPtrSetImpl<Decl *> &Deserialized;      GlobalDeclID CanonID;      SmallVector<Decl *, 4> Chain;    public:      RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls, -                       llvm::SmallPtrSet<Decl *, 16> &Deserialized, +                       llvm::SmallPtrSetImpl<Decl *> &Deserialized,                         GlobalDeclID CanonID)        : Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized),          CanonID(CanonID) {  @@ -3038,7 +3315,7 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {      if (Chain[I] == CanonDecl)        continue; -    ASTDeclReader::attachPreviousDecl(Chain[I], MostRecent); +    ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent);      MostRecent = Chain[I];    } @@ -3052,7 +3329,7 @@ namespace {      ASTReader &Reader;      serialization::GlobalDeclID InterfaceID;      ObjCInterfaceDecl *Interface; -    llvm::SmallPtrSet<ObjCCategoryDecl *, 16> &Deserialized; +    llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized;      unsigned PreviousGeneration;      ObjCCategoryDecl *Tail;      llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap; @@ -3100,7 +3377,7 @@ namespace {      ObjCCategoriesVisitor(ASTReader &Reader,                            serialization::GlobalDeclID InterfaceID,                            ObjCInterfaceDecl *Interface, -                        llvm::SmallPtrSet<ObjCCategoryDecl *, 16> &Deserialized, +                        llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized,                            unsigned PreviousGeneration)        : Reader(Reader), InterfaceID(InterfaceID), Interface(Interface),          Deserialized(Deserialized), PreviousGeneration(PreviousGeneration), @@ -3168,13 +3445,80 @@ void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID,    ModuleMgr.visit(ObjCCategoriesVisitor::visit, &Visitor);  } +namespace { +/// Iterator over the redeclarations of a declaration that have already +/// been merged into the same redeclaration chain. +template<typename DeclT> +class MergedRedeclIterator { +  DeclT *Start, *Canonical, *Current; +public: +  MergedRedeclIterator() : Current(nullptr) {} +  MergedRedeclIterator(DeclT *Start) +      : Start(Start), Canonical(nullptr), Current(Start) {} + +  DeclT *operator*() { return Current; } + +  MergedRedeclIterator &operator++() { +    if (Current->isFirstDecl()) { +      Canonical = Current; +      Current = Current->getMostRecentDecl(); +    } else +      Current = Current->getPreviousDecl(); + +    // If we started in the merged portion, we'll reach our start position +    // eventually. Otherwise, we'll never reach it, but the second declaration +    // we reached was the canonical declaration, so stop when we see that one +    // again. +    if (Current == Start || Current == Canonical) +      Current = nullptr; +    return *this; +  } + +  friend bool operator!=(const MergedRedeclIterator &A, +                         const MergedRedeclIterator &B) { +    return A.Current != B.Current; +  } +}; +} +template<typename DeclT> +llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) { +  return llvm::iterator_range<MergedRedeclIterator<DeclT>>( +      MergedRedeclIterator<DeclT>(D), +      MergedRedeclIterator<DeclT>()); +} + +template<typename DeclT, typename Fn> +static void forAllLaterRedecls(DeclT *D, Fn F) { +  F(D); + +  // Check whether we've already merged D into its redeclaration chain. +  // MostRecent may or may not be nullptr if D has not been merged. If +  // not, walk the merged redecl chain and see if it's there. +  auto *MostRecent = D->getMostRecentDecl(); +  bool Found = false; +  for (auto *Redecl = MostRecent; Redecl && !Found; +       Redecl = Redecl->getPreviousDecl()) +    Found = (Redecl == D); + +  // If this declaration is merged, apply the functor to all later decls. +  if (Found) { +    for (auto *Redecl = MostRecent; Redecl != D; +         Redecl = Redecl->getPreviousDecl()) +      F(Redecl); +  } +} +  void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,                                 const RecordData &Record) {    while (Idx < Record.size()) {      switch ((DeclUpdateKind)Record[Idx++]) {      case UPD_CXX_ADDED_IMPLICIT_MEMBER: { +      // 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);        break;      } @@ -3191,7 +3535,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,        // 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. -      if (ModuleFile.Kind != MK_Module) { +      if (ModuleFile.Kind != MK_ImplicitModule && +          ModuleFile.Kind != MK_ExplicitModule) {          if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))            TU->setAnonymousNamespace(Anon);          else @@ -3205,7 +3550,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,            Reader.ReadSourceLocation(ModuleFile, Record, Idx));        break; -    case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION: { +    case UPD_CXX_ADDED_FUNCTION_DEFINITION: {        FunctionDecl *FD = cast<FunctionDecl>(D);        if (Reader.PendingBodies[FD]) {          // FIXME: Maybe check for ODR violations. @@ -3217,17 +3562,18 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,          // Maintain AST consistency: any later redeclarations of this function          // are inline if this one is. (We might have merged another declaration          // into this one.) -        for (auto *D = FD->getMostRecentDecl(); /**/; -             D = D->getPreviousDecl()) { -          D->setImplicitlyInline(); -          if (D == FD) -            break; -        } +        forAllLaterRedecls(FD, [](FunctionDecl *FD) { +          FD->setImplicitlyInline(); +        });        }        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));        // Store the offset of the body so we can lazily load it later.        Reader.PendingBodies[FD] = GetCurrentCursorOffset();        HasPendingBody = true; @@ -3246,6 +3592,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,          Reader.ReadDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor,                                            std::make_pair(LexicalOffset, 0),                                            ModuleFile.DeclContextInfos[RD]); +        Reader.PendingDefinitions.insert(RD);        }        auto TSK = (TemplateSpecializationKind)Record[Idx++]; @@ -3267,7 +3614,12 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,            Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);            auto *TemplArgList = TemplateArgumentList::CreateCopy(                Reader.getContext(), TemplArgs.data(), TemplArgs.size()); -          Spec->setInstantiationOf(PartialSpec, TemplArgList); + +          // FIXME: If we already have a partial specialization set, +          // check that it matches. +          if (!Spec->getSpecializedTemplateOrPartial() +                   .is<ClassTemplatePartialSpecializationDecl *>()) +            Spec->setInstantiationOf(PartialSpec, TemplArgList);          }        } @@ -3285,20 +3637,35 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,      }      case UPD_CXX_RESOLVED_EXCEPTION_SPEC: { -      auto *FD = cast<FunctionDecl>(D); -      auto *FPT = FD->getType()->castAs<FunctionProtoType>(); -      auto EPI = FPT->getExtProtoInfo(); +      // 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, EPI, Record, Idx); -      FD->setType(Reader.Context.getFunctionType(FPT->getReturnType(), -                                                 FPT->getParamTypes(), EPI)); +      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; +        } +        FD->setType(Reader.Context.getFunctionType( +            FPT->getReturnType(), FPT->getParamTypes(), +            FPT->getExtProtoInfo().withExceptionSpec(ESI))); +      }        break;      }      case UPD_CXX_DEDUCED_RETURN_TYPE: { -      FunctionDecl *FD = cast<FunctionDecl>(D); -      Reader.Context.adjustDeducedFunctionResultType( -          FD, Reader.readType(ModuleFile, Record, Idx)); +      // FIXME: Also do this when merging redecls. +      QualType DeducedResultType = Reader.readType(ModuleFile, Record, Idx); +      for (auto *Redecl : merged_redecls(D)) { +        // FIXME: If the return type is already deduced, check that it matches. +        FunctionDecl *FD = cast<FunctionDecl>(Redecl); +        Reader.Context.adjustDeducedFunctionResultType(FD, DeducedResultType); +      }        break;      } @@ -3306,17 +3673,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,        // FIXME: This doesn't send the right notifications if there are        // ASTMutationListeners other than an ASTWriter. -      // FIXME: We can't both pull in declarations (and thus create new pending -      // redeclaration chains) *and* walk redeclaration chains in this function. -      // We should defer the updates that require walking redecl chains. -        // Maintain AST consistency: any later redeclarations are used too. -      for (auto *Redecl = D->getMostRecentDecl(); /**/; -           Redecl = Redecl->getPreviousDecl()) { -        Redecl->Used = true; -        if (Redecl == D) -          break; -      } +      forAllLaterRedecls(D, [](Decl *D) { D->Used = true; });        break;      } @@ -3327,6 +3685,10 @@ 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;      }    }  } diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h index a63e362eb64f..d1b032b27ac2 100644 --- a/lib/Serialization/ASTReaderInternals.h +++ b/lib/Serialization/ASTReaderInternals.h @@ -10,8 +10,8 @@  //  This file provides internal definitions used in the AST reader.  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H -#define LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H +#ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H +#define LLVM_CLANG_LIB_SERIALIZATION_ASTREADERINTERNALS_H  #include "clang/AST/DeclarationName.h"  #include "clang/Serialization/ASTBitCodes.h" @@ -156,6 +156,8 @@ public:      SelectorID ID;      unsigned InstanceBits;      unsigned FactoryBits; +    bool InstanceHasMoreThanOneDecl; +    bool FactoryHasMoreThanOneDecl;      SmallVector<ObjCMethodDecl *, 2> Instance;      SmallVector<ObjCMethodDecl *, 2> Factory;    }; @@ -194,8 +196,8 @@ typedef llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>  ///  /// The on-disk hash table contains a mapping from each header path to   /// information about that header (how many times it has been included, its -/// controlling macro, etc.). Note that we actually hash based on the  -/// filename, and support "deep" comparisons of file names based on current +/// controlling macro, etc.). Note that we actually hash based on the size +/// and mtime, and support "deep" comparisons of file names based on current  /// inode numbers, so that the search can cope with non-normalized path names  /// and symlinks.  class HeaderFileInfoTrait { @@ -211,6 +213,7 @@ public:      off_t Size;      time_t ModTime;      const char *Filename; +    bool Imported;    };    typedef const internal_key_type &internal_key_ref; diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 8bf17d51b3e8..4ef2e73062a5 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -135,8 +135,8 @@ void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {    while (NumStmts--)      Stmts.push_back(Reader.ReadSubStmt());    S->setStmts(Reader.getContext(), Stmts.data(), Stmts.size()); -  S->setLBracLoc(ReadSourceLocation(Record, Idx)); -  S->setRBracLoc(ReadSourceLocation(Record, Idx)); +  S->LBraceLoc = ReadSourceLocation(Record, Idx); +  S->RBraceLoc = ReadSourceLocation(Record, Idx);  }  void ASTStmtReader::VisitSwitchCase(SwitchCase *S) { @@ -422,7 +422,8 @@ void ASTStmtReader::VisitExpr(Expr *E) {  void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {    VisitExpr(E);    E->setLocation(ReadSourceLocation(Record, Idx)); -  E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]); +  E->Type = (PredefinedExpr::IdentType)Record[Idx++]; +  E->FnName = cast_or_null<StringLiteral>(Reader.ReadSubExpr());  }  void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { @@ -432,7 +433,7 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {    E->DeclRefExprBits.HasFoundDecl = Record[Idx++];    E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record[Idx++];    E->DeclRefExprBits.HadMultipleCandidates = Record[Idx++]; -  E->DeclRefExprBits.RefersToEnclosingLocal = Record[Idx++]; +  E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record[Idx++];    unsigned NumTemplateArgs = 0;    if (E->hasTemplateKWAndArgsInfo())      NumTemplateArgs = Record[Idx++]; @@ -634,7 +635,7 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {    unsigned NumBaseSpecs = Record[Idx++];    assert(NumBaseSpecs == E->path_size());    E->setSubExpr(Reader.ReadSubExpr()); -  E->setCastKind((CastExpr::CastKind)Record[Idx++]); +  E->setCastKind((CastKind)Record[Idx++]);    CastExpr::path_iterator BaseI = E->path_begin();    while (NumBaseSpecs--) {      CXXBaseSpecifier *BaseSpec = new (Reader.getContext()) CXXBaseSpecifier; @@ -1579,12 +1580,26 @@ void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {    E->setExtendingDecl(VD, ManglingNumber);  } +void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) { +  VisitExpr(E); +  E->LParenLoc = ReadSourceLocation(Record, Idx); +  E->EllipsisLoc = ReadSourceLocation(Record, Idx); +  E->RParenLoc = ReadSourceLocation(Record, Idx); +  E->SubExprs[0] = Reader.ReadSubExpr(); +  E->SubExprs[1] = Reader.ReadSubExpr(); +  E->Opcode = (BinaryOperatorKind)Record[Idx++]; +} +  void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {    VisitExpr(E);    E->SourceExpr = Reader.ReadSubExpr();    E->Loc = ReadSourceLocation(Record, Idx);  } +void ASTStmtReader::VisitTypoExpr(TypoExpr *E) { +  llvm_unreachable("Cannot read TypoExpr nodes"); +} +  //===----------------------------------------------------------------------===//  // Microsoft Expressions and Statements  //===----------------------------------------------------------------------===// @@ -1715,6 +1730,21 @@ OMPClause *OMPClauseReader::readClause() {    case OMPC_mergeable:      C = new (Context) OMPMergeableClause();      break; +  case OMPC_read: +    C = new (Context) OMPReadClause(); +    break; +  case OMPC_write: +    C = new (Context) OMPWriteClause(); +    break; +  case OMPC_update: +    C = new (Context) OMPUpdateClause(); +    break; +  case OMPC_capture: +    C = new (Context) OMPCaptureClause(); +    break; +  case OMPC_seq_cst: +    C = new (Context) OMPSeqCstClause(); +    break;    case OMPC_private:      C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);      break; @@ -1809,6 +1839,16 @@ void OMPClauseReader::VisitOMPUntiedClause(OMPUntiedClause *) {}  void OMPClauseReader::VisitOMPMergeableClause(OMPMergeableClause *) {} +void OMPClauseReader::VisitOMPReadClause(OMPReadClause *) {} + +void OMPClauseReader::VisitOMPWriteClause(OMPWriteClause *) {} + +void OMPClauseReader::VisitOMPUpdateClause(OMPUpdateClause *) {} + +void OMPClauseReader::VisitOMPCaptureClause(OMPCaptureClause *) {} + +void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {} +  void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {    C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));    unsigned NumVars = C->varlist_size(); @@ -1817,6 +1857,10 @@ void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {    for (unsigned i = 0; i != NumVars; ++i)      Vars.push_back(Reader->Reader.ReadSubExpr());    C->setVarRefs(Vars); +  Vars.clear(); +  for (unsigned i = 0; i != NumVars; ++i) +    Vars.push_back(Reader->Reader.ReadSubExpr()); +  C->setPrivateCopies(Vars);  }  void OMPClauseReader::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) { @@ -1827,6 +1871,14 @@ void OMPClauseReader::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {    for (unsigned i = 0; i != NumVars; ++i)      Vars.push_back(Reader->Reader.ReadSubExpr());    C->setVarRefs(Vars); +  Vars.clear(); +  for (unsigned i = 0; i != NumVars; ++i) +    Vars.push_back(Reader->Reader.ReadSubExpr()); +  C->setPrivateCopies(Vars); +  Vars.clear(); +  for (unsigned i = 0; i != NumVars; ++i) +    Vars.push_back(Reader->Reader.ReadSubExpr()); +  C->setInits(Vars);  }  void OMPClauseReader::VisitOMPLastprivateClause(OMPLastprivateClause *C) { @@ -1936,6 +1988,45 @@ void ASTStmtReader::VisitOMPExecutableDirective(OMPExecutableDirective *E) {      E->setAssociatedStmt(Reader.ReadSubStmt());  } +void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) { +  VisitStmt(D); +  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream. +  Idx += 2; +  VisitOMPExecutableDirective(D); +  D->setIterationVariable(Reader.ReadSubExpr()); +  D->setLastIteration(Reader.ReadSubExpr()); +  D->setCalcLastIteration(Reader.ReadSubExpr()); +  D->setPreCond(Reader.ReadSubExpr()); +  auto Fst = Reader.ReadSubExpr(); +  auto Snd = Reader.ReadSubExpr(); +  D->setCond(Fst, Snd); +  D->setInit(Reader.ReadSubExpr()); +  D->setInc(Reader.ReadSubExpr()); +  if (isOpenMPWorksharingDirective(D->getDirectiveKind())) { +    D->setIsLastIterVariable(Reader.ReadSubExpr()); +    D->setLowerBoundVariable(Reader.ReadSubExpr()); +    D->setUpperBoundVariable(Reader.ReadSubExpr()); +    D->setStrideVariable(Reader.ReadSubExpr()); +    D->setEnsureUpperBound(Reader.ReadSubExpr()); +    D->setNextLowerBound(Reader.ReadSubExpr()); +    D->setNextUpperBound(Reader.ReadSubExpr()); +  } +  SmallVector<Expr *, 4> Sub; +  unsigned CollapsedNum = D->getCollapsedNumber(); +  Sub.reserve(CollapsedNum); +  for (unsigned i = 0; i < CollapsedNum; ++i) +    Sub.push_back(Reader.ReadSubExpr()); +  D->setCounters(Sub); +  Sub.clear(); +  for (unsigned i = 0; i < CollapsedNum; ++i) +    Sub.push_back(Reader.ReadSubExpr()); +  D->setUpdates(Sub); +  Sub.clear(); +  for (unsigned i = 0; i < CollapsedNum; ++i) +    Sub.push_back(Reader.ReadSubExpr()); +  D->setFinals(Sub); +} +  void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) {    VisitStmt(D);    // The NumClauses field was read in ReadStmtFromStream. @@ -1944,17 +2035,15 @@ void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) {  }  void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) { -  VisitStmt(D); -  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream. -  Idx += 2; -  VisitOMPExecutableDirective(D); +  VisitOMPLoopDirective(D);  }  void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) { -  VisitStmt(D); -  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream. -  Idx += 2; -  VisitOMPExecutableDirective(D); +  VisitOMPLoopDirective(D); +} + +void ASTStmtReader::VisitOMPForSimdDirective(OMPForSimdDirective *D) { +  VisitOMPLoopDirective(D);  }  void ASTStmtReader::VisitOMPSectionsDirective(OMPSectionsDirective *D) { @@ -1988,10 +2077,12 @@ void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) {  }  void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) { -  VisitStmt(D); -  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream. -  Idx += 2; -  VisitOMPExecutableDirective(D); +  VisitOMPLoopDirective(D); +} + +void ASTStmtReader::VisitOMPParallelForSimdDirective( +    OMPParallelForSimdDirective *D) { +  VisitOMPLoopDirective(D);  }  void ASTStmtReader::VisitOMPParallelSectionsDirective( @@ -2031,6 +2122,35 @@ void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {    VisitOMPExecutableDirective(D);  } +void ASTStmtReader::VisitOMPOrderedDirective(OMPOrderedDirective *D) { +  VisitStmt(D); +  VisitOMPExecutableDirective(D); +} + +void ASTStmtReader::VisitOMPAtomicDirective(OMPAtomicDirective *D) { +  VisitStmt(D); +  // The NumClauses field was read in ReadStmtFromStream. +  ++Idx; +  VisitOMPExecutableDirective(D); +  D->setX(Reader.ReadSubExpr()); +  D->setV(Reader.ReadSubExpr()); +  D->setExpr(Reader.ReadSubExpr()); +} + +void ASTStmtReader::VisitOMPTargetDirective(OMPTargetDirective *D) { +  VisitStmt(D); +  // The NumClauses field was read in ReadStmtFromStream. +  ++Idx; +  VisitOMPExecutableDirective(D); +} + +void ASTStmtReader::VisitOMPTeamsDirective(OMPTeamsDirective *D) { +  VisitStmt(D); +  // The NumClauses field was read in ReadStmtFromStream. +  ++Idx; +  VisitOMPExecutableDirective(D); +} +  //===----------------------------------------------------------------------===//  // ASTReader Implementation  //===----------------------------------------------------------------------===// @@ -2529,6 +2649,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {        break;      } +    case STMT_OMP_FOR_SIMD_DIRECTIVE: { +      unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; +      unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; +      S = OMPForSimdDirective::CreateEmpty(Context, NumClauses, CollapsedNum, +                                           Empty); +      break; +    } +      case STMT_OMP_SECTIONS_DIRECTIVE:        S = OMPSectionsDirective::CreateEmpty(            Context, Record[ASTStmtReader::NumStmtFields], Empty); @@ -2559,6 +2687,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {        break;      } +    case STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE: { +      unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; +      unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1]; +      S = OMPParallelForSimdDirective::CreateEmpty(Context, NumClauses, +                                                   CollapsedNum, Empty); +      break; +    } +      case STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE:        S = OMPParallelSectionsDirective::CreateEmpty(            Context, Record[ASTStmtReader::NumStmtFields], Empty); @@ -2586,6 +2722,25 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {            Context, Record[ASTStmtReader::NumStmtFields], Empty);        break; +    case STMT_OMP_ORDERED_DIRECTIVE: +      S = OMPOrderedDirective::CreateEmpty(Context, Empty); +      break; + +    case STMT_OMP_ATOMIC_DIRECTIVE: +      S = OMPAtomicDirective::CreateEmpty( +          Context, Record[ASTStmtReader::NumStmtFields], Empty); +      break; + +    case STMT_OMP_TARGET_DIRECTIVE: +      S = OMPTargetDirective::CreateEmpty( +          Context, Record[ASTStmtReader::NumStmtFields], Empty); +      break; + +    case STMT_OMP_TEAMS_DIRECTIVE: +      S = OMPTeamsDirective::CreateEmpty( +          Context, Record[ASTStmtReader::NumStmtFields], Empty); +      break; +      case EXPR_CXX_OPERATOR_CALL:        S = new (Context) CXXOperatorCallExpr(Context, Empty);        break; @@ -2775,7 +2930,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {      case EXPR_MATERIALIZE_TEMPORARY:        S = new (Context) MaterializeTemporaryExpr(Empty);        break; -         + +    case EXPR_CXX_FOLD: +      S = new (Context) CXXFoldExpr(Empty); +      break; +      case EXPR_OPAQUE_VALUE:        S = new (Context) OpaqueValueExpr(Empty);        break; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 0f52a9fd0408..6c60d45503de 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -51,6 +51,7 @@  #include "llvm/Support/MemoryBuffer.h"  #include "llvm/Support/OnDiskHashTable.h"  #include "llvm/Support/Path.h" +#include "llvm/Support/Process.h"  #include <algorithm>  #include <cstdio>  #include <string.h> @@ -83,6 +84,8 @@ namespace {    public:      /// \brief Type code that corresponds to the record generated.      TypeCode Code; +    /// \brief Abbreviation to use for the record, if any. +    unsigned AbbrevToUse;      ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)        : Writer(Writer), Record(Record), Code(TYPE_EXT_QUAL) { } @@ -190,6 +193,9 @@ void ASTTypeWriter::VisitFunctionType(const FunctionType *T) {    // FIXME: need to stabilize encoding of calling convention...    Record.push_back(C.getCC());    Record.push_back(C.getProducesResult()); + +  if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult()) +    AbbrevToUse = 0;  }  void ASTTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { @@ -216,14 +222,21 @@ static void addExceptionSpec(ASTWriter &Writer, const FunctionProtoType *T,  void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {    VisitFunctionType(T); -  Record.push_back(T->getNumParams()); -  for (unsigned I = 0, N = T->getNumParams(); I != N; ++I) -    Writer.AddTypeRef(T->getParamType(I), Record); +    Record.push_back(T->isVariadic());    Record.push_back(T->hasTrailingReturn());    Record.push_back(T->getTypeQuals());    Record.push_back(static_cast<unsigned>(T->getRefQualifier()));    addExceptionSpec(Writer, T, Record); + +  Record.push_back(T->getNumParams()); +  for (unsigned I = 0, N = T->getNumParams(); I != N; ++I) +    Writer.AddTypeRef(T->getParamType(I), Record); + +  if (T->isVariadic() || T->hasTrailingReturn() || T->getTypeQuals() || +      T->getRefQualifier() || T->getExceptionSpecType() != EST_None) +    AbbrevToUse = 0; +    Code = TYPE_FUNCTION_PROTO;  } @@ -649,6 +662,40 @@ void TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) {    Writer.AddSourceLocation(TL.getRParenLoc(), Record);  } +void ASTWriter::WriteTypeAbbrevs() { +  using namespace llvm; + +  BitCodeAbbrev *Abv; + +  // Abbreviation for TYPE_EXT_QUAL +  Abv = new BitCodeAbbrev(); +  Abv->Add(BitCodeAbbrevOp(serialization::TYPE_EXT_QUAL)); +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Type +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3));   // Quals +  TypeExtQualAbbrev = Stream.EmitAbbrev(Abv); + +  // Abbreviation for TYPE_FUNCTION_PROTO +  Abv = new BitCodeAbbrev(); +  Abv->Add(BitCodeAbbrevOp(serialization::TYPE_FUNCTION_PROTO)); +  // FunctionType +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // ReturnType +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // NoReturn +  Abv->Add(BitCodeAbbrevOp(0));                         // HasRegParm +  Abv->Add(BitCodeAbbrevOp(0));                         // RegParm +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC +  Abv->Add(BitCodeAbbrevOp(0));                         // ProducesResult +  // FunctionProtoType +  Abv->Add(BitCodeAbbrevOp(0));                         // IsVariadic +  Abv->Add(BitCodeAbbrevOp(0));                         // HasTrailingReturn +  Abv->Add(BitCodeAbbrevOp(0));                         // TypeQuals +  Abv->Add(BitCodeAbbrevOp(0));                         // RefQualifier +  Abv->Add(BitCodeAbbrevOp(EST_None));                  // ExceptionSpec +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // NumParams +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Params +  TypeFunctionProtoAbbrev = Stream.EmitAbbrev(Abv); +} +  //===----------------------------------------------------------------------===//  // ASTWriter Implementation  //===----------------------------------------------------------------------===// @@ -684,6 +731,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,  #define RECORD(X) EmitRecordID(X, #X, Stream, Record)    RECORD(STMT_STOP);    RECORD(STMT_NULL_PTR); +  RECORD(STMT_REF_PTR);    RECORD(STMT_NULL);    RECORD(STMT_COMPOUND);    RECORD(STMT_CASE); @@ -711,6 +759,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,    RECORD(EXPR_STRING_LITERAL);    RECORD(EXPR_CHARACTER_LITERAL);    RECORD(EXPR_PAREN); +  RECORD(EXPR_PAREN_LIST);    RECORD(EXPR_UNARY_OPERATOR);    RECORD(EXPR_SIZEOF_ALIGN_OF);    RECORD(EXPR_ARRAY_SUBSCRIPT); @@ -752,8 +801,13 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,    RECORD(STMT_OBJC_AT_SYNCHRONIZED);    RECORD(STMT_OBJC_AT_THROW);    RECORD(EXPR_OBJC_BOOL_LITERAL); +  RECORD(STMT_CXX_CATCH); +  RECORD(STMT_CXX_TRY); +  RECORD(STMT_CXX_FOR_RANGE);    RECORD(EXPR_CXX_OPERATOR_CALL); +  RECORD(EXPR_CXX_MEMBER_CALL);    RECORD(EXPR_CXX_CONSTRUCT); +  RECORD(EXPR_CXX_TEMPORARY_OBJECT);    RECORD(EXPR_CXX_STATIC_CAST);    RECORD(EXPR_CXX_DYNAMIC_CAST);    RECORD(EXPR_CXX_REINTERPRET_CAST); @@ -765,11 +819,10 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,    RECORD(EXPR_CXX_NULL_PTR_LITERAL);    RECORD(EXPR_CXX_TYPEID_EXPR);    RECORD(EXPR_CXX_TYPEID_TYPE); -  RECORD(EXPR_CXX_UUIDOF_EXPR); -  RECORD(EXPR_CXX_UUIDOF_TYPE);    RECORD(EXPR_CXX_THIS);    RECORD(EXPR_CXX_THROW);    RECORD(EXPR_CXX_DEFAULT_ARG); +  RECORD(EXPR_CXX_DEFAULT_INIT);    RECORD(EXPR_CXX_BIND_TEMPORARY);    RECORD(EXPR_CXX_SCALAR_VALUE_INIT);    RECORD(EXPR_CXX_NEW); @@ -781,12 +834,22 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,    RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT);    RECORD(EXPR_CXX_UNRESOLVED_MEMBER);    RECORD(EXPR_CXX_UNRESOLVED_LOOKUP); +  RECORD(EXPR_CXX_EXPRESSION_TRAIT);    RECORD(EXPR_CXX_NOEXCEPT);    RECORD(EXPR_OPAQUE_VALUE); +  RECORD(EXPR_BINARY_CONDITIONAL_OPERATOR); +  RECORD(EXPR_TYPE_TRAIT); +  RECORD(EXPR_ARRAY_TYPE_TRAIT);    RECORD(EXPR_PACK_EXPANSION);    RECORD(EXPR_SIZEOF_PACK); +  RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM);    RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK); +  RECORD(EXPR_FUNCTION_PARM_PACK); +  RECORD(EXPR_MATERIALIZE_TEMPORARY);    RECORD(EXPR_CUDA_KERNEL_CALL); +  RECORD(EXPR_CXX_UUIDOF_EXPR); +  RECORD(EXPR_CXX_UUIDOF_TYPE); +  RECORD(EXPR_LAMBDA);  #undef RECORD  } @@ -800,6 +863,7 @@ void ASTWriter::WriteBlockInfoBlock() {    // Control Block.    BLOCK(CONTROL_BLOCK);    RECORD(METADATA); +  RECORD(SIGNATURE);    RECORD(MODULE_NAME);    RECORD(MODULE_MAP_FILE);    RECORD(IMPORTS); @@ -895,15 +959,14 @@ void ASTWriter::WriteBlockInfoBlock() {    RECORD(TYPE_VARIABLE_ARRAY);    RECORD(TYPE_VECTOR);    RECORD(TYPE_EXT_VECTOR); -  RECORD(TYPE_FUNCTION_PROTO);    RECORD(TYPE_FUNCTION_NO_PROTO); +  RECORD(TYPE_FUNCTION_PROTO);    RECORD(TYPE_TYPEDEF);    RECORD(TYPE_TYPEOF_EXPR);    RECORD(TYPE_TYPEOF);    RECORD(TYPE_RECORD);    RECORD(TYPE_ENUM);    RECORD(TYPE_OBJC_INTERFACE); -  RECORD(TYPE_OBJC_OBJECT);    RECORD(TYPE_OBJC_OBJECT_POINTER);    RECORD(TYPE_DECLTYPE);    RECORD(TYPE_ELABORATED); @@ -920,8 +983,13 @@ void ASTWriter::WriteBlockInfoBlock() {    RECORD(TYPE_PACK_EXPANSION);    RECORD(TYPE_ATTRIBUTED);    RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK); +  RECORD(TYPE_AUTO); +  RECORD(TYPE_UNARY_TRANSFORM);    RECORD(TYPE_ATOMIC); +  RECORD(TYPE_DECAYED); +  RECORD(TYPE_ADJUSTED);    RECORD(DECL_TYPEDEF); +  RECORD(DECL_TYPEALIAS);    RECORD(DECL_ENUM);    RECORD(DECL_RECORD);    RECORD(DECL_ENUM_CONSTANT); @@ -990,42 +1058,76 @@ void ASTWriter::WriteBlockInfoBlock() {    Stream.ExitBlock();  } +/// \brief Prepares a path for being written to an AST file by converting it +/// to an absolute path and removing nested './'s. +/// +/// \return \c true if the path was changed. +bool cleanPathForOutput(FileManager &FileMgr, SmallVectorImpl<char> &Path) { +  bool Changed = false; + +  if (!llvm::sys::path::is_absolute(StringRef(Path.data(), Path.size()))) { +    llvm::sys::fs::make_absolute(Path); +    Changed = true; +  } + +  return Changed | FileMgr.removeDotPaths(Path); +} +  /// \brief Adjusts the given filename to only write out the portion of the  /// filename that is not part of the system root directory.  ///  /// \param Filename the file name to adjust.  /// -/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and -/// the returned filename will be adjusted by this system root. +/// \param BaseDir When non-NULL, the PCH file is a relocatable AST file and +/// the returned filename will be adjusted by this root directory.  ///  /// \returns either the original filename (if it needs no adjustment) or the  /// adjusted filename (which points into the @p Filename parameter).  static const char * -adjustFilenameForRelocatablePCH(const char *Filename, StringRef isysroot) { +adjustFilenameForRelocatableAST(const char *Filename, StringRef BaseDir) {    assert(Filename && "No file name to adjust?"); -  if (isysroot.empty()) +  if (BaseDir.empty())      return Filename;    // Verify that the filename and the system root have the same prefix.    unsigned Pos = 0; -  for (; Filename[Pos] && Pos < isysroot.size(); ++Pos) -    if (Filename[Pos] != isysroot[Pos]) +  for (; Filename[Pos] && Pos < BaseDir.size(); ++Pos) +    if (Filename[Pos] != BaseDir[Pos])        return Filename; // Prefixes don't match.    // We hit the end of the filename before we hit the end of the system root.    if (!Filename[Pos])      return Filename; -  // If the file name has a '/' at the current position, skip over the '/'. -  // We distinguish sysroot-based includes from absolute includes by the -  // absence of '/' at the beginning of sysroot-based includes. -  if (Filename[Pos] == '/') +  // If there's not a path separator at the end of the base directory nor +  // immediately after it, then this isn't within the base directory. +  if (!llvm::sys::path::is_separator(Filename[Pos])) { +    if (!llvm::sys::path::is_separator(BaseDir.back())) +      return Filename; +  } else { +    // If the file name has a '/' at the current position, skip over the '/'. +    // We distinguish relative paths from absolute paths by the +    // absence of '/' at the beginning of relative paths. +    // +    // FIXME: This is wrong. We distinguish them by asking if the path is +    // absolute, which isn't the same thing. And there might be multiple '/'s +    // in a row. Use a better mechanism to indicate whether we have emitted an +    // absolute or relative path.      ++Pos; +  }    return Filename + Pos;  } +static ASTFileSignature getSignature() { +  while (1) { +    if (ASTFileSignature S = llvm::sys::Process::GetRandomNumber()) +      return S; +    // Rely on GetRandomNumber to eventually return non-zero... +  } +} +  /// \brief Write the control block.  void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,                                    StringRef isysroot, @@ -1050,13 +1152,20 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,    Record.push_back(VERSION_MINOR);    Record.push_back(CLANG_VERSION_MAJOR);    Record.push_back(CLANG_VERSION_MINOR); +  assert((!WritingModule || isysroot.empty()) && +         "writing module as a relocatable PCH?");    Record.push_back(!isysroot.empty());    Record.push_back(ASTHasCompilerErrors);    Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,                              getClangFullRepositoryVersion()); -  // Module name +  // Signature +  Record.clear(); +  Record.push_back(getSignature()); +  Stream.EmitRecord(SIGNATURE, Record); +    if (WritingModule) { +    // Module name      BitCodeAbbrev *Abbrev = new BitCodeAbbrev();      Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));      Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name @@ -1066,19 +1175,46 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,      Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);    } -  // Module map file -  if (WritingModule) { +  if (WritingModule && WritingModule->Directory) { +    // Module directory.      BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); -    Abbrev->Add(BitCodeAbbrevOp(MODULE_MAP_FILE)); -    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename +    Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY)); +    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory      unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev); - -    assert(WritingModule->ModuleMap && "missing module map"); -    SmallString<128> ModuleMap(WritingModule->ModuleMap->getName()); -    llvm::sys::fs::make_absolute(ModuleMap);      RecordData Record; -    Record.push_back(MODULE_MAP_FILE); -    Stream.EmitRecordWithBlob(AbbrevCode, Record, ModuleMap.str()); +    Record.push_back(MODULE_DIRECTORY); + +    SmallString<128> BaseDir(WritingModule->Directory->getName()); +    cleanPathForOutput(Context.getSourceManager().getFileManager(), BaseDir); +    Stream.EmitRecordWithBlob(AbbrevCode, Record, BaseDir); + +    // Write out all other paths relative to the base directory if possible. +    BaseDirectory.assign(BaseDir.begin(), BaseDir.end()); +  } else if (!isysroot.empty()) { +    // Write out paths relative to the sysroot if possible. +    BaseDirectory = isysroot; +  } + +  // Module map file +  if (WritingModule) { +    Record.clear(); + +    auto &Map = PP.getHeaderSearchInfo().getModuleMap(); + +    // Primary module map file. +    AddPath(Map.getModuleMapFileForUniquing(WritingModule)->getName(), Record); + +    // Additional module map files. +    if (auto *AdditionalModMaps = +            Map.getAdditionalModuleMapFiles(WritingModule)) { +      Record.push_back(AdditionalModMaps->size()); +      for (const FileEntry *F : *AdditionalModMaps) +        AddPath(F->getName(), Record); +    } else { +      Record.push_back(0); +    } + +    Stream.EmitRecord(MODULE_MAP_FILE, Record);    }    // Imports @@ -1096,9 +1232,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,        AddSourceLocation((*M)->ImportLoc, Record);        Record.push_back((*M)->File->getSize());        Record.push_back((*M)->File->getModificationTime()); -      const std::string &FileName = (*M)->FileName; -      Record.push_back(FileName.size()); -      Record.append(FileName.begin(), FileName.end()); +      Record.push_back((*M)->Signature); +      AddPath((*M)->FileName, Record);      }      Stream.EmitRecord(IMPORTS, Record);    } @@ -1110,8 +1245,9 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,    Record.push_back(LangOpts.Name);  #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \    Record.push_back(static_cast<unsigned>(LangOpts.get##Name())); -#include "clang/Basic/LangOptions.def"   -#define SANITIZER(NAME, ID) Record.push_back(LangOpts.Sanitize.ID); +#include "clang/Basic/LangOptions.def" +#define SANITIZER(NAME, ID)                                                    \ +  Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));  #include "clang/Basic/Sanitizers.def"    Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind()); @@ -1245,17 +1381,10 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,      FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name      unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev); -    SmallString<128> MainFilePath(MainFile->getName()); - -    llvm::sys::fs::make_absolute(MainFilePath); - -    const char *MainFileNameStr = MainFilePath.c_str(); -    MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, -                                                      isysroot);      Record.clear();      Record.push_back(ORIGINAL_FILE);      Record.push_back(SM.getMainFileID().getOpaqueValue()); -    Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); +    EmitRecordWithPath(FileAbbrevCode, Record, MainFile->getName());    }    Record.clear(); @@ -1281,7 +1410,6 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,    WriteInputFiles(Context.SourceMgr,                    PP.getHeaderSearchInfo().getHeaderSearchOpts(), -                  isysroot,                    PP.getLangOpts().Modules);    Stream.ExitBlock();  } @@ -1297,7 +1425,6 @@ namespace  {  void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,                                  HeaderSearchOptions &HSOpts, -                                StringRef isysroot,                                  bool Modules) {    using namespace llvm;    Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4); @@ -1368,23 +1495,8 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,      // Whether this file was overridden.      Record.push_back(Entry.BufferOverridden); -    // Turn the file name into an absolute path, if it isn't already. -    const char *Filename = Entry.File->getName(); -    SmallString<128> FilePath(Filename); -     -    // Ask the file manager to fixup the relative path for us. This will  -    // honor the working directory. -    SourceMgr.getFileManager().FixupRelativePath(FilePath); -     -    // FIXME: This call to make_absolute shouldn't be necessary, the -    // call to FixupRelativePath should always return an absolute path. -    llvm::sys::fs::make_absolute(FilePath); -    Filename = FilePath.c_str(); -     -    Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); - -    Stream.EmitRecordWithBlob(IFAbbrevCode, Record, Filename); -  }   +    EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName()); +  }    Stream.ExitBlock(); @@ -1494,6 +1606,9 @@ namespace {        // The hash is based only on size/time of the file, so that the reader can        // match even when symlinking or excess path elements ("foo/../", "../")        // change the form of the name. However, complete path is still the key. +      // +      // FIXME: Using the mtime here will cause problems for explicit module +      // imports.        return llvm::hash_combine(key.FE->getSize(),                                  key.FE->getModificationTime());      } @@ -1574,7 +1689,7 @@ namespace {  /// \brief Write the header search block for the list of files that   ///  /// \param HS The header search structure to save. -void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) { +void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {    SmallVector<const FileEntry *, 16> FilesByUID;    HS.getFileMgr().GetUniqueIDMapping(FilesByUID); @@ -1598,17 +1713,16 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) {          (HFI.isModuleHeader && !HFI.isCompilingModuleHeader))        continue; -    // Turn the file name into an absolute path, if it isn't already. +    // Massage the file path into an appropriate form.      const char *Filename = File->getName(); -    Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); -       -    // If we performed any translation on the file name at all, we need to -    // save this string, since the generator will refer to it later. -    if (Filename != File->getName()) { -      Filename = strdup(Filename); +    SmallString<128> FilenameTmp(Filename); +    if (PreparePathForOutput(FilenameTmp)) { +      // If we performed any translation on the file name at all, we need to +      // save this string, since the generator will refer to it later. +      Filename = strdup(FilenameTmp.c_str());        SavedStrings.push_back(Filename);      } -     +      HeaderFileInfoTrait::key_type key = { File, Filename };      Generator.insert(key, HFI, GeneratorTrait);      ++NumHeaderSearchEntries; @@ -1658,8 +1772,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) {  /// errors), we probably won't have to create file entries for any of  /// the files in the AST.  void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, -                                        const Preprocessor &PP, -                                        StringRef isysroot) { +                                        const Preprocessor &PP) {    RecordData Record;    // Enter the source manager block. @@ -1808,17 +1921,10 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,      LineTableInfo &LineTable = SourceMgr.getLineTable();      Record.clear(); -    // Emit the file names +    // Emit the file names.      Record.push_back(LineTable.getNumFilenames()); -    for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) { -      // Emit the file name -      const char *Filename = LineTable.getFilename(I); -      Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); -      unsigned FilenameLen = Filename? strlen(Filename) : 0; -      Record.push_back(FilenameLen); -      if (FilenameLen) -        Record.insert(Record.end(), Filename, Filename + FilenameLen); -    } +    for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) +      AddPath(LineTable.getFilename(I), Record);      // Emit the line entries      for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end(); @@ -1904,10 +2010,8 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,    if (IsModule) {      // Re-export any imported directives. -    // FIXME: Also ensure we re-export imported #undef directives. -    if (auto *DMD = dyn_cast<DefMacroDirective>(MD)) -      if (DMD->isImported()) -        return false; +    if (MD->isImported()) +      return false;      SourceLocation Loc = MD->getLocation();      if (Loc.isInvalid()) @@ -1986,16 +2090,24 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {        AddSourceLocation(MD->getLocation(), Record);        Record.push_back(MD->getKind()); -      if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) { +      if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {          MacroID InfoID = getMacroRef(DefMD->getInfo(), Name);          Record.push_back(InfoID); -        Record.push_back(DefMD->isImported()); +        Record.push_back(DefMD->getOwningModuleID());          Record.push_back(DefMD->isAmbiguous()); - -      } else if (VisibilityMacroDirective * -                   VisMD = dyn_cast<VisibilityMacroDirective>(MD)) { +      } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) { +        Record.push_back(UndefMD->getOwningModuleID()); +      } else { +        auto *VisMD = 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); +      }      }      if (Record.empty())        continue; @@ -2271,7 +2383,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {    }    // Enter the submodule description block. -  Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE); +  Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5);    // Write the abbreviations needed for the submodules block.    using namespace llvm; @@ -2322,11 +2434,21 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {    unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(Abbrev);    Abbrev = new BitCodeAbbrev(); +  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_TEXTUAL_HEADER)); +  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name +  unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev); + +  Abbrev = new BitCodeAbbrev();    Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_HEADER));    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name    unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(Abbrev);    Abbrev = new BitCodeAbbrev(); +  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER)); +  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name +  unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev); + +  Abbrev = new BitCodeAbbrev();    Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY));    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));     // Name @@ -2398,35 +2520,34 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {        Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,                                   UmbrellaDir->getName());            } -     +      // Emit the headers. -    for (unsigned I = 0, N = Mod->NormalHeaders.size(); I != N; ++I) { -      Record.clear(); -      Record.push_back(SUBMODULE_HEADER); -      Stream.EmitRecordWithBlob(HeaderAbbrev, Record,  -                                Mod->NormalHeaders[I]->getName()); -    } -    // Emit the excluded headers. -    for (unsigned I = 0, N = Mod->ExcludedHeaders.size(); I != N; ++I) { -      Record.clear(); -      Record.push_back(SUBMODULE_EXCLUDED_HEADER); -      Stream.EmitRecordWithBlob(ExcludedHeaderAbbrev, Record,  -                                Mod->ExcludedHeaders[I]->getName()); -    } -    // Emit the private headers. -    for (unsigned I = 0, N = Mod->PrivateHeaders.size(); I != N; ++I) { +    struct { +      unsigned RecordKind; +      unsigned Abbrev; +      Module::HeaderKind HeaderKind; +    } HeaderLists[] = { +      {SUBMODULE_HEADER, HeaderAbbrev, Module::HK_Normal}, +      {SUBMODULE_TEXTUAL_HEADER, TextualHeaderAbbrev, Module::HK_Textual}, +      {SUBMODULE_PRIVATE_HEADER, PrivateHeaderAbbrev, Module::HK_Private}, +      {SUBMODULE_PRIVATE_TEXTUAL_HEADER, PrivateTextualHeaderAbbrev, +        Module::HK_PrivateTextual}, +      {SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Module::HK_Excluded} +    }; +    for (auto &HL : HeaderLists) {        Record.clear(); -      Record.push_back(SUBMODULE_PRIVATE_HEADER); -      Stream.EmitRecordWithBlob(PrivateHeaderAbbrev, Record,  -                                Mod->PrivateHeaders[I]->getName()); +      Record.push_back(HL.RecordKind); +      for (auto &H : Mod->Headers[HL.HeaderKind]) +        Stream.EmitRecordWithBlob(HL.Abbrev, Record, H.NameAsWritten);      } -    ArrayRef<const FileEntry *> -      TopHeaders = Mod->getTopHeaders(PP->getFileManager()); -    for (unsigned I = 0, N = TopHeaders.size(); I != N; ++I) { + +    // Emit the top headers. +    { +      auto TopHeaders = Mod->getTopHeaders(PP->getFileManager());        Record.clear();        Record.push_back(SUBMODULE_TOPHEADER); -      Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, -                                TopHeaders[I]->getName()); +      for (auto *H : TopHeaders) +        Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, H->getName());      }      // Emit the imports.  @@ -2434,7 +2555,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {        Record.clear();        for (unsigned I = 0, N = Mod->Imports.size(); I != N; ++I) {          unsigned ImportedID = getSubmoduleID(Mod->Imports[I]); -        assert(ImportedID && "Unknown submodule!");                                            +        assert(ImportedID && "Unknown submodule!");          Record.push_back(ImportedID);        }        Stream.EmitRecord(SUBMODULE_IMPORTS, Record); @@ -2611,12 +2732,14 @@ void ASTWriter::WriteType(QualType T) {    // Emit the type's representation.    ASTTypeWriter W(*this, Record); +  W.AbbrevToUse = 0;    if (T.hasLocalNonFastQualifiers()) {      Qualifiers Qs = T.getLocalQualifiers();      AddTypeRef(T.getLocalUnqualifiedType(), Record);      Record.push_back(Qs.getAsOpaqueValue());      W.Code = TYPE_EXT_QUAL; +    W.AbbrevToUse = TypeExtQualAbbrev;    } else {      switch (T->getTypeClass()) {        // For all of the concrete, non-dependent types, call the @@ -2629,7 +2752,7 @@ void ASTWriter::WriteType(QualType T) {    }    // Emit the serialized record. -  Stream.EmitRecord(W.Code, Record); +  Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);    // Flush any expressions that were written as part of this type.    FlushStmts(); @@ -2772,11 +2895,11 @@ public:      unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts      for (const ObjCMethodList *Method = &Methods.Instance; Method;           Method = Method->getNext()) -      if (Method->Method) +      if (Method->getMethod())          DataLen += 4;      for (const ObjCMethodList *Method = &Methods.Factory; Method;           Method = Method->getNext()) -      if (Method->Method) +      if (Method->getMethod())          DataLen += 4;      LE.write<uint16_t>(DataLen);      return std::make_pair(KeyLen, DataLen); @@ -2806,32 +2929,39 @@ public:      unsigned NumInstanceMethods = 0;      for (const ObjCMethodList *Method = &Methods.Instance; Method;           Method = Method->getNext()) -      if (Method->Method) +      if (Method->getMethod())          ++NumInstanceMethods;      unsigned NumFactoryMethods = 0;      for (const ObjCMethodList *Method = &Methods.Factory; Method;           Method = Method->getNext()) -      if (Method->Method) +      if (Method->getMethod())          ++NumFactoryMethods;      unsigned InstanceBits = Methods.Instance.getBits();      assert(InstanceBits < 4); -    unsigned NumInstanceMethodsAndBits = -        (NumInstanceMethods << 2) | InstanceBits; +    unsigned InstanceHasMoreThanOneDeclBit = +        Methods.Instance.hasMoreThanOneDecl(); +    unsigned FullInstanceBits = (NumInstanceMethods << 3) | +                                (InstanceHasMoreThanOneDeclBit << 2) | +                                InstanceBits;      unsigned FactoryBits = Methods.Factory.getBits();      assert(FactoryBits < 4); -    unsigned NumFactoryMethodsAndBits = (NumFactoryMethods << 2) | FactoryBits; -    LE.write<uint16_t>(NumInstanceMethodsAndBits); -    LE.write<uint16_t>(NumFactoryMethodsAndBits); +    unsigned FactoryHasMoreThanOneDeclBit = +        Methods.Factory.hasMoreThanOneDecl(); +    unsigned FullFactoryBits = (NumFactoryMethods << 3) | +                               (FactoryHasMoreThanOneDeclBit << 2) | +                               FactoryBits; +    LE.write<uint16_t>(FullInstanceBits); +    LE.write<uint16_t>(FullFactoryBits);      for (const ObjCMethodList *Method = &Methods.Instance; Method;           Method = Method->getNext()) -      if (Method->Method) -        LE.write<uint32_t>(Writer.getDeclID(Method->Method)); +      if (Method->getMethod()) +        LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));      for (const ObjCMethodList *Method = &Methods.Factory; Method;           Method = Method->getNext()) -      if (Method->Method) -        LE.write<uint32_t>(Writer.getDeclID(Method->Method)); +      if (Method->getMethod()) +        LE.write<uint32_t>(Writer.getDeclID(Method->getMethod()));      assert(Out.tell() - Start == DataLen && "Data length is wrong");    } @@ -2877,19 +3007,19 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {        if (Chain && I->second < FirstSelectorID) {          // Selector already exists. Did it change?          bool changed = false; -        for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method; -             M = M->getNext()) { -          if (!M->Method->isFromASTFile()) +        for (ObjCMethodList *M = &Data.Instance; +             !changed && M && M->getMethod(); M = M->getNext()) { +          if (!M->getMethod()->isFromASTFile())              changed = true;          } -        for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method; +        for (ObjCMethodList *M = &Data.Factory; !changed && M && M->getMethod();               M = M->getNext()) { -          if (!M->Method->isFromASTFile()) +          if (!M->getMethod()->isFromASTFile())              changed = true;          }          if (!changed)            continue; -      } else if (Data.Instance.Method || Data.Factory.Method) { +      } else if (Data.Instance.getMethod() || Data.Factory.getMethod()) {          // A new method pool entry.          ++NumTableEntries;        } @@ -2995,115 +3125,140 @@ class ASTIdentifierTableTrait {      if (Macro || (Macro = PP.getMacroDirectiveHistory(II))) {        if (!IsModule)          return !shouldIgnoreMacro(Macro, IsModule, PP); -      SubmoduleID ModID; -      if (getFirstPublicSubmoduleMacro(Macro, ModID)) + +      MacroState State; +      if (getFirstPublicSubmoduleMacro(Macro, State))          return true;      }      return false;    } -  typedef llvm::SmallVectorImpl<SubmoduleID> OverriddenList; +  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, SubmoduleID &ModID) { -    ModID = 0; -    llvm::SmallVector<SubmoduleID, 1> Overridden; -    if (MacroDirective *NextMD = getPublicSubmoduleMacro(MD, ModID, Overridden)) -      if (!shouldIgnoreMacro(NextMD, IsModule, PP)) -        return NextMD; +  getFirstPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) { +    if (MacroDirective *NextMD = getPublicSubmoduleMacro(MD, State)) +      return NextMD;      return nullptr;    }    MacroDirective * -  getNextPublicSubmoduleMacro(MacroDirective *MD, SubmoduleID &ModID, -                              OverriddenList &Overridden) { +  getNextPublicSubmoduleMacro(MacroDirective *MD, MacroState &State) {      if (MacroDirective *NextMD = -            getPublicSubmoduleMacro(MD->getPrevious(), ModID, Overridden)) -      if (!shouldIgnoreMacro(NextMD, IsModule, PP)) -        return NextMD; +            getPublicSubmoduleMacro(MD->getPrevious(), State)) +      return NextMD;      return nullptr;    } -  /// \brief Traverses the macro directives history and returns the latest -  /// public macro definition or undefinition that is not in ModID. +  /// \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. -  /// ModID is updated to the module containing the returned directive. -  /// -  /// FIXME: This process breaks down if a module defines a macro, imports -  ///        another submodule that changes the macro, then changes the -  ///        macro again itself.    MacroDirective *getPublicSubmoduleMacro(MacroDirective *MD, -                                          SubmoduleID &ModID, -                                          OverriddenList &Overridden) { -    Overridden.clear(); +                                          MacroState &State) {      if (!MD)        return nullptr; -    SubmoduleID OrigModID = ModID;      Optional<bool> IsPublic;      for (; MD; MD = MD->getPrevious()) { -      SubmoduleID ThisModID = getSubmoduleID(MD); -      if (ThisModID == 0) { -        IsPublic = Optional<bool>(); - -        // If we have no directive location, this macro was installed when -        // finalizing the ASTReader. -        if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) -          if (DefMD->getInfo()->getOwningModuleID()) -            return MD; -        // Skip imports that only produce #undefs for now. -        // FIXME: We should still re-export them! +      // 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;        } -      if (ThisModID != ModID) { -        ModID = ThisModID; -        IsPublic = Optional<bool>(); -      } +    } + +    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. -      // FIXME: This should only apply to macros defined in OrigModID. -      // We can't do that currently, because a #include of a different submodule -      // of the same module just leaks through macros instead of providing new -      // DefMacroDirectives for them. -      if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) { -        // Figure out which submodule the macro was originally defined within. -        SubmoduleID SourceID = DefMD->getInfo()->getOwningModuleID(); -        if (!SourceID) { -          SourceLocation DefLoc = DefMD->getInfo()->getDefinitionLoc(); -          if (DefLoc == MD->getLocation()) -            SourceID = ThisModID; -          else -            SourceID = Writer.inferSubmoduleIDFromLocation(DefLoc); +      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());          } -        if (OrigModID && SourceID != OrigModID) -          Overridden.push_back(SourceID);        } -      // We are looking for a definition in a different submodule than the one -      // that we started with. If a submodule has re-definitions of the same -      // macro, only the last definition will be used as the "exported" one. -      if (ModID == OrigModID) -        continue; - -      // The latest visibility directive for a name in a submodule affects all -      // the directives that come before it. -      if (VisibilityMacroDirective *VisMD = -              dyn_cast<VisibilityMacroDirective>(MD)) { -        if (!IsPublic.hasValue()) -          IsPublic = VisMD->isPublic(); -      } else if (!IsPublic.hasValue() || IsPublic.getValue()) { -        // FIXME: If we find an imported macro, we should include its list of -        // overrides in our export. -        return MD; +      // 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;        }      } -    return nullptr; +    std::sort(ScratchSpace.begin(), ScratchSpace.end()); +    ScratchSpace.erase(std::unique(ScratchSpace.begin(), ScratchSpace.end()), +                       ScratchSpace.end()); +    return ScratchSpace;    }    SubmoduleID getSubmoduleID(MacroDirective *MD) { @@ -3139,27 +3294,23 @@ public:        if (hadMacroDefinition(II, Macro)) {          DataLen += 4; // MacroDirectives offset.          if (IsModule) { -          SubmoduleID ModID; -          llvm::SmallVector<SubmoduleID, 4> Overridden; -          for (MacroDirective * -                 MD = getFirstPublicSubmoduleMacro(Macro, ModID); -                 MD; MD = getNextPublicSubmoduleMacro(MD, ModID, Overridden)) { -            // Previous macro's overrides. -            if (!Overridden.empty()) -              DataLen += 4 * (1 + Overridden.size()); +          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);            } -          // Previous macro's overrides. -          if (!Overridden.empty()) -            DataLen += 4 * (1 + Overridden.size()); -          DataLen += 4; +          DataLen += 4; // 0 terminator.          }        }        for (IdentifierResolver::iterator D = IdResolver.begin(II),                                       DEnd = IdResolver.end();             D != DEnd; ++D) -        DataLen += sizeof(DeclID); +        DataLen += 4;      }      using namespace llvm::support;      endian::Writer<little> LE(Out); @@ -3186,8 +3337,10 @@ public:        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) +      for (unsigned I = 0, N = Overridden.size(); I != N; ++I) { +        assert(Overridden[I] && "zero module ID for override");          LE.write<uint32_t>(Overridden[I]); +      }      }    } @@ -3219,24 +3372,28 @@ public:        LE.write<uint32_t>(Writer.getMacroDirectivesOffset(II));        if (IsModule) {          // Write the IDs of macros coming from different submodules. -        SubmoduleID ModID; -        llvm::SmallVector<SubmoduleID, 4> Overridden; -        for (MacroDirective * -               MD = getFirstPublicSubmoduleMacro(Macro, ModID); -               MD; MD = getNextPublicSubmoduleMacro(MD, ModID, Overridden)) { -          MacroID InfoID = 0; -          emitMacroOverrides(Out, Overridden); +        MacroState State; +        SmallVector<SubmoduleID, 16> Scratch; +        for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, State); +             MD; MD = getNextPublicSubmoduleMacro(MD, State)) {            if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) { -            InfoID = Writer.getMacroID(DefMD->getInfo()); +            // 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 { -            assert(isa<UndefMacroDirective>(MD)); -            LE.write<uint32_t>((ModID << 1) | 1); +            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));          } -        emitMacroOverrides(Out, Overridden); -        LE.write<uint32_t>(0); +        LE.write<uint32_t>(0xdeadbeef);        }      } @@ -3367,6 +3524,31 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,  // 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 { @@ -3484,7 +3666,7 @@ 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(*I)); +      LE.write<uint32_t>(Writer.GetDeclRef(getDeclForLocalLookup(*I)));      assert(Out.tell() - Start == DataLen && "Data length is wrong");    } @@ -3524,13 +3706,13 @@ static void visitLocalLookupResults(const DeclContext *ConstDC,  }  void ASTWriter::AddUpdatedDeclContext(const DeclContext *DC) { -  if (UpdatedDeclContexts.insert(DC) && WritingAST) { +  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(Decl); +        GetDeclRef(getDeclForLocalLookup(Decl));      });    }  } @@ -3646,8 +3828,6 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,    Record.push_back(BucketOffset);    Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,                              LookupTable.str()); - -  Stream.EmitRecord(DECL_CONTEXT_VISIBLE, Record);    ++NumVisibleDeclContexts;    return Offset;  } @@ -3729,6 +3909,8 @@ void ASTWriter::WriteRedeclarations() {            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));      } @@ -3914,6 +4096,37 @@ void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) {    Record.insert(Record.end(), Str.begin(), Str.end());  } +bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &Path) { +  assert(Context && "should have context when outputting path"); + +  bool Changed = +      cleanPathForOutput(Context->getSourceManager().getFileManager(), Path); + +  // Remove a prefix to make the path relative, if relevant. +  const char *PathBegin = Path.data(); +  const char *PathPtr = +      adjustFilenameForRelocatableAST(PathBegin, BaseDirectory); +  if (PathPtr != PathBegin) { +    Path.erase(Path.begin(), Path.begin() + (PathPtr - PathBegin)); +    Changed = true; +  } + +  return Changed; +} + +void ASTWriter::AddPath(StringRef Path, RecordDataImpl &Record) { +  SmallString<128> FilePath(Path); +  PreparePathForOutput(FilePath); +  AddString(FilePath, Record); +} + +void ASTWriter::EmitRecordWithPath(unsigned Abbrev, RecordDataImpl &Record, +                                   StringRef Path) { +  SmallString<128> FilePath(Path); +  PreparePathForOutput(FilePath); +  Stream.EmitRecordWithBlob(Abbrev, Record, FilePath); +} +  void ASTWriter::AddVersionTuple(const VersionTuple &Version,                                  RecordDataImpl &Record) {    Record.push_back(Version.getMajor()); @@ -3950,29 +4163,26 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {  }  ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) -  : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr), -    WritingModule(nullptr), WritingAST(false), DoneWritingDeclsAndTypes(false), -    ASTHasCompilerErrors(false), -    FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID), -    FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), -    FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID), -    FirstMacroID(NUM_PREDEF_MACRO_IDS), NextMacroID(FirstMacroID), -    FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS),  -    NextSubmoduleID(FirstSubmoduleID), -    FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID), -    CollectedStmts(&StmtsToEmit), -    NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), -    NumVisibleDeclContexts(0), -    NextCXXBaseSpecifiersID(1), -    DeclParmVarAbbrev(0), DeclContextLexicalAbbrev(0), -    DeclContextVisibleLookupAbbrev(0), UpdateVisibleAbbrev(0), -    DeclRefExprAbbrev(0), CharacterLiteralAbbrev(0), -    DeclRecordAbbrev(0), IntegerLiteralAbbrev(0), -    DeclTypedefAbbrev(0), -    DeclVarAbbrev(0), DeclFieldAbbrev(0), -    DeclEnumAbbrev(0), DeclObjCIvarAbbrev(0) -{ -} +    : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr), +      WritingModule(nullptr), WritingAST(false), +      DoneWritingDeclsAndTypes(false), ASTHasCompilerErrors(false), +      FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID), +      FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), +      FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID), +      FirstMacroID(NUM_PREDEF_MACRO_IDS), NextMacroID(FirstMacroID), +      FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS), +      NextSubmoduleID(FirstSubmoduleID), +      FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID), +      CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), +      NumLexicalDeclContexts(0), NumVisibleDeclContexts(0), +      NextCXXBaseSpecifiersID(1), TypeExtQualAbbrev(0), +      TypeFunctionProtoAbbrev(0), DeclParmVarAbbrev(0), +      DeclContextLexicalAbbrev(0), DeclContextVisibleLookupAbbrev(0), +      UpdateVisibleAbbrev(0), DeclRecordAbbrev(0), DeclTypedefAbbrev(0), +      DeclVarAbbrev(0), DeclFieldAbbrev(0), DeclEnumAbbrev(0), +      DeclObjCIvarAbbrev(0), DeclCXXMethodAbbrev(0), DeclRefExprAbbrev(0), +      CharacterLiteralAbbrev(0), IntegerLiteralAbbrev(0), +      ExprImplicitCastAbbrev(0) {}  ASTWriter::~ASTWriter() {    llvm::DeleteContainerSeconds(FileDeclIDs); @@ -4001,6 +4211,7 @@ void ASTWriter::WriteAST(Sema &SemaRef,    Context = nullptr;    PP = nullptr;    this->WritingModule = nullptr; +  this->BaseDirectory.clear();    WritingAST = false;  } @@ -4150,6 +4361,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,      }    } +  // Build a record containing all of the UnusedLocalTypedefNameCandidates. +  RecordData UnusedLocalTypedefNameCandidates; +  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); @@ -4316,22 +4532,36 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,      SmallString<2048> Buffer;      {        llvm::raw_svector_ostream Out(Buffer); -      for (ModuleManager::ModuleConstIterator M = Chain->ModuleMgr.begin(), -                                           MEnd = Chain->ModuleMgr.end(); -           M != MEnd; ++M) { +      for (ModuleFile *M : Chain->ModuleMgr) {          using namespace llvm::support;          endian::Writer<little> LE(Out); -        StringRef FileName = (*M)->FileName; +        StringRef FileName = M->FileName;          LE.write<uint16_t>(FileName.size());          Out.write(FileName.data(), FileName.size()); -        LE.write<uint32_t>((*M)->SLocEntryBaseOffset); -        LE.write<uint32_t>((*M)->BaseIdentifierID); -        LE.write<uint32_t>((*M)->BaseMacroID); -        LE.write<uint32_t>((*M)->BasePreprocessedEntityID); -        LE.write<uint32_t>((*M)->BaseSubmoduleID); -        LE.write<uint32_t>((*M)->BaseSelectorID); -        LE.write<uint32_t>((*M)->BaseDeclID); -        LE.write<uint32_t>((*M)->BaseTypeIndex); + +        // Note: if a base ID was uint max, it would not be possible to load +        // another module after it or have more than one entity inside it. +        uint32_t None = std::numeric_limits<uint32_t>::max(); + +        auto writeBaseIDOrNone = [&](uint32_t BaseID, bool ShouldWrite) { +          assert(BaseID < std::numeric_limits<uint32_t>::max() && "base id too high"); +          if (ShouldWrite) +            LE.write<uint32_t>(BaseID); +          else +            LE.write<uint32_t>(None); +        }; + +        // These values should be unique within a chain, since they will be read +        // as keys into ContinuousRangeMaps. +        writeBaseIDOrNone(M->SLocEntryBaseOffset, M->LocalNumSLocEntries); +        writeBaseIDOrNone(M->BaseIdentifierID, M->LocalNumIdentifiers); +        writeBaseIDOrNone(M->BaseMacroID, M->LocalNumMacros); +        writeBaseIDOrNone(M->BasePreprocessedEntityID, +                          M->NumPreprocessedEntities); +        writeBaseIDOrNone(M->BaseSubmoduleID, M->LocalNumSubmodules); +        writeBaseIDOrNone(M->BaseSelectorID, M->LocalNumSelectors); +        writeBaseIDOrNone(M->BaseDeclID, M->LocalNumDecls); +        writeBaseIDOrNone(M->BaseTypeIndex, M->LocalNumTypes);        }      }      Record.clear(); @@ -4344,8 +4574,9 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    // Keep writing types, declarations, and declaration update records    // until we've emitted all of them. -  Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE); -  WriteDeclsBlockAbbrevs(); +  Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5); +  WriteTypeAbbrevs(); +  WriteDeclAbbrevs();    for (DeclsToRewriteTy::iterator I = DeclsToRewrite.begin(),                                    E = DeclsToRewrite.end();         I != E; ++I) @@ -4371,11 +4602,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,      Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);    WriteCXXBaseSpecifiersOffsets();    WriteFileDeclIDsMap(); -  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); +  WriteSourceManagerBlock(Context.getSourceManager(), PP);    WriteComments();    WritePreprocessor(PP, isModule); -  WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot); +  WriteHeaderSearch(PP.getHeaderSearchInfo());    WriteSelectors(SemaRef);    WriteReferencedSelectorsPool(SemaRef);    WriteIdentifierTable(PP, SemaRef.IdResolver, isModule); @@ -4423,6 +4654,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,    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, +                      UnusedLocalTypedefNameCandidates); +    // Write the record containing pending implicit instantiations.    if (!PendingInstantiations.empty())      Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations); @@ -4469,10 +4705,13 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,        auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {          return A.ID < B.ID;        }; +      auto Eq = [](const ModuleInfo &A, const ModuleInfo &B) { +        return A.ID == B.ID; +      };        // Sort and deduplicate module IDs.        std::sort(Imports.begin(), Imports.end(), Cmp); -      Imports.erase(std::unique(Imports.begin(), Imports.end(), Cmp), +      Imports.erase(std::unique(Imports.begin(), Imports.end(), Eq),                      Imports.end());        RecordData ImportedModules; @@ -4532,17 +4771,17 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {          Record.push_back(GetDeclRef(Update.getDecl()));          break; -      case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: -        AddSourceLocation(Update.getLoc(), Record); -        break; - -      case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION: +      case UPD_CXX_ADDED_FUNCTION_DEFINITION:          // An updated body is emitted last, so that the reader doesn't need          // to skip over the lazy body to reach statements for other records.          Record.pop_back();          HasUpdatedBody = true;          break; +      case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: +        AddSourceLocation(Update.getLoc(), Record); +        break; +        case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {          auto *RD = cast<CXXRecordDecl>(D);          AddUpdatedDeclContext(RD->getPrimaryContext()); @@ -4582,8 +4821,8 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {          // Instantiation may change attributes; write them all out afresh.          Record.push_back(D->hasAttrs());          if (Record.back()) -          WriteAttributes(ArrayRef<const Attr*>(D->getAttrs().begin(), -                                                D->getAttrs().size()), Record); +          WriteAttributes(llvm::makeArrayRef(D->getAttrs().begin(), +                                             D->getAttrs().size()), Record);          // FIXME: Ensure we don't get here for explicit instantiations.          break; @@ -4607,15 +4846,21 @@ 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;        }      }      if (HasUpdatedBody) {        const FunctionDecl *Def = cast<FunctionDecl>(D); -      Record.push_back(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION); +      Record.push_back(UPD_CXX_ADDED_FUNCTION_DEFINITION);        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)); @@ -4981,6 +5226,30 @@ void ASTWriter::AddDeclarationName(DeclarationName Name, RecordDataImpl &Record)    }  } +unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) { +  assert(needsAnonymousDeclarationNumber(D) && +         "expected an anonymous declaration"); + +  // Number the anonymous declarations within this context, if we've not +  // 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++; +    } + +    It = AnonymousDeclarationNumbers.find(D); +    assert(It != AnonymousDeclarationNumbers.end() && +           "declaration not found within its lexical context"); +  } + +  return It->second; +} +  void ASTWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,                                       DeclarationName Name, RecordDataImpl &Record) {    switch (Name.getNameKind()) { @@ -5068,6 +5337,10 @@ void ASTWriter::AddNestedNameSpecifier(NestedNameSpecifier *NNS,      case NestedNameSpecifier::Global:        // Don't need to write an associated value.        break; + +    case NestedNameSpecifier::Super: +      AddDeclRef(NNS->getAsRecordDecl(), Record); +      break;      }    }  } @@ -5117,6 +5390,11 @@ void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,      case NestedNameSpecifier::Global:        AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);        break; + +    case NestedNameSpecifier::Super: +      AddDeclRef(NNS.getNestedNameSpecifier()->getAsRecordDecl(), Record); +      AddSourceRange(NNS.getLocalSourceRange(), Record); +      break;      }    }  } @@ -5186,7 +5464,7 @@ void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg,      break;    case TemplateArgument::Declaration:      AddDeclRef(Arg.getAsDecl(), Record); -    Record.push_back(Arg.isDeclForReferenceParam()); +    AddTypeRef(Arg.getParamTypeForDecl(), Record);      break;    case TemplateArgument::NullPtr:      AddTypeRef(Arg.getNullPtrType(), Record); @@ -5418,6 +5696,7 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec        Record.push_back(Capture.getCaptureKind());        switch (Capture.getCaptureKind()) {        case LCK_This: +      case LCK_VLAType:          break;        case LCK_ByCopy:        case LCK_ByRef: @@ -5521,8 +5800,6 @@ void ASTWriter::CompletedTagDefinition(const TagDecl *D) {  }  void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { -  assert(!WritingAST && "Already writing the AST!"); -    // TU and namespaces are handled elsewhere.    if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC))      return; @@ -5531,12 +5808,12 @@ void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {      return; // Not a source decl added to a DeclContext from PCH.    assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!"); +  assert(!WritingAST && "Already writing the AST!");    AddUpdatedDeclContext(DC);    UpdatingVisibleDecls.push_back(D);  }  void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { -  assert(!WritingAST && "Already writing the AST!");    assert(D->isImplicit());    if (!(!D->isFromASTFile() && RD->isFromASTFile()))      return; // Not a source member added to a class from PCH. @@ -5545,17 +5822,18 @@ void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {    // A decl coming from PCH was modified.    assert(RD->isCompleteDefinition()); +  assert(!WritingAST && "Already writing the AST!");    DeclUpdates[RD].push_back(DeclUpdate(UPD_CXX_ADDED_IMPLICIT_MEMBER, D));  }  void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,                                       const ClassTemplateSpecializationDecl *D) {    // The specializations set is kept in the canonical template. -  assert(!WritingAST && "Already writing the AST!");    TD = TD->getCanonicalDecl();    if (!(!D->isFromASTFile() && TD->isFromASTFile()))      return; // Not a source specialization added to a template from PCH. +  assert(!WritingAST && "Already writing the AST!");    DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,                                         D));  } @@ -5563,11 +5841,11 @@ void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,  void ASTWriter::AddedCXXTemplateSpecialization(      const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {    // The specializations set is kept in the canonical template. -  assert(!WritingAST && "Already writing the AST!");    TD = TD->getCanonicalDecl();    if (!(!D->isFromASTFile() && TD->isFromASTFile()))      return; // Not a source specialization added to a template from PCH. +  assert(!WritingAST && "Already writing the AST!");    DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,                                         D));  } @@ -5575,11 +5853,11 @@ void ASTWriter::AddedCXXTemplateSpecialization(  void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,                                                 const FunctionDecl *D) {    // The specializations set is kept in the canonical template. -  assert(!WritingAST && "Already writing the AST!");    TD = TD->getCanonicalDecl();    if (!(!D->isFromASTFile() && TD->isFromASTFile()))      return; // Not a source specialization added to a template from PCH. +  assert(!WritingAST && "Already writing the AST!");    DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,                                         D));  } @@ -5607,9 +5885,8 @@ void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {    if (!D->isFromASTFile())      return; // Declaration not imported from PCH. -  // Implicit decl from a PCH was defined. -  // FIXME: Should implicit definition be a separate FunctionDecl? -  RewriteDecl(D); +  // Implicit function decl from a PCH was defined. +  DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));  }  void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) { @@ -5617,10 +5894,8 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {    if (!D->isFromASTFile())      return; -  // Since the actual instantiation is delayed, this really means that we need -  // to update the instantiation location.    DeclUpdates[D].push_back( -      DeclUpdate(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION)); +      DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));  }  void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) { @@ -5668,3 +5943,11 @@ void ASTWriter::DeclarationMarkedUsed(const Decl *D) {    DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_USED));  } + +void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) { +  assert(!WritingAST && "Already writing the AST!"); +  if (!D->isFromASTFile()) +    return; + +  DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE)); +} diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 47ce747d5bd3..4017ec63d4f2 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -167,8 +167,8 @@ void ASTDeclWriter::VisitDecl(Decl *D) {    Record.push_back(D->isInvalidDecl());    Record.push_back(D->hasAttrs());    if (D->hasAttrs()) -    Writer.WriteAttributes(ArrayRef<const Attr*>(D->getAttrs().begin(), -                                                 D->getAttrs().size()), Record); +    Writer.WriteAttributes(llvm::makeArrayRef(D->getAttrs().begin(), +                                              D->getAttrs().size()), Record);    Record.push_back(D->isImplicit());    Record.push_back(D->isUsed(false));    Record.push_back(D->isReferenced()); @@ -203,6 +203,8 @@ void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {  void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {    VisitDecl(D);    Writer.AddDeclarationName(D->getDeclName(), Record); +  if (needsAnonymousDeclarationNumber(D)) +    Record.push_back(Writer.getAnonymousDeclarationNumber(D));  }  void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) { @@ -224,13 +226,11 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {    VisitTypedefNameDecl(D);    if (!D->hasAttrs() &&        !D->isImplicit() && -      !D->isUsed(false) &&        D->getFirstDecl() == D->getMostRecentDecl() &&        !D->isInvalidDecl() && -      !D->isReferenced() &&        !D->isTopLevelDeclInObjCContainer() && -      D->getAccess() == AS_none &&        !D->isModulePrivate() && +      !needsAnonymousDeclarationNumber(D) &&        D->getDeclName().getNameKind() == DeclarationName::Identifier)      AbbrevToUse = Writer.getDeclTypedefAbbrev(); @@ -239,6 +239,7 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {  void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {    VisitTypedefNameDecl(D); +  Writer.AddDeclRef(D->getDescribedAliasTemplate(), Record);    Code = serialization::DECL_TYPEALIAS;  } @@ -247,18 +248,26 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) {    VisitTypeDecl(D);    Record.push_back(D->getIdentifierNamespace());    Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding -  Record.push_back(D->isCompleteDefinition()); +  if (!isa<CXXRecordDecl>(D)) +    Record.push_back(D->isCompleteDefinition());    Record.push_back(D->isEmbeddedInDeclarator());    Record.push_back(D->isFreeStanding());    Record.push_back(D->isCompleteDefinitionRequired());    Writer.AddSourceLocation(D->getRBraceLoc(), Record); -  Record.push_back(D->hasExtInfo()); -  if (D->hasExtInfo()) + +  if (D->hasExtInfo()) { +    Record.push_back(1);      Writer.AddQualifierInfo(*D->getExtInfo(), Record); -  else if (D->hasDeclaratorForAnonDecl()) -    Writer.AddDeclRef(D->getDeclaratorForAnonDecl(), Record); -  else -    Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record); +  } else if (auto *TD = D->getTypedefNameForAnonDecl()) { +    Record.push_back(2); +    Writer.AddDeclRef(TD, Record); +    Writer.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo(), Record); +  } else if (auto *DD = D->getDeclaratorForAnonDecl()) { +    Record.push_back(3); +    Writer.AddDeclRef(DD, Record); +  } else { +    Record.push_back(0); +  }  }  void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { @@ -284,6 +293,8 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {        !D->isImplicit() &&        !D->isUsed(false) &&        !D->hasExtInfo() && +      !D->getTypedefNameForAnonDecl() && +      !D->getDeclaratorForAnonDecl() &&        D->getFirstDecl() == D->getMostRecentDecl() &&        !D->isInvalidDecl() &&        !D->isReferenced() && @@ -293,6 +304,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {        !CXXRecordDecl::classofKind(D->getKind()) &&        !D->getIntegerTypeSourceInfo() &&        !D->getMemberSpecializationInfo() && +      !needsAnonymousDeclarationNumber(D) &&        D->getDeclName().getNameKind() == DeclarationName::Identifier)      AbbrevToUse = Writer.getDeclEnumAbbrev(); @@ -310,6 +322,8 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {        !D->isImplicit() &&        !D->isUsed(false) &&        !D->hasExtInfo() && +      !D->getTypedefNameForAnonDecl() && +      !D->getDeclaratorForAnonDecl() &&        D->getFirstDecl() == D->getMostRecentDecl() &&        !D->isInvalidDecl() &&        !D->isReferenced() && @@ -317,6 +331,7 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {        D->getAccess() == AS_none &&        !D->isModulePrivate() &&        !CXXRecordDecl::classofKind(D->getKind()) && +      !needsAnonymousDeclarationNumber(D) &&        D->getDeclName().getNameKind() == DeclarationName::Identifier)      AbbrevToUse = Writer.getDeclRecordAbbrev(); @@ -349,7 +364,6 @@ void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {  void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {    VisitRedeclarable(D);    VisitDeclaratorDecl(D); -    Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);    Record.push_back(D->getIdentifierNamespace()); @@ -663,12 +677,17 @@ void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {  void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {    VisitDeclaratorDecl(D);    Record.push_back(D->isMutable()); -  if (D->InitializerOrBitWidth.getInt() != ICIS_NoInit || -      D->InitializerOrBitWidth.getPointer()) { -    Record.push_back(D->InitializerOrBitWidth.getInt() + 1); -    Writer.AddStmt(D->InitializerOrBitWidth.getPointer()); -  } else { +  if (D->InitStorage.getInt() == FieldDecl::ISK_BitWidthOrNothing && +      D->InitStorage.getPointer() == nullptr) {      Record.push_back(0); +  } else if (D->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) { +    Record.push_back(D->InitStorage.getInt() + 1); +    Writer.AddTypeRef( +        QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0), +        Record); +  } else { +    Record.push_back(D->InitStorage.getInt() + 1); +    Writer.AddStmt(static_cast<Expr *>(D->InitStorage.getPointer()));    }    if (!D->getDeclName())      Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record); @@ -753,6 +772,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {        !D->isTopLevelDeclInObjCContainer() &&        D->getAccess() == AS_none &&        !D->isModulePrivate() && +      !needsAnonymousDeclarationNumber(D) &&        D->getDeclName().getNameKind() == DeclarationName::Identifier &&        !D->hasExtInfo() &&        D->getFirstDecl() == D->getMostRecentDecl() && @@ -930,6 +950,7 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {  }  void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { +  VisitRedeclarable(D);    VisitNamedDecl(D);    Writer.AddSourceLocation(D->getNamespaceLoc(), Record);    Writer.AddSourceLocation(D->getTargetNameLoc(), Record); @@ -1027,6 +1048,17 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {      // We only need to record overridden methods once for the canonical decl.      Record.push_back(0);    } + +  if (D->getFirstDecl() == D->getMostRecentDecl() && +      !D->isInvalidDecl() && +      !D->hasAttrs() && +      !D->isTopLevelDeclInObjCContainer() && +      D->getDeclName().getNameKind() == DeclarationName::Identifier && +      !D->hasExtInfo() && +      !D->hasInheritedPrototype() && +      D->hasWrittenPrototype()) +    AbbrevToUse = Writer.getDeclCXXMethodAbbrev(); +    Code = serialization::DECL_CXX_METHOD;  } @@ -1449,7 +1481,7 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {  // ASTWriter Implementation  //===----------------------------------------------------------------------===// -void ASTWriter::WriteDeclsBlockAbbrevs() { +void ASTWriter::WriteDeclAbbrevs() {    using namespace llvm;    BitCodeAbbrev *Abv; @@ -1552,8 +1584,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation -  Abv->Add(BitCodeAbbrevOp(0));                         // hasExtInfo -  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // TypedefNameAnonDecl +  Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind    // EnumDecl    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // AddTypeRef    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IntegerType @@ -1600,8 +1631,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation -  Abv->Add(BitCodeAbbrevOp(0));                         // hasExtInfo -  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // TypedefNameAnonDecl +  Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind    // RecordDecl    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion @@ -1676,10 +1706,10 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {    Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl    Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs    Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit -  Abv->Add(BitCodeAbbrevOp(0));                       // isUsed -  Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced    Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer -  Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier    Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID    // NamedDecl @@ -1738,6 +1768,63 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc    DeclVarAbbrev = Stream.EmitAbbrev(Abv); +  // Abbreviation for DECL_CXX_METHOD +  Abv = new BitCodeAbbrev(); +  Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD)); +  // RedeclarableDecl +  Abv->Add(BitCodeAbbrevOp(0));                         // CanonicalDecl +  // Decl +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // DeclContext +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalDeclContext +  Abv->Add(BitCodeAbbrevOp(0));                         // Invalid +  Abv->Add(BitCodeAbbrevOp(0));                         // HasAttrs +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced +  Abv->Add(BitCodeAbbrevOp(0));                         // InObjCContainer +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModulePrivate +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SubmoduleID +  // NamedDecl +  Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Identifier +  // ValueDecl +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Type +  // DeclaratorDecl +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InnerLocStart +  Abv->Add(BitCodeAbbrevOp(0));                         // HasExtInfo +  // FunctionDecl +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure +  Abv->Add(BitCodeAbbrevOp(0));                         // HasInheritedProto +  Abv->Add(BitCodeAbbrevOp(1));                         // HasWrittenProto +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // DeletedAsWritten +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LocEnd +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind +  // This Array slurps the rest of the record. Fortunately we want to encode +  // (nearly) all the remaining (variable number of) fields in the same way. +  // +  // This is the function template information if any, then +  //         NumParams and Params[] from FunctionDecl, and +  //         NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl. +  // +  //  Add an AbbrevOp for 'size then elements' and use it here. +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); +  DeclCXXMethodAbbrev = Stream.EmitAbbrev(Abv); +    // Abbreviation for EXPR_DECL_REF    Abv = new BitCodeAbbrev();    Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF)); @@ -1755,7 +1842,8 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates -  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //RefersToEnclosingLocal +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, +                           1)); // RefersToEnclosingVariableOrCapture    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location    DeclRefExprAbbrev = Stream.EmitAbbrev(Abv); @@ -1796,6 +1884,24 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // getKind    CharacterLiteralAbbrev = Stream.EmitAbbrev(Abv); +  // Abbreviation for EXPR_IMPLICIT_CAST +  Abv = new BitCodeAbbrev(); +  Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST)); +  // Stmt +  // Expr +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind +  // CastExpr +  Abv->Add(BitCodeAbbrevOp(0)); // PathSize +  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind +  // ImplicitCastExpr +  ExprImplicitCastAbbrev = Stream.EmitAbbrev(Abv); +    Abv = new BitCodeAbbrev();    Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index a43b3527a711..e980ce783f5e 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -307,7 +307,7 @@ void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {    // Captures    for (const auto &I : S->captures()) { -    if (I.capturesThis()) +    if (I.capturesThis() || I.capturesVariableArrayType())        Writer.AddDeclRef(nullptr, Record);      else        Writer.AddDeclRef(I.getCapturedVar(), Record); @@ -333,6 +333,7 @@ void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {    VisitExpr(E);    Writer.AddSourceLocation(E->getLocation(), Record);    Record.push_back(E->getIdentType()); // FIXME: stable encoding +  Writer.AddStmt(E->getFunctionName());    Code = serialization::EXPR_PREDEFINED;  } @@ -343,7 +344,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {    Record.push_back(E->getDecl() != E->getFoundDecl());    Record.push_back(E->hasTemplateKWAndArgsInfo());    Record.push_back(E->hadMultipleCandidates()); -  Record.push_back(E->refersToEnclosingLocal()); +  Record.push_back(E->refersToEnclosingVariableOrCapture());    if (E->hasTemplateKWAndArgsInfo()) {      unsigned NumTemplateArgs = E->getNumTemplateArgs(); @@ -635,6 +636,10 @@ ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {  void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {    VisitCastExpr(E); + +  if (E->path_size() == 0) +    AbbrevToUse = Writer.getExprImplicitCastAbbrev(); +    Code = serialization::EXPR_IMPLICIT_CAST;  } @@ -1574,6 +1579,17 @@ void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {    Code = serialization::EXPR_MATERIALIZE_TEMPORARY;  } +void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) { +  VisitExpr(E); +  Writer.AddSourceLocation(E->LParenLoc, Record); +  Writer.AddSourceLocation(E->EllipsisLoc, Record); +  Writer.AddSourceLocation(E->RParenLoc, Record); +  Writer.AddStmt(E->SubExprs[0]); +  Writer.AddStmt(E->SubExprs[1]); +  Record.push_back(E->Opcode); +  Code = serialization::EXPR_CXX_FOLD; +} +  void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {    VisitExpr(E);    Writer.AddStmt(E->getSourceExpr()); @@ -1581,6 +1597,12 @@ void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {    Code = serialization::EXPR_OPAQUE_VALUE;  } +void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) { +  VisitExpr(E); +  // TODO: Figure out sane writer behavior for a TypoExpr, if necessary +  assert(false && "Cannot write TypoExpr nodes"); +} +  //===----------------------------------------------------------------------===//  // CUDA Expressions and Statements.  //===----------------------------------------------------------------------===// @@ -1735,18 +1757,39 @@ void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}  void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {} +void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {} + +void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {} + +void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {} + +void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {} + +void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {} +  void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {    Record.push_back(C->varlist_size());    Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); -  for (auto *VE : C->varlists()) +  for (auto *VE : C->varlists()) { +    Writer->Writer.AddStmt(VE); +  } +  for (auto *VE : C->private_copies()) {      Writer->Writer.AddStmt(VE); +  }  }  void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {    Record.push_back(C->varlist_size());    Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); -  for (auto *VE : C->varlists()) +  for (auto *VE : C->varlists()) { +    Writer->Writer.AddStmt(VE); +  } +  for (auto *VE : C->private_copies()) { +    Writer->Writer.AddStmt(VE); +  } +  for (auto *VE : C->inits()) {      Writer->Writer.AddStmt(VE); +  }  }  void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) { @@ -1826,29 +1869,61 @@ void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {      Writer.AddStmt(E->getAssociatedStmt());  } -void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) { +void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {    VisitStmt(D);    Record.push_back(D->getNumClauses()); +  Record.push_back(D->getCollapsedNumber());    VisitOMPExecutableDirective(D); -  Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE; +  Writer.AddStmt(D->getIterationVariable()); +  Writer.AddStmt(D->getLastIteration()); +  Writer.AddStmt(D->getCalcLastIteration()); +  Writer.AddStmt(D->getPreCond()); +  Writer.AddStmt(D->getCond(/* SeparateIter */ false)); +  Writer.AddStmt(D->getCond(/* SeparateIter */ true)); +  Writer.AddStmt(D->getInit()); +  Writer.AddStmt(D->getInc()); +  if (isOpenMPWorksharingDirective(D->getDirectiveKind())) { +    Writer.AddStmt(D->getIsLastIterVariable()); +    Writer.AddStmt(D->getLowerBoundVariable()); +    Writer.AddStmt(D->getUpperBoundVariable()); +    Writer.AddStmt(D->getStrideVariable()); +    Writer.AddStmt(D->getEnsureUpperBound()); +    Writer.AddStmt(D->getNextLowerBound()); +    Writer.AddStmt(D->getNextUpperBound()); +  } +  for (auto I : D->counters()) { +    Writer.AddStmt(I); +  } +  for (auto I : D->updates()) { +    Writer.AddStmt(I); +  } +  for (auto I : D->finals()) { +    Writer.AddStmt(I); +  }  } -void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) { +void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {    VisitStmt(D);    Record.push_back(D->getNumClauses()); -  Record.push_back(D->getCollapsedNumber());    VisitOMPExecutableDirective(D); +  Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) { +  VisitOMPLoopDirective(D);    Code = serialization::STMT_OMP_SIMD_DIRECTIVE;  }  void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) { -  VisitStmt(D); -  Record.push_back(D->getNumClauses()); -  Record.push_back(D->getCollapsedNumber()); -  VisitOMPExecutableDirective(D); +  VisitOMPLoopDirective(D);    Code = serialization::STMT_OMP_FOR_DIRECTIVE;  } +void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) { +  VisitOMPLoopDirective(D); +  Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE; +} +  void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {    VisitStmt(D);    Record.push_back(D->getNumClauses()); @@ -1883,13 +1958,16 @@ void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {  }  void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) { -  VisitStmt(D); -  Record.push_back(D->getNumClauses()); -  Record.push_back(D->getCollapsedNumber()); -  VisitOMPExecutableDirective(D); +  VisitOMPLoopDirective(D);    Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;  } +void ASTStmtWriter::VisitOMPParallelForSimdDirective( +    OMPParallelForSimdDirective *D) { +  VisitOMPLoopDirective(D); +  Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE; +} +  void ASTStmtWriter::VisitOMPParallelSectionsDirective(      OMPParallelSectionsDirective *D) {    VisitStmt(D); @@ -1905,6 +1983,23 @@ void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {    Code = serialization::STMT_OMP_TASK_DIRECTIVE;  } +void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) { +  VisitStmt(D); +  Record.push_back(D->getNumClauses()); +  VisitOMPExecutableDirective(D); +  Writer.AddStmt(D->getX()); +  Writer.AddStmt(D->getV()); +  Writer.AddStmt(D->getExpr()); +  Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) { +  VisitStmt(D); +  Record.push_back(D->getNumClauses()); +  VisitOMPExecutableDirective(D); +  Code = serialization::STMT_OMP_TARGET_DIRECTIVE; +} +  void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {    VisitStmt(D);    VisitOMPExecutableDirective(D); @@ -1930,6 +2025,19 @@ void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {    Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;  } +void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) { +  VisitStmt(D); +  VisitOMPExecutableDirective(D); +  Code = serialization::STMT_OMP_ORDERED_DIRECTIVE; +} + +void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) { +  VisitStmt(D); +  Record.push_back(D->getNumClauses()); +  VisitOMPExecutableDirective(D); +  Code = serialization::STMT_OMP_TEAMS_DIRECTIVE; +} +  //===----------------------------------------------------------------------===//  // ASTWriter Implementation  //===----------------------------------------------------------------------===// diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp index 985812232505..479138804547 100644 --- a/lib/Serialization/GlobalModuleIndex.cpp +++ b/lib/Serialization/GlobalModuleIndex.cpp @@ -122,11 +122,10 @@ typedef llvm::OnDiskIterableChainedHashTable<IdentifierIndexReaderTrait>  } -GlobalModuleIndex::GlobalModuleIndex(llvm::MemoryBuffer *Buffer, +GlobalModuleIndex::GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,                                       llvm::BitstreamCursor Cursor) -  : Buffer(Buffer), IdentifierIndex(), -    NumIdentifierLookups(), NumIdentifierLookupHits() -{ +    : Buffer(std::move(Buffer)), IdentifierIndex(), NumIdentifierLookups(), +      NumIdentifierLookupHits() {    // Read the global index.    bool InGlobalIndexBlock = false;    bool Done = false; @@ -260,7 +259,7 @@ GlobalModuleIndex::readIndex(StringRef Path) {      return std::make_pair(nullptr, EC_IOError);    } -  return std::make_pair(new GlobalModuleIndex(Buffer.release(), Cursor), +  return std::make_pair(new GlobalModuleIndex(std::move(Buffer), Cursor),                          EC_None);  } @@ -494,19 +493,17 @@ namespace {  bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {    // Open the module file. -  std::unique_ptr<llvm::MemoryBuffer> Buffer; -  std::string ErrorStr; -  Buffer.reset(FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)); + +  auto Buffer = FileMgr.getBufferForFile(File, /*isVolatile=*/true);    if (!Buffer) {      return true;    }    // Initialize the input stream    llvm::BitstreamReader InStreamFile; -  llvm::BitstreamCursor InStream; -  InStreamFile.init((const unsigned char *)Buffer->getBufferStart(), -                  (const unsigned char *)Buffer->getBufferEnd()); -  InStream.init(InStreamFile); +  InStreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(), +                    (const unsigned char *)(*Buffer)->getBufferEnd()); +  llvm::BitstreamCursor InStream(InStreamFile);    // Sniff for the signature.    if (InStream.Read(8) != 'C' || @@ -591,6 +588,10 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {          off_t StoredSize = (off_t)Record[Idx++];          time_t StoredModTime = (time_t)Record[Idx++]; +        // Skip the stored signature. +        // FIXME: we could read the signature out of the import and validate it. +        Idx++; +          // Retrieve the imported file name.          unsigned Length = Record[Idx++];          SmallString<128> ImportedFile(Record.begin() + Idx, diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp index 6f2a3c220430..6c48a41187c2 100644 --- a/lib/Serialization/Module.cpp +++ b/lib/Serialization/Module.cpp @@ -21,7 +21,7 @@ using namespace serialization;  using namespace reader;  ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation) -  : Kind(Kind), File(nullptr), DirectlyImported(false), +  : Kind(Kind), File(nullptr), Signature(0), DirectlyImported(false),      Generation(Generation), SizeInBits(0),      LocalNumSLocEntries(0), SLocEntryBaseID(0),      SLocEntryBaseOffset(0), SLocEntryOffsets(nullptr), diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index 2c10c119a07b..ac98ca0b8720 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -45,10 +45,11 @@ ModuleFile *ModuleManager::lookup(const FileEntry *File) {    return Known->second;  } -llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) { +std::unique_ptr<llvm::MemoryBuffer> +ModuleManager::lookupBuffer(StringRef Name) {    const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,                                             /*cacheFailure=*/false); -  return InMemoryBuffers[Entry]; +  return std::move(InMemoryBuffers[Entry]);  }  ModuleManager::AddModuleResult @@ -56,6 +57,9 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,                           SourceLocation ImportLoc, ModuleFile *ImportedBy,                           unsigned Generation,                           off_t ExpectedSize, time_t ExpectedModTime, +                         ASTFileSignature ExpectedSignature, +                         std::function<ASTFileSignature(llvm::BitstreamReader &)> +                             ReadSignature,                           ModuleFile *&Module,                           std::string &ErrorStr) {    Module = nullptr; @@ -63,6 +67,13 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,    // Look for the file entry. This only fails if the expected size or    // modification time differ.    const FileEntry *Entry; +  if (Type == MK_ExplicitModule) { +    // If we're not expecting to pull this file out of the module cache, it +    // might have a different mtime due to being moved across filesystems in +    // a distributed build. The size must still match, though. (As must the +    // contents, but we can't check that.) +    ExpectedModTime = 0; +  }    if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) {      ErrorStr = "module file out of date";      return OutOfDate; @@ -88,7 +99,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,      ModuleEntry = New;      New->InputFilesValidationTimestamp = 0; -    if (New->Kind == MK_Module) { +    if (New->Kind == MK_ImplicitModule) {        std::string TimestampFilename = New->getTimestampFilename();        vfs::Status Status;        // A cached stat value would be fine as well. @@ -98,39 +109,59 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,      }      // Load the contents of the module -    if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) { +    if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {        // The buffer was already provided for us. -      assert(Buffer && "Passed null buffer"); -      New->Buffer.reset(Buffer); +      New->Buffer = std::move(Buffer);      } else {        // Open the AST file. -      std::error_code ec; +      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf( +          (std::error_code()));        if (FileName == "-") { -        llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf = -            llvm::MemoryBuffer::getSTDIN(); -        ec = Buf.getError(); -        if (ec) -          ErrorStr = ec.message(); -        else -          New->Buffer = std::move(Buf.get()); +        Buf = llvm::MemoryBuffer::getSTDIN();        } else {          // Leave the FileEntry open so if it gets read again by another          // ModuleManager it must be the same underlying file.          // FIXME: Because FileManager::getFile() doesn't guarantee that it will          // give us an open file, this may not be 100% reliable. -        New->Buffer.reset(FileMgr.getBufferForFile(New->File, &ErrorStr, -                                                   /*IsVolatile*/false, -                                                   /*ShouldClose*/false)); +        Buf = FileMgr.getBufferForFile(New->File, +                                       /*IsVolatile=*/false, +                                       /*ShouldClose=*/false);        } -       -      if (!New->Buffer) + +      if (!Buf) { +        ErrorStr = Buf.getError().message();          return Missing; +      } + +      New->Buffer = std::move(*Buf);      }      // Initialize the stream      New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),                           (const unsigned char *)New->Buffer->getBufferEnd());    } + +  if (ExpectedSignature) { +    if (NewModule) +      ModuleEntry->Signature = ReadSignature(ModuleEntry->StreamFile); +    else +      assert(ModuleEntry->Signature == ReadSignature(ModuleEntry->StreamFile)); + +    if (ModuleEntry->Signature != ExpectedSignature) { +      ErrorStr = ModuleEntry->Signature ? "signature mismatch" +                                        : "could not read module signature"; + +      if (NewModule) { +        // Remove the module file immediately, since removeModules might try to +        // invalidate the file cache for Entry, and that is not safe if this +        // module is *itself* up to date, but has an out-of-date importer. +        Modules.erase(Entry); +        Chain.pop_back(); +        delete ModuleEntry; +      } +      return OutOfDate; +    } +  }    if (ImportedBy) {      ModuleEntry->ImportedBy.insert(ImportedBy); @@ -187,12 +218,13 @@ void ModuleManager::removeModules(    Chain.erase(first, last);  } -void ModuleManager::addInMemoryBuffer(StringRef FileName,  -                                      llvm::MemoryBuffer *Buffer) { -   -  const FileEntry *Entry = FileMgr.getVirtualFile(FileName,  -                                                  Buffer->getBufferSize(), 0); -  InMemoryBuffers[Entry] = Buffer; +void +ModuleManager::addInMemoryBuffer(StringRef FileName, +                                 std::unique_ptr<llvm::MemoryBuffer> Buffer) { + +  const FileEntry *Entry = +      FileMgr.getVirtualFile(FileName, Buffer->getBufferSize(), 0); +  InMemoryBuffers[Entry] = std::move(Buffer);  }  ModuleManager::VisitState *ModuleManager::allocateVisitState() { @@ -249,7 +281,7 @@ ModuleManager::~ModuleManager() {  void  ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData),                       void *UserData, -                     llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit) { +                     llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {    // If the visitation order vector is the wrong size, recompute the order.    if (VisitOrder.size() != Chain.size()) {      unsigned N = size();  | 
