diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-04-10 01:53:50 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-04-10 01:53:50 +0000 |
commit | 03409967bd9860ffb2ff6b38126e04493c55567f (patch) | |
tree | 5c29c146cb5c84c558455c7157833c87ab57d0ed | |
parent | 15aa81a4746697311f71f5802ce27c7dc98b2ff3 (diff) |
[frontend] -frewrite-includes: turn implicit module imports into @imports.
rdar://13610250
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179145 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Rewrite/Frontend/InclusionRewriter.cpp | 39 | ||||
-rw-r--r-- | test/Frontend/rewrite-includes-modules.c | 20 |
2 files changed, 44 insertions, 15 deletions
diff --git a/lib/Rewrite/Frontend/InclusionRewriter.cpp b/lib/Rewrite/Frontend/InclusionRewriter.cpp index 5740a8407e..cbdc702815 100644 --- a/lib/Rewrite/Frontend/InclusionRewriter.cpp +++ b/lib/Rewrite/Frontend/InclusionRewriter.cpp @@ -27,10 +27,11 @@ class InclusionRewriter : public PPCallbacks { /// Information about which #includes were actually performed, /// created by preprocessor callbacks. struct FileChange { + const Module *Mod; SourceLocation From; FileID Id; SrcMgr::CharacteristicKind FileType; - FileChange(SourceLocation From) : From(From) { + FileChange(SourceLocation From, const Module *Mod) : Mod(Mod), From(From) { } }; Preprocessor &PP; ///< Used to find inclusion directives. @@ -65,6 +66,7 @@ private: void WriteLineInfo(const char *Filename, int Line, SrcMgr::CharacteristicKind FileType, StringRef EOL, StringRef Extra = StringRef()); + void WriteImplicitModuleImport(const Module *Mod, StringRef EOL); void OutputContentUpTo(const MemoryBuffer &FromFile, unsigned &WriteFrom, unsigned WriteTo, StringRef EOL, int &lines, @@ -117,6 +119,12 @@ void InclusionRewriter::WriteLineInfo(const char *Filename, int Line, OS << EOL; } +void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod, + StringRef EOL) { + OS << "@import " << Mod->getFullModuleName() << ";" + << " /* clang -frewrite-includes: implicit import */" << EOL; +} + /// FileChanged - Whenever the preprocessor enters or exits a #include file /// it invokes this handler. void InclusionRewriter::FileChanged(SourceLocation Loc, @@ -157,13 +165,14 @@ void InclusionRewriter::InclusionDirective(SourceLocation HashLoc, const FileEntry * /*File*/, StringRef /*SearchPath*/, StringRef /*RelativePath*/, - const Module * /*Imported*/) { + const Module *Imported) { assert(LastInsertedFileChange == FileChanges.end() && "Another inclusion " "directive was found before the previous one was processed"); std::pair<FileChangeMap::iterator, bool> p = FileChanges.insert( - std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc))); + std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc, Imported))); assert(p.second && "Unexpected revisitation of the same include directive"); - LastInsertedFileChange = p.first; + if (!Imported) + LastInsertedFileChange = p.first; } /// Simple lookup for a SourceLocation (specifically one denoting the hash in @@ -289,24 +298,24 @@ bool InclusionRewriter::Process(FileID FileId, case tok::pp_import: { CommentOutDirective(RawLex, HashToken, FromFile, EOL, NextToWrite, Line); + StringRef LineInfoExtra; if (const FileChange *Change = FindFileChangeLocation( HashToken.getLocation())) { - // now include and recursively process the file - if (Process(Change->Id, Change->FileType)) { + if (Change->Mod) { + WriteImplicitModuleImport(Change->Mod, EOL); + + // else now include and recursively process the file + } else if (Process(Change->Id, Change->FileType)) { // and set lineinfo back to this file, if the nested one was // actually included // `2' indicates returning to a file (after having included // another file. - WriteLineInfo(FileName, Line, FileType, EOL, " 2"); - } else { - // fix up lineinfo (since commented out directive changed line - // numbers). - WriteLineInfo(FileName, Line, FileType, EOL); + LineInfoExtra = " 2"; } - } else - // fix up lineinfo (since commented out directive changed line - // numbers) for inclusions that were skipped due to header guards - WriteLineInfo(FileName, Line, FileType, EOL); + } + // fix up lineinfo (since commented out directive changed line + // numbers) for inclusions that were skipped due to header guards + WriteLineInfo(FileName, Line, FileType, EOL, LineInfoExtra); break; } case tok::pp_pragma: { diff --git a/test/Frontend/rewrite-includes-modules.c b/test/Frontend/rewrite-includes-modules.c new file mode 100644 index 0000000000..783a96739a --- /dev/null +++ b/test/Frontend/rewrite-includes-modules.c @@ -0,0 +1,20 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c %s -F %S/../Modules/Inputs -E -frewrite-includes -o - | FileCheck %s + +int bar(); +#include <Module/Module.h> +int foo(); +#include <Module/Module.h> + +// CHECK: int bar();{{$}} +// CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: #include <Module/Module.h>{{$}} +// CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}} +// CHECK-NEXT: # 6 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}} +// CHECK-NEXT: int foo();{{$}} +// CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: #include <Module/Module.h>{{$}} +// CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}} +// CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}} +// CHECK-NEXT: # 8 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}} |