Skip to content

Commit 4a16b51

Browse files
authored
Make -frewrite-includes put an endif at the end of the included text (#67613)
The #if now has a conditional expression, so a user can add `-D__CLANG_REWRITTEN_SYSTEM_INCLUDES` to include the system headers instead of using the expanded content, or `-D__CLANG_REWRITTEN_INCLUDES` to include all headers. Also added the filename to the comments it emits, to help identify where included text ends, making it easier to identify and remove the content of individual headers.
1 parent e2a37cd commit 4a16b51

File tree

5 files changed

+98
-50
lines changed

5 files changed

+98
-50
lines changed

clang/docs/ReleaseNotes.rst

+3
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ Modified Compiler Flags
168168

169169
* ``-Woverriding-t-option`` is renamed to ``-Woverriding-option``.
170170
* ``-Winterrupt-service-routine`` is renamed to ``-Wexcessive-regsave`` as a generalization
171+
* ``-frewrite-includes`` now guards the original #include directives with
172+
``__CLANG_REWRITTEN_INCLUDES``, and ``__CLANG_REWRITTEN_SYSTEM_INCLUDES`` as
173+
appropriate.
171174

172175
Removed Compiler Flags
173176
-------------------------

clang/lib/Frontend/Rewrite/InclusionRewriter.cpp

+34-8
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ class InclusionRewriter : public PPCallbacks {
9090
bool EnsureNewline);
9191
void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,
9292
const MemoryBufferRef &FromFile, StringRef EOL,
93-
unsigned &NextToWrite, int &Lines);
93+
unsigned &NextToWrite, int &Lines,
94+
const IncludedFile *Inc = nullptr);
9495
const IncludedFile *FindIncludeAtLocation(SourceLocation Loc) const;
96+
StringRef getIncludedFileName(const IncludedFile *Inc) const;
9597
const Module *FindModuleAtLocation(SourceLocation Loc) const;
9698
const Module *FindEnteredModule(SourceLocation Loc) const;
9799
bool IsIfAtLocationTrue(SourceLocation Loc) const;
@@ -311,6 +313,17 @@ void InclusionRewriter::OutputContentUpTo(const MemoryBufferRef &FromFile,
311313
WriteFrom = WriteTo;
312314
}
313315

316+
StringRef
317+
InclusionRewriter::getIncludedFileName(const IncludedFile *Inc) const {
318+
if (Inc) {
319+
auto B = SM.getBufferOrNone(Inc->Id);
320+
assert(B && "Attempting to process invalid inclusion");
321+
if (B)
322+
return llvm::sys::path::filename(B->getBufferIdentifier());
323+
}
324+
return StringRef();
325+
}
326+
314327
/// Print characters from \p FromFile starting at \p NextToWrite up until the
315328
/// inclusion directive at \p StartToken, then print out the inclusion
316329
/// inclusion directive disabled by a #if directive, updating \p NextToWrite
@@ -320,7 +333,8 @@ void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,
320333
const Token &StartToken,
321334
const MemoryBufferRef &FromFile,
322335
StringRef LocalEOL,
323-
unsigned &NextToWrite, int &Line) {
336+
unsigned &NextToWrite, int &Line,
337+
const IncludedFile *Inc) {
324338
OutputContentUpTo(FromFile, NextToWrite,
325339
SM.getFileOffset(StartToken.getLocation()), LocalEOL, Line,
326340
false);
@@ -332,12 +346,21 @@ void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,
332346
// OutputContentUpTo() would not output anything anyway.
333347
return;
334348
}
335-
OS << "#if 0 /* expanded by -frewrite-includes */" << MainEOL;
349+
if (Inc) {
350+
OS << "#if defined(__CLANG_REWRITTEN_INCLUDES) ";
351+
if (isSystem(Inc->FileType))
352+
OS << "|| defined(__CLANG_REWRITTEN_SYSTEM_INCLUDES) ";
353+
OS << "/* " << getIncludedFileName(Inc);
354+
} else {
355+
OS << "#if 0 /*";
356+
}
357+
OS << " expanded by -frewrite-includes */" << MainEOL;
336358
OutputContentUpTo(FromFile, NextToWrite,
337359
SM.getFileOffset(DirectiveToken.getLocation()) +
338360
DirectiveToken.getLength(),
339361
LocalEOL, Line, true);
340-
OS << "#endif /* expanded by -frewrite-includes */" << MainEOL;
362+
OS << (Inc ? "#else /* " : "#endif /*") << getIncludedFileName(Inc)
363+
<< " expanded by -frewrite-includes */" << MainEOL;
341364
}
342365

343366
/// Find the next identifier in the pragma directive specified by \p RawToken.
@@ -400,15 +423,16 @@ void InclusionRewriter::Process(FileID FileId,
400423
case tok::pp_include:
401424
case tok::pp_include_next:
402425
case tok::pp_import: {
403-
CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL, NextToWrite,
404-
Line);
426+
SourceLocation Loc = HashToken.getLocation();
427+
const IncludedFile *Inc = FindIncludeAtLocation(Loc);
428+
CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL,
429+
NextToWrite, Line, Inc);
405430
if (FileId != PP.getPredefinesFileID())
406431
WriteLineInfo(FileName, Line - 1, FileType, "");
407432
StringRef LineInfoExtra;
408-
SourceLocation Loc = HashToken.getLocation();
409433
if (const Module *Mod = FindModuleAtLocation(Loc))
410434
WriteImplicitModuleImport(Mod);
411-
else if (const IncludedFile *Inc = FindIncludeAtLocation(Loc)) {
435+
else if (Inc) {
412436
const Module *Mod = FindEnteredModule(Loc);
413437
if (Mod)
414438
OS << "#pragma clang module begin "
@@ -420,6 +444,8 @@ void InclusionRewriter::Process(FileID FileId,
420444
if (Mod)
421445
OS << "#pragma clang module end /*"
422446
<< Mod->getFullModuleName(true) << "*/\n";
447+
OS << "#endif /* " << getIncludedFileName(Inc)
448+
<< " expanded by -frewrite-includes */" << LocalEOL;
423449

424450
// Add line marker to indicate we're returning from an included
425451
// file.

clang/test/Frontend/rewrite-includes-cli-include.c

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ main_file_line
33
// CHECK: {{^}}# 1 "<built-in>"{{$}}
44
// CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes2.h" 1{{$}}
55
// CHECK-NEXT: {{^}}int included_line2;{{$}}
6+
// CHECK-NEXT: {{^}}#endif /* rewrite-includes2.h expanded by -frewrite-includes */{{$}}
67
// CHECK-NEXT: {{^}}# 1 "<built-in>" 2{{$}}
78
// CHECK-NEXT: {{^}}# 1 "{{.*}}rewrite-includes-cli-include.c"{{$}}
89
// CHECK-NEXT: FileCheck

0 commit comments

Comments
 (0)