Support object-file-wrapped modules in clang -module-file-info.
authorAdrian Prantl <aprantl@apple.com>
Wed, 17 Aug 2016 23:13:53 +0000 (23:13 +0000)
committerAdrian Prantl <aprantl@apple.com>
Wed, 17 Aug 2016 23:13:53 +0000 (23:13 +0000)
rdar://problem/24504815

llvm-svn: 279004

clang/include/clang/Frontend/FrontendActions.h
clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
clang/lib/Frontend/FrontendActions.cpp
clang/test/Modules/module_file_info.m

index 0cbacbb..b56a04a 100644 (file)
@@ -138,6 +138,7 @@ class DumpModuleInfoAction : public ASTFrontendAction {
 protected:
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) override;
+  bool BeginInvocation(CompilerInstance &CI) override;
   void ExecuteAction() override;
 
 public:
index de40e41..f2090f9 100644 (file)
@@ -314,25 +314,29 @@ ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
 
 void ObjectFilePCHContainerReader::ExtractPCH(
     llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const {
-  if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) {
-    auto *Obj = OF.get().get();
-    bool IsCOFF = isa<llvm::object::COFFObjectFile>(Obj);
+  auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer);
+  if (OFOrErr) {
+    auto &OF = OFOrErr.get();
+    bool IsCOFF = isa<llvm::object::COFFObjectFile>(*OF);
     // Find the clang AST section in the container.
-    for (auto &Section : OF->get()->sections()) {
+    for (auto &Section : OF->sections()) {
       StringRef Name;
       Section.getName(Name);
-      if ((!IsCOFF && Name == "__clangast") ||
-          ( IsCOFF && Name ==   "clangast")) {
+      if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) {
         StringRef Buf;
         Section.getContents(Buf);
-        StreamFile.init((const unsigned char *)Buf.begin(),
-                        (const unsigned char *)Buf.end());
-        return;
+        return StreamFile.init((const unsigned char *)Buf.begin(),
+                               (const unsigned char *)Buf.end());
       }
     }
   }
-
-  // As a fallback, treat the buffer as a raw AST.
-  StreamFile.init((const unsigned char *)Buffer.getBufferStart(),
-                  (const unsigned char *)Buffer.getBufferEnd());
+  handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) {
+    if (EIB.convertToErrorCode() ==
+        llvm::object::object_error::invalid_file_type)
+      // As a fallback, treat the buffer as a raw AST.
+      StreamFile.init((const unsigned char *)Buffer.getBufferStart(),
+                      (const unsigned char *)Buffer.getBufferEnd());
+    else
+      EIB.log(llvm::errs());
+  });
 }
index babaa2d..88ff7e0 100644 (file)
@@ -596,6 +596,13 @@ namespace {
   };
 }
 
+bool DumpModuleInfoAction::BeginInvocation(CompilerInstance &CI) {
+  // The Object file reader also supports raw ast files and there is no point in
+  // being strict about the module file format in -module-file-info mode.
+  CI.getHeaderSearchOpts().ModuleFormat = "obj";
+  return true;
+}
+
 void DumpModuleInfoAction::ExecuteAction() {
   // Set up the output file.
   std::unique_ptr<llvm::raw_fd_ostream> OutFile;
@@ -608,6 +615,7 @@ void DumpModuleInfoAction::ExecuteAction() {
   llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
 
   Out << "Information for module file '" << getCurrentFile() << "':\n";
+
   Preprocessor &PP = getCompilerInstance().getPreprocessor();
   DumpModuleInfoListener Listener(Out);
   HeaderSearchOptions &HSOpts =
index 8693d2b..6f32659 100644 (file)
@@ -1,10 +1,13 @@
 
 @import DependsOnModule;
 
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -w -Wunused -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE -fmodule-feature myfeature %s
+// RUN: rm -rf %t %t-obj
+// RUN: %clang_cc1 -w -Wunused -fmodules -fmodule-format=raw -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE -fmodule-feature myfeature %s
 // RUN: %clang_cc1 -module-file-info %t/DependsOnModule.pcm | FileCheck %s
 
+// RUN: %clang_cc1 -w -Wunused -fmodules -fmodule-format=obj -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-obj -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE -fmodule-feature myfeature %s
+// RUN: %clang_cc1 -module-file-info %t-obj/DependsOnModule.pcm | FileCheck %s
+
 // CHECK: Generated by this Clang:
 
 // CHECK: Module name: DependsOnModule