r228234 - [modules] When using -E, we may try to merge decls despite having no Sema

Richard Smith richard-llvm at metafoo.co.uk
Wed Feb 4 15:37:59 PST 2015


Author: rsmith
Date: Wed Feb  4 17:37:59 2015
New Revision: 228234

URL: http://llvm.org/viewvc/llvm-project?rev=228234&view=rev
Log:
[modules] When using -E, we may try to merge decls despite having no Sema
object. In such a case, use the TU's DC for merging global decls rather than
giving up when we find there is no TU scope.

Ultimately, we should probably avoid all loading of decls when preprocessing,
but there are other reasonable use cases for loading an AST file with no Sema
object for which this is the right thing.

Added:
    cfe/trunk/test/Modules/Inputs/preprocess/
    cfe/trunk/test/Modules/Inputs/preprocess/file.h
    cfe/trunk/test/Modules/Inputs/preprocess/fwd.h
    cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap
Modified:
    cfe/trunk/include/clang/Frontend/CompilerInstance.h
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/test/Modules/preprocess.m

Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=228234&r1=228233&r2=228234&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Wed Feb  4 17:37:59 2015
@@ -588,7 +588,7 @@ public:
   /// Create an external AST source to read a PCH file.
   ///
   /// \return - The new object on success, or null on failure.
-  static ExternalASTSource *createPCHExternalASTSource(
+  static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
       StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
       bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
       void *DeserializationListener, bool OwnDeserializationListener,

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=228234&r1=228233&r2=228234&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Wed Feb  4 17:37:59 2015
@@ -388,32 +388,30 @@ void CompilerInstance::createASTContext(
 void CompilerInstance::createPCHExternalASTSource(
     StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors,
     void *DeserializationListener, bool OwnDeserializationListener) {
-  IntrusiveRefCntPtr<ExternalASTSource> Source;
   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
-  Source = createPCHExternalASTSource(
+  ModuleManager = createPCHExternalASTSource(
       Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
       AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
       DeserializationListener, OwnDeserializationListener, Preamble,
       getFrontendOpts().UseGlobalModuleIndex);
-  ModuleManager = static_cast<ASTReader*>(Source.get());
-  getASTContext().setExternalSource(Source);
 }
 
-ExternalASTSource *CompilerInstance::createPCHExternalASTSource(
+IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
     StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
     bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
     void *DeserializationListener, bool OwnDeserializationListener,
     bool Preamble, bool UseGlobalModuleIndex) {
   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
 
-  std::unique_ptr<ASTReader> Reader;
-  Reader.reset(new ASTReader(PP, Context,
-                             Sysroot.empty() ? "" : Sysroot.c_str(),
-                             DisablePCHValidation,
-                             AllowPCHWithCompilerErrors,
-                             /*AllowConfigurationMismatch*/false,
-                             HSOpts.ModulesValidateSystemHeaders,
-                             UseGlobalModuleIndex));
+  IntrusiveRefCntPtr<ASTReader> Reader(
+      new ASTReader(PP, Context, Sysroot.empty() ? "" : Sysroot.c_str(),
+                    DisablePCHValidation, AllowPCHWithCompilerErrors,
+                    /*AllowConfigurationMismatch*/ false,
+                    HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
+
+  // We need the external source to be set up before we read the AST, because
+  // eagerly-deserialized declarations may use it.
+  Context.setExternalSource(Reader.get());
 
   Reader->setDeserializationListener(
       static_cast<ASTDeserializationListener *>(DeserializationListener),
@@ -427,7 +425,7 @@ ExternalASTSource *CompilerInstance::cre
     // Set the predefines buffer as suggested by the PCH reader. Typically, the
     // predefines buffer will be empty.
     PP.setPredefines(Reader->getSuggestedPredefines());
-    return Reader.release();
+    return Reader;
 
   case ASTReader::Failure:
     // Unrecoverable failure: don't even try to process the input file.
@@ -442,6 +440,7 @@ ExternalASTSource *CompilerInstance::cre
     break;
   }
 
+  Context.setExternalSource(nullptr);
   return nullptr;
 }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=228234&r1=228233&r2=228234&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Feb  4 17:37:59 2015
@@ -2591,6 +2591,11 @@ DeclContext *ASTDeclReader::getPrimaryCo
     return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
                                                       : nullptr;
 
+  // We can see the TU here only if we have no Sema object. In that case,
+  // there's no TU scope to look in, so using the DC alone is sufficient.
+  if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
+    return TU;
+
   return nullptr;
 }
 

Added: cfe/trunk/test/Modules/Inputs/preprocess/file.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/file.h?rev=228234&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/preprocess/file.h (added)
+++ cfe/trunk/test/Modules/Inputs/preprocess/file.h Wed Feb  4 17:37:59 2015
@@ -0,0 +1,3 @@
+struct __FILE;
+#include "fwd.h"
+typedef struct __FILE FILE;

Added: cfe/trunk/test/Modules/Inputs/preprocess/fwd.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/fwd.h?rev=228234&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/preprocess/fwd.h (added)
+++ cfe/trunk/test/Modules/Inputs/preprocess/fwd.h Wed Feb  4 17:37:59 2015
@@ -0,0 +1 @@
+struct __FILE;

Added: cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap?rev=228234&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap (added)
+++ cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap Wed Feb  4 17:37:59 2015
@@ -0,0 +1,2 @@
+module fwd { header "fwd.h" export * }
+module file { header "file.h" export * }

Modified: cfe/trunk/test/Modules/preprocess.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess.m?rev=228234&r1=228233&r2=228234&view=diff
==============================================================================
--- cfe/trunk/test/Modules/preprocess.m (original)
+++ cfe/trunk/test/Modules/preprocess.m Wed Feb  4 17:37:59 2015
@@ -1,9 +1,14 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -include %S/Inputs/preprocess-prefix.h -E %s | FileCheck -strict-whitespace %s
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -x objective-c-header -emit-pch %S/Inputs/preprocess-prefix.h -o %t.pch
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -include-pch %t.pch -E %s | FileCheck -strict-whitespace %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -include %S/Inputs/preprocess-prefix.h -E %s | FileCheck -strict-whitespace %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c-header -emit-pch %S/Inputs/preprocess-prefix.h -o %t.pch
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -include-pch %t.pch -E %s | FileCheck -strict-whitespace %s
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c++ -include %S/Inputs/preprocess-prefix.h -E %s | FileCheck -strict-whitespace %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c++-header -emit-pch %S/Inputs/preprocess-prefix.h -o %t.pch
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c++ -include-pch %t.pch -E %s | FileCheck -strict-whitespace %s
 #import "diamond_right.h"
 #import "diamond_right.h" // to check that imports get their own line
+#include "file.h"
 void test() {
   top_left_before();
   left_and_right();
@@ -15,6 +20,7 @@ void test() {
 
 // CHECK: @import diamond_right; /* clang -E: implicit import for "{{.*}}diamond_right.h" */{{$}}
 // CHECK: @import diamond_right; /* clang -E: implicit import for "{{.*}}diamond_right.h" */{{$}}
+// CHECK: @import file; /* clang -E: implicit import for "{{.*}}file.h" */{{$}}
 // CHECK-NEXT: void test() {{{$}}
 // CHECK-NEXT:    top_left_before();{{$}}
 // CHECK-NEXT:    left_and_right();{{$}}





More information about the cfe-commits mailing list