r301725 - Add pragma to perform module import and use it in -E output.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 28 17:34:48 PDT 2017


Author: rsmith
Date: Fri Apr 28 19:34:47 2017
New Revision: 301725

URL: http://llvm.org/viewvc/llvm-project?rev=301725&view=rev
Log:
Add pragma to perform module import and use it in -E output.

Many of our supported configurations support modules but do not have any
first-class syntax to perform a module import. This leaves us with a problem:
there is no way to represent the expansion of a #include that imports a module
in the -E output for such languages. (We don't want to just leave it as a
#include because that requires the consumer of the preprocessed source to have
the same file system layout and include paths as the creator.)

This patch adds a new pragma:

  #pragma clang module import MODULE.NAME.HERE

that imports a module, and changes -E and -frewrite-includes to use it when
rewriting a #include that maps to a module import. We don't make any attempt
to use a native language syntax import if one exists, to get more consistent
output. (If in the future, @import and #include have different semantics in
some way, the pragma will track the #include semantics.)

Added:
    cfe/trunk/test/Modules/import-syntax.c
    cfe/trunk/test/Preprocessor/pragma_module.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
    cfe/trunk/lib/Frontend/Rewrite/InclusionRewriter.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/Pragma.cpp
    cfe/trunk/test/Frontend/rewrite-includes-modules.c
    cfe/trunk/test/Modules/crash-vfs-path-emptydir-entries.m
    cfe/trunk/test/Modules/crash-vfs-path-symlink-component.m
    cfe/trunk/test/Modules/crash-vfs-path-symlink-topheader.m
    cfe/trunk/test/Modules/crash-vfs-path-traversal.m
    cfe/trunk/test/Modules/crash-vfs-relative-overlay.m
    cfe/trunk/test/Modules/preprocess-module.cpp
    cfe/trunk/test/Modules/preprocess.cpp
    cfe/trunk/test/Modules/preprocess.m
    cfe/trunk/test/Preprocessor/pp-modules.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Apr 28 19:34:47 2017
@@ -475,6 +475,8 @@ def warn_pragma_pop_macro_no_push : Warn
 def warn_pragma_message : Warning<"%0">,
    InGroup<PoundPragmaMessage>, DefaultWarnNoWerror;
 def err_pragma_message : Error<"%0">;
+def err_pragma_module_import_expected_module_name : Error<
+  "expected %select{identifier in|'.' or end of directive after}0 module name">;
 def warn_pragma_ignored : Warning<"unknown pragma ignored">,
    InGroup<UnknownPragmas>, DefaultIgnore;
 def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Apr 28 19:34:47 2017
@@ -1263,6 +1263,10 @@ public:
       CachedTokens[CachedLexPos-1] = Tok;
   }
 
+  /// Enter an annotation token into the token stream.
+  void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind,
+                            void *AnnotationVal);
+
   /// Update the current token to represent the provided
   /// identifier, in order to cache an action performed by typo correction.
   void TypoCorrectToken(const Token &Tok) {
@@ -1963,6 +1967,7 @@ public:
   void HandlePragmaPoison();
   void HandlePragmaSystemHeader(Token &SysHeaderTok);
   void HandlePragmaDependency(Token &DependencyTok);
+  void HandlePragmaModuleImport(Token &Tok);
   void HandlePragmaPushMacro(Token &Tok);
   void HandlePragmaPopMacro(Token &Tok);
   void HandlePragmaIncludeAlias(Token &Tok);

Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Fri Apr 28 19:34:47 2017
@@ -324,43 +324,50 @@ void PrintPPOutputPPCallbacks::Inclusion
                                                   StringRef SearchPath,
                                                   StringRef RelativePath,
                                                   const Module *Imported) {
-  if (Imported) {
-    // When preprocessing, turn implicit imports into @imports.
-    // FIXME: This is a stop-gap until a more comprehensive "preprocessing with
-    // modules" solution is introduced.
+  // In -dI mode, dump #include directives prior to dumping their content or
+  // interpretation.
+  if (DumpIncludeDirectives) {
     startNewLineIfNeeded();
     MoveToLine(HashLoc);
-    if (PP.getLangOpts().ObjC2) {
-      OS << "@import " << Imported->getFullModuleName() << ";"
-         << " /* clang -E: implicit import for \"" << File->getName()
-         << "\" */";
-    } else {
-      const std::string TokenText = PP.getSpelling(IncludeTok);
-      assert(!TokenText.empty());
-      OS << "#" << TokenText << " "
-         << (IsAngled ? '<' : '"')
-         << FileName
-         << (IsAngled ? '>' : '"')
-         << " /* clang -E: implicit import for module "
-         << Imported->getFullModuleName() << " */";
-    }
-    // Since we want a newline after the @import, but not a #<line>, start a new
-    // line immediately.
-    EmittedTokensOnThisLine = true;
+    const std::string TokenText = PP.getSpelling(IncludeTok);
+    assert(!TokenText.empty());
+    OS << "#" << TokenText << " "
+       << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"')
+       << " /* clang -E -dI */";
+    setEmittedDirectiveOnThisLine();
     startNewLineIfNeeded();
-  } else {
-    // Not a module import; it's a more vanilla inclusion of some file using one
-    // of: #include, #import, #include_next, #include_macros.
-    if (DumpIncludeDirectives) {
+  }
+
+  // When preprocessing, turn implicit imports into module import pragmas.
+  if (Imported) {
+    switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
+    case tok::pp_include:
+    case tok::pp_import:
+    case tok::pp_include_next:
       startNewLineIfNeeded();
       MoveToLine(HashLoc);
-      const std::string TokenText = PP.getSpelling(IncludeTok);
-      assert(!TokenText.empty());
-      OS << "#" << TokenText << " "
+      OS << "#pragma clang module import " << Imported->getFullModuleName()
+         << " /* clang -E: implicit import for "
+         << "#" << PP.getSpelling(IncludeTok) << " "
          << (IsAngled ? '<' : '"') << FileName << (IsAngled ? '>' : '"')
-         << " /* clang -E -dI */";
-      setEmittedDirectiveOnThisLine();
+         << " */";
+      // Since we want a newline after the pragma, but not a #<line>, start a
+      // new line immediately.
+      EmittedTokensOnThisLine = true;
       startNewLineIfNeeded();
+      break;
+
+    case tok::pp___include_macros:
+      // #__include_macros has no effect on a user of a preprocessed source
+      // file; the only effect is on preprocessing.
+      //
+      // FIXME: That's not *quite* true: it causes the module in question to
+      // be loaded, which can affect downstream diagnostics.
+      break;
+
+    default:
+      llvm_unreachable("unknown include directive kind");
+      break;
     }
   }
 }

Modified: cfe/trunk/lib/Frontend/Rewrite/InclusionRewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/InclusionRewriter.cpp?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/Rewrite/InclusionRewriter.cpp (original)
+++ cfe/trunk/lib/Frontend/Rewrite/InclusionRewriter.cpp Fri Apr 28 19:34:47 2017
@@ -132,7 +132,7 @@ void InclusionRewriter::WriteLineInfo(St
 }
 
 void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod) {
-  OS << "@import " << Mod->getFullModuleName() << ";"
+  OS << "#pragma clang module import " << Mod->getFullModuleName()
      << " /* clang -frewrite-includes: implicit import */" << MainEOL;
 }
 
