diff options
| -rw-r--r-- | clang/include/clang/Basic/Module.h | 4 | ||||
| -rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 124 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 2 | 
3 files changed, 47 insertions, 83 deletions
diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index a53f87d7b77..faaca22bd06 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -290,6 +290,10 @@ public:    submodule_iterator submodule_end()   { return SubModules.end(); }    submodule_const_iterator submodule_end() const { return SubModules.end(); } +  static StringRef getModuleInputBufferName() { +    return "<module-includes>"; +  } +    /// \brief Print the module map for this module to the given stream.     ///    void print(llvm::raw_ostream &OS, unsigned Indent = 0) const; diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index f4ea5d3da08..47063f78b5d 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -131,6 +131,29 @@ ASTConsumer *GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,                            Sysroot, OS);  } +static SmallVectorImpl<char> & +operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) { +  Includes.append(RHS.begin(), RHS.end()); +  return Includes; +} + +static void addHeaderInclude(StringRef HeaderName, +                             SmallVectorImpl<char> &Includes, +                             const LangOptions &LangOpts) { +  if (LangOpts.ObjC1) +    Includes += "#import \""; +  else +    Includes += "#include \""; +  Includes += HeaderName; +  Includes += "\"\n"; +} + +static void addHeaderInclude(const FileEntry *Header, +                             SmallVectorImpl<char> &Includes, +                             const LangOptions &LangOpts) { +  addHeaderInclude(Header->getName(), Includes, LangOpts); +} +  /// \brief Collect the set of header includes needed to construct the given   /// module and update the TopHeaders file set of the module.  /// @@ -142,7 +165,7 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts,                                          FileManager &FileMgr,                                          ModuleMap &ModMap,                                          clang::Module *Module, -                                        SmallString<256> &Includes) { +                                        SmallVectorImpl<char> &Includes) {    // Don't collect any headers for unavailable modules.    if (!Module->isAvailable())      return; @@ -151,24 +174,14 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts,    for (unsigned I = 0, N = Module->Headers.size(); I != N; ++I) {      const FileEntry *Header = Module->Headers[I];      Module->TopHeaders.insert(Header); -    if (LangOpts.ObjC1) -      Includes += "#import \""; -    else -      Includes += "#include \""; -    Includes += Header->getName(); -    Includes += "\"\n"; +    addHeaderInclude(Header, Includes, LangOpts);    }    if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {      Module->TopHeaders.insert(UmbrellaHeader);      if (Module->Parent) {        // Include the umbrella header for submodules. -      if (LangOpts.ObjC1) -        Includes += "#import \""; -      else -        Includes += "#include \""; -      Includes += UmbrellaHeader->getName(); -      Includes += "\"\n"; +      addHeaderInclude(UmbrellaHeader, Includes, LangOpts);      }    } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {      // Add all of the headers we find in this subdirectory. @@ -194,12 +207,7 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts,        }        // Include this header umbrella header for submodules. -      if (LangOpts.ObjC1) -        Includes += "#import \""; -      else -        Includes += "#include \""; -      Includes += Dir->path(); -      Includes += "\"\n"; +      addHeaderInclude(Dir->path(), Includes, LangOpts);      }    } @@ -255,77 +263,29 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,      return false;    } -  // Do we have an umbrella header for this module? -  const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader(); -   +  FileManager &FileMgr = CI.getFileManager(); +    // Collect the set of #includes we need to build the module.    SmallString<256> HeaderContents; -  collectModuleHeaderIncludes(CI.getLangOpts(), CI.getFileManager(), +  if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) +    addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts()); +  collectModuleHeaderIncludes(CI.getLangOpts(), FileMgr,      CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(),      Module, HeaderContents); -  if (UmbrellaHeader && HeaderContents.empty()) { -    // Simple case: we have an umbrella header and there are no additional -    // includes, we can just parse the umbrella header directly. -    setCurrentInput(FrontendInputFile(UmbrellaHeader->getName(), -                                      getCurrentFileKind(), -                                      Module->IsSystem)); -    return true; -  } -   -  FileManager &FileMgr = CI.getFileManager(); -  SmallString<128> HeaderName; -  time_t ModTime; -  if (UmbrellaHeader) { -    // Read in the umbrella header. -    // FIXME: Go through the source manager; the umbrella header may have -    // been overridden. -    std::string ErrorStr; -    llvm::MemoryBuffer *UmbrellaContents -      = FileMgr.getBufferForFile(UmbrellaHeader, &ErrorStr); -    if (!UmbrellaContents) { -      CI.getDiagnostics().Report(diag::err_missing_umbrella_header) -        << UmbrellaHeader->getName() << ErrorStr; -      return false; -    } -     -    // Combine the contents of the umbrella header with the automatically- -    // generated includes. -    SmallString<256> OldContents = HeaderContents; -    HeaderContents = UmbrellaContents->getBuffer(); -    HeaderContents += "\n\n"; -    HeaderContents += "/* Module includes */\n"; -    HeaderContents += OldContents; - -    // Pretend that we're parsing the umbrella header. -    HeaderName = UmbrellaHeader->getName(); -    ModTime = UmbrellaHeader->getModificationTime(); -     -    delete UmbrellaContents; -  } else { -    // Pick an innocuous-sounding name for the umbrella header. -    HeaderName = Module->Name + ".h"; -    if (FileMgr.getFile(HeaderName, /*OpenFile=*/false,  -                        /*CacheFailure=*/false)) { -      // Try again! -      HeaderName = Module->Name + "-module.h";       -      if (FileMgr.getFile(HeaderName, /*OpenFile=*/false,  -                          /*CacheFailure=*/false)) { -        // Pick something ridiculous and go with it. -        HeaderName = Module->Name + "-module.hmod"; -      } -    } -    ModTime = time(0); -  } -   -  // Remap the contents of the header name we're using to our synthesized -  // buffer. -  const FileEntry *HeaderFile = FileMgr.getVirtualFile(HeaderName,  + +  StringRef InputName = Module::getModuleInputBufferName(); + +  // We consistently construct a buffer as input to build the module. +  // This means the main file for modules will always be a virtual one. +  // FIXME: Maybe allow using a memory buffer as input directly instead of +  // messing with virtual files. +  const FileEntry *HeaderFile = FileMgr.getVirtualFile(InputName,                                                          HeaderContents.size(),  -                                                       ModTime); +                                                       time(0));    llvm::MemoryBuffer *HeaderContentsBuf      = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents);    CI.getSourceManager().overrideFileContents(HeaderFile, HeaderContentsBuf);   -  setCurrentInput(FrontendInputFile(HeaderName, getCurrentFileKind(), +  setCurrentInput(FrontendInputFile(InputName, getCurrentFileKind(),                                      Module->IsSystem));    return true;  } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index cdb9646758c..d060e795ded 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1111,7 +1111,7 @@ ASTReader::ASTReadResult ASTReader::ReadSLocEntryRecord(int ID) {        return Failure;      } -    if (!DisableValidation && +    if (!DisableValidation && !OverriddenBuffer &&          ((off_t)Record[4] != File->getSize()  #if !defined(LLVM_ON_WIN32)          // In our regression testing, the Windows file system seems to  | 

