diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-04-29 00:34:47 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-04-29 00:34:47 +0000 |
commit | c51c38b4ec63ca17f5d38ec73b218a0247b39ace (patch) | |
tree | a2c3032fc1feb995c824e078a39c82086319a6d1 /clang/lib/Frontend/PrintPreprocessedOutput.cpp | |
parent | 6fdcb3c2cea9af306285867f4b4132e4149af8a6 (diff) | |
download | bcm5719-llvm-c51c38b4ec63ca17f5d38ec73b218a0247b39ace.tar.gz bcm5719-llvm-c51c38b4ec63ca17f5d38ec73b218a0247b39ace.zip |
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
Diffstat (limited to 'clang/lib/Frontend/PrintPreprocessedOutput.cpp')
-rw-r--r-- | clang/lib/Frontend/PrintPreprocessedOutput.cpp | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 42d609cdb64..ffedf3cac84 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -324,43 +324,50 @@ void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc, 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; } } } |