@@ -450,9 +450,7 @@ bool InclusionRewriter::Process(FileID F
               WriteLineInfo(FileName, Line - 1, FileType, "");
             StringRef LineInfoExtra;
             SourceLocation Loc = HashToken.getLocation();
-            if (const Module *Mod = PP.getLangOpts().ObjC2
-                                        ? FindModuleAtLocation(Loc)
-                                        : nullptr)
+            if (const Module *Mod = FindModuleAtLocation(Loc))
               WriteImplicitModuleImport(Mod);
             else if (const IncludedFile *Inc = FindIncludeAtLocation(Loc)) {
               // include and recursively process the file

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Apr 28 19:34:47 2017
@@ -1588,18 +1588,18 @@ bool Preprocessor::ConcatenateIncludeNam
 }
 
 /// \brief Push a token onto the token stream containing an annotation.
-static void EnterAnnotationToken(Preprocessor &PP,
-                                 SourceLocation Begin, SourceLocation End,
-                                 tok::TokenKind Kind, void *AnnotationVal) {
+void Preprocessor::EnterAnnotationToken(SourceRange Range,
+                                        tok::TokenKind Kind,
+                                        void *AnnotationVal) {
   // FIXME: Produce this as the current token directly, rather than
   // allocating a new token for it.
   auto Tok = llvm::make_unique<Token[]>(1);
   Tok[0].startToken();
   Tok[0].setKind(Kind);
-  Tok[0].setLocation(Begin);
-  Tok[0].setAnnotationEndLoc(End);
+  Tok[0].setLocation(Range.getBegin());
+  Tok[0].setAnnotationEndLoc(Range.getEnd());
   Tok[0].setAnnotationValue(AnnotationVal);
-  PP.EnterTokenStream(std::move(Tok), 1, true);
+  EnterTokenStream(std::move(Tok), 1, true);
 }
 
 /// \brief Produce a diagnostic informing the user that a #include or similar
@@ -2021,7 +2021,8 @@ void Preprocessor::HandleIncludeDirectiv
 
       if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
           tok::pp___include_macros)
-        EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include, M);
+        EnterAnnotationToken(SourceRange(HashLoc, End),
+                             tok::annot_module_include, M);
     }
     return;
   }
@@ -2059,7 +2060,7 @@ void Preprocessor::HandleIncludeDirectiv
     // submodule.
     // FIXME: There's no point doing this if we're handling a #__include_macros
     // directive.
-    EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin, M);
+    EnterAnnotationToken(SourceRange(HashLoc, End), tok::annot_module_begin, M);
   }
 }
 

Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Fri Apr 28 19:34:47 2017
@@ -534,6 +534,47 @@ void Preprocessor::HandlePragmaDependenc
   }
 }
 
+void Preprocessor::HandlePragmaModuleImport(Token &ImportTok) {
+  SourceLocation ImportLoc = ImportTok.getLocation();
+
+  Token Tok;
+
+  llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8> ModuleName;
+  while (true) {
+    LexUnexpandedToken(Tok);
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok.getLocation(),
+           diag::err_pragma_module_import_expected_module_name) << 0;
+      return;
+    }
+
+    ModuleName.emplace_back(Tok.getIdentifierInfo(), Tok.getLocation());
+
+    LexUnexpandedToken(Tok);
+    assert(Tok.isNot(tok::eof));
+    if (Tok.is(tok::eod))
+      break;
+    if (Tok.isNot(tok::period)) {
+      Diag(Tok.getLocation(),
+           diag::err_pragma_module_import_expected_module_name) << 1;
+      return;
+    }
+  }
+
+  // If we have a non-empty module path, load the named module.
+  Module *Imported =
+      TheModuleLoader.loadModule(ImportLoc, ModuleName, Module::Hidden,
+                                 /*IsIncludeDirective=*/false);
+  if (!Imported)
+    return;
+
+  makeModuleVisible(Imported, ImportLoc);
+  EnterAnnotationToken(SourceRange(ImportLoc, Tok.getLocation()),
+                       tok::annot_module_include, Imported);
+  if (Callbacks)
+    Callbacks->moduleImport(ImportLoc, ModuleName, Imported);
+}
+
 /// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
 /// Return the IdentifierInfo* associated with the macro to push or pop.
 IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
