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 +@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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits