forked from OSchip/llvm-project
[frontend] -frewrite-includes: turn implicit module imports into @imports.
rdar://13610250 llvm-svn: 179145
This commit is contained in:
parent
a6444b1ce1
commit
cf22d1f3ab
|
@ -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: {
|
||||
|
|
|
@ -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"{{$}}
|
Loading…
Reference in New Issue