@@ -1301,6 +1342,19 @@ public:
   }
 };
 
+/// Handle the clang \#pragma module import extension. The syntax is:
+/// \code
+///   #pragma clang module import some.module.name
+/// \endcode
+struct PragmaModuleImportHandler : public PragmaHandler {
+  PragmaModuleImportHandler() : PragmaHandler("import") {}
+
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &ImportTok) override {
+    PP.HandlePragmaModuleImport(ImportTok);
+  }
+};
+
 /// PragmaPushMacroHandler - "\#pragma push_macro" saves the value of the
 /// macro on the top of the stack.
 struct PragmaPushMacroHandler : public PragmaHandler {
@@ -1524,6 +1578,11 @@ void Preprocessor::RegisterBuiltinPragma
   AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
   AddPragmaHandler("clang", new PragmaAssumeNonNullHandler());
 
+  // #pragma clang module ...
+  auto *ModuleHandler = new PragmaNamespace("module");
+  AddPragmaHandler("clang", ModuleHandler);
+  ModuleHandler->AddPragma(new PragmaModuleImportHandler());
+
   AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
   AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
   AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());

Modified: cfe/trunk/test/Frontend/rewrite-includes-modules.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/rewrite-includes-modules.c?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Frontend/rewrite-includes-modules.c (original)
+++ cfe/trunk/test/Frontend/rewrite-includes-modules.c Fri Apr 28 19:34:47 2017
@@ -1,22 +1,27 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c %s -F %S/../Modules/Inputs -E -frewrite-includes -o - | FileCheck %s
+// RUN: mkdir %t
+// RUN: echo 'extern int dummy;' > %t/dummy.h
+// RUN: echo 'module dummy { header "dummy.h" }' > %t/module.modulemap
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t %s -I%t -E -frewrite-includes -o - | FileCheck %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c %s -I%t -E -frewrite-includes -o - | FileCheck %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ %s -I%t -E -frewrite-includes -o - | FileCheck %s
 
 int bar();
-#include <Module/Module.h>
+#include "dummy.h"
 int foo();
-#include <Module/Module.h>
+#include "dummy.h"
 
 // CHECK: int bar();{{$}}
 // CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}}
-// CHECK-NEXT: #include <Module/Module.h>{{$}}
+// CHECK-NEXT: #include "dummy.h"{{$}}
 // CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}}
-// CHECK-NEXT: # 5 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
-// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}}
-// CHECK-NEXT: # 6 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
+// CHECK-NEXT: # 10 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
+// CHECK-NEXT: #pragma clang module import dummy /* clang -frewrite-includes: implicit import */{{$}}
+// CHECK-NEXT: # 11 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
 // CHECK-NEXT: int foo();{{$}}
 // CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}}
-// CHECK-NEXT: #include <Module/Module.h>{{$}}
+// CHECK-NEXT: #include "dummy.h"{{$}}
 // CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}}
-// CHECK-NEXT: # 7 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
-// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}}
-// CHECK-NEXT: # 8 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
+// CHECK-NEXT: # 12 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
+// CHECK-NEXT: #pragma clang module import dummy /* clang -frewrite-includes: implicit import */{{$}}
+// CHECK-NEXT: # 13 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}

Modified: cfe/trunk/test/Modules/crash-vfs-path-emptydir-entries.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/crash-vfs-path-emptydir-entries.m?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/crash-vfs-path-emptydir-entries.m (original)
+++ cfe/trunk/test/Modules/crash-vfs-path-emptydir-entries.m Fri Apr 28 19:34:47 2017
@@ -27,7 +27,7 @@
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.m
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
 
-// CHECKSRC: @import cstd.stdio;
+// CHECKSRC: #pragma clang module import cstd.stdio
 
 // CHECKSH: # Crash reproducer
 // CHECKSH-NEXT: # Driver args: "-fsyntax-only"

