diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Lex/HeaderSearch.cpp | 18 | ||||
| -rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 37 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 30 | 
4 files changed, 72 insertions, 26 deletions
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index d4d14e87455..9e4b68232a1 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -47,7 +47,7 @@ HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,                             const LangOptions &LangOpts,                              const TargetInfo *Target)    : HSOpts(HSOpts), FileMgr(FM), FrameworkMap(64), -    ModMap(FileMgr, *Diags.getClient(), LangOpts, Target) +    ModMap(FileMgr, *Diags.getClient(), LangOpts, Target, *this)  {    AngledDirIdx = 0;    SystemDirIdx = 0; @@ -806,6 +806,7 @@ static void mergeHeaderFileInfo(HeaderFileInfo &HFI,                                  const HeaderFileInfo &OtherHFI) {    HFI.isImport |= OtherHFI.isImport;    HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; +  HFI.isModuleHeader |= OtherHFI.isModuleHeader;    HFI.NumIncludes += OtherHFI.NumIncludes;    if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { @@ -851,6 +852,14 @@ bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {        HFI.ControllingMacro || HFI.ControllingMacroID;  } +void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE) { +  if (FE->getUID() >= FileInfo.size()) +    FileInfo.resize(FE->getUID()+1); + +  HeaderFileInfo &HFI = FileInfo[FE->getUID()]; +  HFI.isModuleHeader = true; +} +  void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) {    if (UID >= FileInfo.size())      FileInfo.resize(UID+1); @@ -948,7 +957,12 @@ bool HeaderSearch::hasModuleMap(StringRef FileName,    } while (true);  } -Module *HeaderSearch::findModuleForHeader(const FileEntry *File) { +Module *HeaderSearch::findModuleForHeader(const FileEntry *File) const { +  if (ExternalSource) { +    // Make sure the external source has handled header info about this file, +    // which includes whether the file is part of a module. +    (void)getFileInfo(File); +  }    if (Module *Mod = ModMap.findModuleForHeader(File))      return Mod; diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index f9b4e2c9474..71a98e2152a 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -18,6 +18,7 @@  #include "clang/Basic/FileManager.h"  #include "clang/Basic/TargetInfo.h"  #include "clang/Basic/TargetOptions.h" +#include "clang/Lex/HeaderSearch.h"  #include "clang/Lex/LexDiagnostic.h"  #include "clang/Lex/Lexer.h"  #include "clang/Lex/LiteralSupport.h" @@ -76,8 +77,10 @@ ModuleMap::resolveExport(Module *Mod,  }  ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, -                     const LangOptions &LangOpts, const TargetInfo *Target) -  : LangOpts(LangOpts), Target(Target), BuiltinIncludeDir(0) +                     const LangOptions &LangOpts, const TargetInfo *Target, +                     HeaderSearch &HeaderInfo) +  : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo), +    BuiltinIncludeDir(0)  {    IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);    Diags = IntrusiveRefCntPtr<DiagnosticsEngine>( @@ -553,10 +556,12 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {  void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,                            bool Excluded) { -  if (Excluded) +  if (Excluded) {      Mod->ExcludedHeaders.push_back(Header); -  else +  } else {      Mod->Headers.push_back(Header); +    HeaderInfo.MarkFileModuleHeader(Header); +  }    Headers[Header] = KnownHeader(Mod, Excluded);  } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 54fe424ddf6..cc9b5d506ac 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1337,7 +1337,7 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {  }  HeaderFileInfoTrait::data_type  -HeaderFileInfoTrait::ReadData(internal_key_ref, const unsigned char *d, +HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,                                unsigned DataLen) {    const unsigned char *End = d + DataLen;    using namespace clang::io; @@ -1358,6 +1358,21 @@ HeaderFileInfoTrait::ReadData(internal_key_ref, const unsigned char *d,      HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);    } +  if (d != End) { +    uint32_t LocalSMID = ReadUnalignedLE32(d); +    if (LocalSMID) { +      // This header is part of a module. Associate it with the module to enable +      // implicit module import. +      SubmoduleID GlobalSMID = Reader.getGlobalSubmoduleID(M, LocalSMID); +      Module *Mod = Reader.getSubmodule(GlobalSMID); +      HFI.isModuleHeader = true; +      FileManager &FileMgr = Reader.getFileManager(); +      ModuleMap &ModMap = +          Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); +      ModMap.addHeader(Mod, FileMgr.getFile(key.Filename), /*Excluded=*/false); +    } +  } +    assert(End == d && "Wrong data length in HeaderFileInfo deserialization");    (void)End; @@ -3508,13 +3523,9 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) {        if (!CurrentModule)          break; -      // FIXME: Be more lazy about this! -      if (const FileEntry *File = PP.getFileManager().getFile(Blob)) { -        if (std::find(CurrentModule->Headers.begin(),  -                      CurrentModule->Headers.end(),  -                      File) == CurrentModule->Headers.end()) -          ModMap.addHeader(CurrentModule, File, false); -      } +      // 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;            } @@ -3527,13 +3538,9 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) {        if (!CurrentModule)          break; -      // FIXME: Be more lazy about this! -      if (const FileEntry *File = PP.getFileManager().getFile(Blob)) { -        if (std::find(CurrentModule->Headers.begin(),  -                      CurrentModule->Headers.end(),  -                      File) == CurrentModule->Headers.end()) -          ModMap.addHeader(CurrentModule, File, true); -      } +      // 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;            } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 8f48d5870af..088e7a3f2cf 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1384,14 +1384,15 @@ namespace {    // Trait used for the on-disk hash table of header search information.    class HeaderFileInfoTrait {      ASTWriter &Writer; +    const HeaderSearch &HS;      // Keep track of the framework names we've used during serialization.      SmallVector<char, 128> FrameworkStringData;      llvm::StringMap<unsigned> FrameworkNameOffset;    public: -    HeaderFileInfoTrait(ASTWriter &Writer) -      : Writer(Writer) { } +    HeaderFileInfoTrait(ASTWriter &Writer, const HeaderSearch &HS) +      : Writer(Writer), HS(HS) { }      struct key_type {        const FileEntry *FE; @@ -1415,6 +1416,8 @@ namespace {        unsigned KeyLen = strlen(key.Filename) + 1 + 8 + 8;        clang::io::Emit16(Out, KeyLen);        unsigned DataLen = 1 + 2 + 4 + 4; +      if (Data.isModuleHeader) +        DataLen += 4;        clang::io::Emit8(Out, DataLen);        return std::make_pair(KeyLen, DataLen);      } @@ -1427,7 +1430,7 @@ namespace {        Out.write(key.Filename, KeyLen);      } -    void EmitData(raw_ostream &Out, key_type_ref, +    void EmitData(raw_ostream &Out, key_type_ref key,                    data_type_ref Data, unsigned DataLen) {        using namespace clang::io;        uint64_t Start = Out.tell(); (void)Start; @@ -1461,7 +1464,12 @@ namespace {            Offset = Pos->second;        }        Emit32(Out, Offset); -       + +      if (Data.isModuleHeader) { +        Module *Mod = HS.findModuleForHeader(key.FE); +        Emit32(Out, Writer.getExistingSubmoduleID(Mod)); +      } +        assert(Out.tell() - Start == DataLen && "Wrong data length");      } @@ -1480,7 +1488,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) {    if (FilesByUID.size() > HS.header_file_size())      FilesByUID.resize(HS.header_file_size()); -  HeaderFileInfoTrait GeneratorTrait(*this); +  HeaderFileInfoTrait GeneratorTrait(*this, HS);    OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;      SmallVector<const char *, 4> SavedStrings;    unsigned NumHeaderSearchEntries = 0; @@ -2020,6 +2028,18 @@ unsigned ASTWriter::getSubmoduleID(Module *Mod) {    return SubmoduleIDs[Mod] = NextSubmoduleID++;  } +unsigned ASTWriter::getExistingSubmoduleID(Module *Mod) const { +  if (!Mod) +    return 0; + +  llvm::DenseMap<Module *, unsigned>::const_iterator +    Known = SubmoduleIDs.find(Mod); +  if (Known != SubmoduleIDs.end()) +    return Known->second; + +  return 0; +} +  /// \brief Compute the number of modules within the given tree (including the  /// given module).  static unsigned getNumberOfModules(Module *Mod) {  | 

