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.)

llvm-svn: 301725
diff --git a/clang/test/Frontend/rewrite-includes-modules.c b/clang/test/Frontend/rewrite-includes-modules.c
index 613609d..e70fe0d 100644
--- a/clang/test/Frontend/rewrite-includes-modules.c
+++ b/clang/test/Frontend/rewrite-includes-modules.c
@@ -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"{{$}}
diff --git a/clang/test/Modules/crash-vfs-path-emptydir-entries.m b/clang/test/Modules/crash-vfs-path-emptydir-entries.m
index e44714b..d96adbb 100644
--- a/clang/test/Modules/crash-vfs-path-emptydir-entries.m
+++ b/clang/test/Modules/crash-vfs-path-emptydir-entries.m
@@ -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"
diff --git a/clang/test/Modules/crash-vfs-path-symlink-component.m b/clang/test/Modules/crash-vfs-path-symlink-component.m
index 5be4925..4723a77 100644
--- a/clang/test/Modules/crash-vfs-path-symlink-component.m
+++ b/clang/test/Modules/crash-vfs-path-symlink-component.m
@@ -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
diff --git a/clang/test/Modules/crash-vfs-path-symlink-topheader.m b/clang/test/Modules/crash-vfs-path-symlink-topheader.m
index 51a14c6..8e0c2d4 100644
--- a/clang/test/Modules/crash-vfs-path-symlink-topheader.m
+++ b/clang/test/Modules/crash-vfs-path-symlink-topheader.m
@@ -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"
diff --git a/clang/test/Modules/crash-vfs-path-traversal.m b/clang/test/Modules/crash-vfs-path-traversal.m
index cc56e53..cd12cad 100644
--- a/clang/test/Modules/crash-vfs-path-traversal.m
+++ b/clang/test/Modules/crash-vfs-path-traversal.m
@@ -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
diff --git a/clang/test/Modules/crash-vfs-relative-overlay.m b/clang/test/Modules/crash-vfs-relative-overlay.m
index 54ba13b..e55f4c8 100644
--- a/clang/test/Modules/crash-vfs-relative-overlay.m
+++ b/clang/test/Modules/crash-vfs-relative-overlay.m
@@ -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
diff --git a/clang/test/Modules/import-syntax.c b/clang/test/Modules/import-syntax.c
new file mode 100644
index 0000000..a29e07a
--- /dev/null
+++ b/clang/test/Modules/import-syntax.c
@@ -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
+@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;
diff --git a/clang/test/Modules/preprocess-module.cpp b/clang/test/Modules/preprocess-module.cpp
index d084b40..99fe8cf 100644
--- a/clang/test/Modules/preprocess-module.cpp
+++ b/clang/test/Modules/preprocess-module.cpp
@@ -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
diff --git a/clang/test/Modules/preprocess.cpp b/clang/test/Modules/preprocess.cpp
index 0615331..d855fed 100644
--- a/clang/test/Modules/preprocess.cpp
+++ b/clang/test/Modules/preprocess.cpp
@@ -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
+// REWRITE: #if 0
+// REWRITE: #include{{ }}"dummy.h"
+// REWRITE: #endif
 
-// OBJC: @import{{ }}dummy; /* clang 
-// OBJC: @import{{ }}dummy; /* clang 
-// OBJC: foo bar baz
+// 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
diff --git a/clang/test/Modules/preprocess.m b/clang/test/Modules/preprocess.m
index 8d740d1..37a6815 100644
--- a/clang/test/Modules/preprocess.m
+++ b/clang/test/Modules/preprocess.m
@@ -16,11 +16,11 @@
 
 
 // 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();{{$}}
diff --git a/clang/test/Preprocessor/pp-modules.c b/clang/test/Preprocessor/pp-modules.c
index 09f3eee..8c283c6 100644
--- a/clang/test/Preprocessor/pp-modules.c
+++ b/clang/test/Preprocessor/pp-modules.c
@@ -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
diff --git a/clang/test/Preprocessor/pragma_module.c b/clang/test/Preprocessor/pragma_module.c
new file mode 100644
index 0000000..d734f66
--- /dev/null
+++ b/clang/test/Preprocessor/pragma_module.c
@@ -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}}