Modified: cfe/trunk/test/Modules/crash-vfs-path-symlink-component.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/crash-vfs-path-symlink-component.m?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/crash-vfs-path-symlink-component.m (original)
+++ cfe/trunk/test/Modules/crash-vfs-path-symlink-component.m Fri Apr 28 19:34:47 2017
@@ -28,7 +28,7 @@
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.m
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
 
-// CHECKSRC: @import cstd.stdio;
+// CHECKSRC: #pragma clang module import cstd.stdio
 
 // CHECKSH: # Crash reproducer
 // CHECKSH-NEXT: # Driver args: "-fsyntax-only"
@@ -65,4 +65,4 @@
 // RUN:     -fmodules-cache-path=%t/m/ 2>&1 \
 // RUN:     | FileCheck %s --check-prefix=CHECKOVERLAY
 
-// CHECKOVERLAY: @import cstd.stdio; /* clang -E: implicit import for "/{{[^ ].*}}/i/usr/x/../stdio.h" */
+// CHECKOVERLAY: #pragma clang module import cstd.stdio /* clang -E: implicit import

Modified: cfe/trunk/test/Modules/crash-vfs-path-symlink-topheader.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/crash-vfs-path-symlink-topheader.m?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/crash-vfs-path-symlink-topheader.m (original)
+++ cfe/trunk/test/Modules/crash-vfs-path-symlink-topheader.m Fri Apr 28 19:34:47 2017
@@ -29,7 +29,7 @@
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.m
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
 
-// CHECKSRC: @import cstd.stdio;
+// CHECKSRC: #pragma clang module import cstd.stdio
 
 // CHECKSH: # Crash reproducer
 // CHECKSH-NEXT: # Driver args: "-fsyntax-only"

Modified: cfe/trunk/test/Modules/crash-vfs-path-traversal.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/crash-vfs-path-traversal.m?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/crash-vfs-path-traversal.m (original)
+++ cfe/trunk/test/Modules/crash-vfs-path-traversal.m Fri Apr 28 19:34:47 2017
@@ -25,7 +25,7 @@
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.m
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
 
-// CHECKSRC: @import cstd.stdio;
+// CHECKSRC: #pragma clang module import cstd.stdio
 
 // CHECKSH: # Crash reproducer
 // CHECKSH-NEXT: # Driver args: "-fsyntax-only"
@@ -62,4 +62,4 @@
 // RUN:     -fmodules-cache-path=%t/m/ 2>&1 \
 // RUN:     | FileCheck %s --check-prefix=CHECKOVERLAY
 
-// CHECKOVERLAY: @import cstd.stdio; /* clang -E: implicit import for "/{{[^ ].*}}/usr/././//////include/../include/./././../include/stdio.h" */
+// CHECKOVERLAY: #pragma clang module import cstd.stdio /* clang -E: implicit import

Modified: cfe/trunk/test/Modules/crash-vfs-relative-overlay.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/crash-vfs-relative-overlay.m?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/crash-vfs-relative-overlay.m (original)
+++ cfe/trunk/test/Modules/crash-vfs-relative-overlay.m Fri Apr 28 19:34:47 2017
@@ -24,7 +24,7 @@
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.m
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
 
-// CHECKSRC: @import cstd.stdio;
+// CHECKSRC: #pragma clang module import cstd.stdio
 
 // CHECKSH: # Crash reproducer
 // CHECKSH-NEXT: # Driver args: "-fsyntax-only"
@@ -58,4 +58,4 @@
 // RUN:     -fmodules-cache-path=%t/m/ 2>&1 \
 // RUN:     | FileCheck %s --check-prefix=CHECKOVERLAY
 
-// CHECKOVERLAY: @import cstd.stdio; /* clang -E: implicit import for "/{{[^ ].*}}/usr/include/stdio.h" */
+// CHECKOVERLAY: #pragma clang module import cstd.stdio /* clang -E: implicit import

Added: cfe/trunk/test/Modules/import-syntax.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/import-syntax.c?rev=301725&view=auto
==============================================================================
--- cfe/trunk/test/Modules/import-syntax.c (added)
+++ cfe/trunk/test/Modules/import-syntax.c Fri Apr 28 19:34:47 2017
@@ -0,0 +1,35 @@
+// RUN: rm -rf %t
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c -DINCLUDE %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x objective-c -DINCLUDE %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c++ -DINCLUDE %s
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x objective-c -DAT_IMPORT=1 %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x objective-c++ -DAT_IMPORT=1 %s
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c++ -fmodules-ts -DIMPORT=1 %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x objective-c++ -fmodules-ts -DIMPORT=1 %s
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c -DPRAGMA %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x objective-c -DPRAGMA %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c++ -DPRAGMA %s
+
+// expected-no-diagnostics
+
+// All forms of module import should make both declarations and macros visible.
+
+#if INCLUDE
+#include "dummy.h"
+#elif AT_IMPORT
+ at import dummy;
+#elif IMPORT
+import dummy;
+#elif PRAGMA
+#pragma clang module import dummy
+#endif
+
+#ifndef DUMMY_H
+#error "macros not visible"
+#endif
+
+void *p = &dummy1;

Modified: cfe/trunk/test/Modules/preprocess-module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess-module.cpp?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/preprocess-module.cpp (original)
+++ cfe/trunk/test/Modules/preprocess-module.cpp Fri Apr 28 19:34:47 2017
@@ -7,6 +7,6 @@
 // CHECK: # 1 "<module-includes>"
 // CHECK: # 1 "{{.*}}file.h" 1
 // CHECK: struct __FILE;
-// CHECK: #include "fwd.h" /* clang -E: implicit import for module fwd */
+// CHECK: #pragma clang module import fwd /* clang -E: implicit import for #include "fwd.h" */
 // CHECK: typedef struct __FILE FILE;
 // CHECK: # 2 "<module-includes>" 2

Modified: cfe/trunk/test/Modules/preprocess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess.cpp?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/preprocess.cpp (original)
+++ cfe/trunk/test/Modules/preprocess.cpp Fri Apr 28 19:34:47 2017
@@ -1,24 +1,30 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x c++ -E %s | \
-// RUN:   FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=CXX --check-prefix=CXX-DASHE
+// RUN:   FileCheck -strict-whitespace %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x objective-c -E %s | \
-// RUN:   FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=OBJC
+// RUN:   FileCheck -strict-whitespace %s
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x c++ -E -frewrite-includes %s | \
-// RUN:   FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=CXX
+// RUN:   FileCheck -strict-whitespace %s --check-prefix=REWRITE
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -x objective-c -E -frewrite-includes %s | \
-// RUN:   FileCheck -strict-whitespace %s --check-prefix=CHECK --check-prefix=OBJC
+// RUN:   FileCheck -strict-whitespace %s --check-prefix=REWRITE
 #include "dummy.h"
 #include "dummy.h"
 foo bar baz
 
-// The weird {{ }} here is to prevent the -frewrite-includes test from matching its own CHECK lines.
+// EOF marker to ensure -frewrite-includes doesn't match its own CHECK lines.
 
-// CXX: #include{{ }}"dummy.h"
-// CXX-DASHE-SAME: /* clang -E: implicit import for module dummy */
-// CXX: #include{{ }}"dummy.h"
-// CXX-DASHE-SAME: /* clang -E: implicit import for module dummy */
-// CXX: foo bar baz
-
-// OBJC: @import{{ }}dummy; /* clang 
-// OBJC: @import{{ }}dummy; /* clang 
-// OBJC: foo bar baz
+// REWRITE: #if 0
+// REWRITE: #include{{ }}"dummy.h"
+// REWRITE: #endif
+
+// CHECK: #pragma clang module import dummy /* clang {{.*}} implicit import
+
+// REWRITE: #if 0
+// REWRITE: #include{{ }}"dummy.h"
+// REWRITE: #endif
+
+// CHECK: #pragma clang module import dummy /* clang {{.*}} implicit import
+
+// CHECK: foo bar baz
+
+// REWRITE: // {{EOF}} marker

Modified: cfe/trunk/test/Modules/preprocess.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess.m?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Modules/preprocess.m (original)
+++ cfe/trunk/test/Modules/preprocess.m Fri Apr 28 19:34:47 2017
@@ -16,11 +16,11 @@ void test() {
 
 
 // CHECK: int left_and_right(int *);{{$}}
-// CHECK-NEXT: @import diamond_left; /* clang -E: implicit import for "{{.*}}diamond_left.h" */{{$}}
+// CHECK-NEXT: #pragma clang module import diamond_left /* clang -E: implicit import for #import "diamond_left.h" */{{$}}
 
-// 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: #pragma clang module import diamond_right /* clang -E: implicit import for #import "diamond_right.h" */{{$}}
+// CHECK: #pragma clang module import diamond_right /* clang -E: implicit import for #import "diamond_right.h" */{{$}}
+// CHECK: #pragma clang module import file /* clang -E: implicit import for #include "file.h" */{{$}}
 // CHECK-NEXT: void test() {{{$}}
 // CHECK-NEXT:    top_left_before();{{$}}
 // CHECK-NEXT:    left_and_right();{{$}}

Modified: cfe/trunk/test/Preprocessor/pp-modules.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pp-modules.c?rev=301725&r1=301724&r2=301725&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/pp-modules.c (original)
+++ cfe/trunk/test/Preprocessor/pp-modules.c Fri Apr 28 19:34:47 2017
@@ -3,13 +3,13 @@
 
 // CHECK: int bar();
 int bar();
-// CHECK: @import Module; /* clang -E: implicit import for "{{.*Headers[/\\]Module.h}}" */
+// CHECK: #pragma clang module import Module /* clang -E: implicit import for #include <Module/Module.h> */{{$}}
 #include <Module/Module.h>
 // CHECK: int foo();
 int foo();
-// CHECK: @import Module; /* clang -E: implicit import for "{{.*Headers[/\\]Module.h}}" */
+// CHECK: #pragma clang module import Module /* clang -E: implicit import for #include <Module/Module.h> */{{$}}
 #include <Module/Module.h>
 
 #include "pp-modules.h" // CHECK: # 1 "{{.*}}pp-modules.h" 1
-// CHECK: @import Module; /* clang -E: implicit import for "{{.*}}Module.h" */{{$}}
+// CHECK: #pragma clang module import Module /* clang -E: implicit import for #include <Module/Module.h> */{{$}}
 // CHECK: # 14 "{{.*}}pp-modules.c" 2

Added: cfe/trunk/test/Preprocessor/pragma_module.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_module.c?rev=301725&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/pragma_module.c (added)
+++ cfe/trunk/test/Preprocessor/pragma_module.c Fri Apr 28 19:34:47 2017
@@ -0,0 +1,11 @@
+// RUN: %clang -cc1 -E -fmodules %s -verify
+
+// Just checking the syntax here; the semantics are tested elsewhere.
+#pragma clang module import // expected-error {{expected identifier in module name}}
+#pragma clang module import ! // expected-error {{expected identifier in module name}}
+#pragma clang module import if // expected-error {{expected identifier in module name}}
+#pragma clang module import foo ? bar // expected-error {{expected '.' or end of directive after module name}}
+#pragma clang module import foo. // expected-error {{expected identifier}}
+#pragma clang module import foo.bar.baz.quux // expected-error {{module 'foo' not found}}
+
+#error here // expected-error {{here}}




More information about the cfe-commits mailing list