Skip to content

Commit c899718

Browse files
committed
Track which headers are system and non-C++-clean-system headers. Use this
information to print the 3/4 flags correctly on #line directives emitted in -E mode. llvm-svn: 38562
1 parent 0c885f5 commit c899718

File tree

3 files changed

+93
-49
lines changed

3 files changed

+93
-49
lines changed

clang/Driver/clang.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ static unsigned EModeCurLine;
592592
static std::string EModeCurFilename;
593593
static Preprocessor *EModePP;
594594
static bool EmodeEmittedTokensOnThisLine;
595+
static DirectoryLookup::DirType EmodeFileType =DirectoryLookup::NormalHeaderDir;
595596

596597
static void MoveToLine(unsigned LineNo) {
597598
// If this line is "close enough" to the original line, just print newlines,
@@ -607,17 +608,20 @@ static void MoveToLine(unsigned LineNo) {
607608

608609
std::cout << "# " << LineNo << " " << EModeCurFilename;
609610

610-
// FIXME: calculate system file right.
611-
std::cout << " 3";
612-
611+
if (EmodeFileType == DirectoryLookup::SystemHeaderDir)
612+
std::cout << " 3";
613+
else if (EmodeFileType == DirectoryLookup::ExternCSystemHeaderDir)
614+
std::cout << " 3 4";
615+
613616
std::cout << "\n";
614617
EModeCurLine = LineNo;
615618
}
616619
}
617620

618621
/// HandleFileChange - Whenever the preprocessor enters or exits a #include file
619622
/// it invokes this handler. Update our conception of the current
620-
static void HandleFileChange(SourceLocation Loc, bool EnteringFile) {
623+
static void HandleFileChange(SourceLocation Loc, bool EnteringFile,
624+
DirectoryLookup::DirType FileType) {
621625
SourceManager &SourceMgr = EModePP->getSourceManager();
622626

623627
// If we are entering a new #include, make sure to skip ahead to the line the
@@ -630,6 +634,7 @@ static void HandleFileChange(SourceLocation Loc, bool EnteringFile) {
630634
EModeCurLine = SourceMgr.getLineNumber(Loc);
631635
// FIXME: escape filename right.
632636
EModeCurFilename = '"' + SourceMgr.getSourceName(Loc) + '"';
637+
EmodeFileType = FileType;
633638

634639
if (EmodeEmittedTokensOnThisLine) {
635640
std::cout << "\n";
@@ -641,8 +646,10 @@ static void HandleFileChange(SourceLocation Loc, bool EnteringFile) {
641646
else
642647
std::cout << " 2";
643648

644-
// FIXME: calculate system file right.
645-
std::cout << " 3";
649+
if (FileType == DirectoryLookup::SystemHeaderDir)
650+
std::cout << " 3";
651+
else if (FileType == DirectoryLookup::ExternCSystemHeaderDir)
652+
std::cout << " 3 4";
646653

647654
std::cout << "\n";
648655
}

clang/Lex/Preprocessor.cpp

+55-27
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
4848
FileManager &FM, SourceManager &SM)
4949
: Diags(diags), Features(opts), FileMgr(FM), SourceMgr(SM),
5050
SystemDirIdx(0), NoCurDirSearch(false),
51-
CurLexer(0), CurNextDirLookup(0), CurMacroExpander(0) {
51+
CurLexer(0), CurDirLookup(0), CurMacroExpander(0) {
5252
// Clear stats.
5353
NumDirectives = NumIncluded = NumDefined = NumUndefined = NumPragma = 0;
5454
NumIf = NumElse = NumEndif = 0;
@@ -267,11 +267,11 @@ unsigned Preprocessor::getSpelling(const LexerToken &Tok, char *Buffer) const {
267267
/// return null on failure. isAngled indicates whether the file reference is
268268
/// for system #include's or not (i.e. using <> instead of "").
269269
const FileEntry *Preprocessor::LookupFile(const std::string &Filename,
270-
bool isSystem,
270+
bool isAngled,
271271
const DirectoryLookup *FromDir,
272-
const DirectoryLookup *&NextDir) {
272+
const DirectoryLookup *&CurDir) {
273273
assert(CurLexer && "Cannot enter a #include inside a macro expansion!");
274-
NextDir = 0;
274+
CurDir = 0;
275275

276276
// If 'Filename' is absolute, check to see if it exists and no searching.
277277
// FIXME: this should be a sys::Path interface, this doesn't handle things
@@ -286,23 +286,28 @@ const FileEntry *Preprocessor::LookupFile(const std::string &Filename,
286286

287287
// Step #0, unless disabled, check to see if the file is in the #includer's
288288
// directory. This search is not done for <> headers.
289-
if (!isSystem && !FromDir && !NoCurDirSearch) {
289+
if (!isAngled && !FromDir && !NoCurDirSearch) {
290290
const FileEntry *CurFE =
291291
SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID());
292292
if (CurFE) {
293+
// Concatenate the requested file onto the directory.
294+
// FIXME: should be in sys::Path.
293295
if (const FileEntry *FE =
294296
FileMgr.getFile(CurFE->getDir()->getName()+"/"+Filename)) {
295-
if (CurNextDirLookup)
296-
NextDir = CurNextDirLookup;
297+
if (CurDirLookup)
298+
CurDir = CurDirLookup;
297299
else
298-
NextDir = &SearchDirs[0];
300+
CurDir = 0;
301+
302+
// This file is a system header or C++ unfriendly if the old file is.
303+
getFileInfo(FE).DirInfo = getFileInfo(CurFE).DirInfo;
299304
return FE;
300305
}
301306
}
302307
}
303308

304309
// If this is a system #include, ignore the user #include locs.
305-
unsigned i = isSystem ? SystemDirIdx : 0;
310+
unsigned i = isAngled ? SystemDirIdx : 0;
306311

307312
// If this is a #include_next request, start searching after the directory the
308313
// file was found in.
@@ -315,7 +320,10 @@ const FileEntry *Preprocessor::LookupFile(const std::string &Filename,
315320
// FIXME: should be in sys::Path.
316321
if (const FileEntry *FE =
317322
FileMgr.getFile(SearchDirs[i].getDir()->getName()+"/"+Filename)) {
318-
NextDir = &SearchDirs[i+1];
323+
CurDir = &SearchDirs[i];
324+
325+
// This file is a system header or C++ unfriendly if the dir is.
326+
getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
319327
return FE;
320328
}
321329
}
@@ -328,12 +336,12 @@ const FileEntry *Preprocessor::LookupFile(const std::string &Filename,
328336
/// start lexing tokens from it instead of the current buffer. Return true
329337
/// on failure.
330338
void Preprocessor::EnterSourceFile(unsigned FileID,
331-
const DirectoryLookup *NextDir) {
339+
const DirectoryLookup *CurDir) {
332340
++NumEnteredSourceFiles;
333341

334342
// Add the current lexer to the include stack.
335343
if (CurLexer) {
336-
IncludeStack.push_back(IncludeStackInfo(CurLexer, CurNextDirLookup));
344+
IncludeStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup));
337345
} else {
338346
assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
339347
}
@@ -343,12 +351,21 @@ void Preprocessor::EnterSourceFile(unsigned FileID,
343351

344352
const SourceBuffer *Buffer = SourceMgr.getBuffer(FileID);
345353

346-
CurLexer = new Lexer(Buffer, FileID, *this);
347-
CurNextDirLookup = NextDir;
354+
CurLexer = new Lexer(Buffer, FileID, *this);
355+
CurDirLookup = CurDir;
348356

349357
// Notify the client, if desired, that we are in a new source file.
350-
if (FileChangeHandler)
351-
FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart), true);
358+
if (FileChangeHandler) {
359+
DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
360+
361+
// Get the file entry for the current file.
362+
if (const FileEntry *FE =
363+
SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID()))
364+
FileType = getFileInfo(FE).DirInfo;
365+
366+
FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferStart), true,
367+
FileType);
368+
}
352369
}
353370

354371
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
@@ -357,9 +374,9 @@ void Preprocessor::EnterMacro(LexerToken &Tok) {
357374
IdentifierTokenInfo *Identifier = Tok.getIdentifierInfo();
358375
MacroInfo &MI = *Identifier->getMacroInfo();
359376
if (CurLexer) {
360-
IncludeStack.push_back(IncludeStackInfo(CurLexer, CurNextDirLookup));
361-
CurLexer = 0;
362-
CurNextDirLookup = 0;
377+
IncludeStack.push_back(IncludeStackInfo(CurLexer, CurDirLookup));
378+
CurLexer = 0;
379+
CurDirLookup = 0;
363380
} else if (CurMacroExpander) {
364381
MacroStack.push_back(CurMacroExpander);
365382
}
@@ -492,14 +509,22 @@ void Preprocessor::HandleEndOfFile(LexerToken &Result, bool isEndOfMacro) {
492509
if (!IncludeStack.empty()) {
493510
// We're done with the #included file.
494511
delete CurLexer;
495-
CurLexer = IncludeStack.back().TheLexer;
496-
CurNextDirLookup = IncludeStack.back().TheDirLookup;
512+
CurLexer = IncludeStack.back().TheLexer;
513+
CurDirLookup = IncludeStack.back().TheDirLookup;
497514
IncludeStack.pop_back();
498515

499516
// Notify the client, if desired, that we are in a new source file.
500-
if (FileChangeHandler && !isEndOfMacro)
517+
if (FileChangeHandler && !isEndOfMacro) {
518+
DirectoryLookup::DirType FileType = DirectoryLookup::NormalHeaderDir;
519+
520+
// Get the file entry for the current file.
521+
if (const FileEntry *FE =
522+
SourceMgr.getFileEntryForFileID(CurLexer->getCurFileID()))
523+
FileType = getFileInfo(FE).DirInfo;
524+
501525
FileChangeHandler(CurLexer->getSourceLocation(CurLexer->BufferPtr),
502-
false);
526+
false, FileType);
527+
}
503528

504529
return Lex(Result);
505530
}
@@ -923,8 +948,8 @@ void Preprocessor::HandleIncludeDirective(LexerToken &IncludeTok,
923948
return Diag(FilenameTok, diag::err_pp_empty_filename);
924949

925950
// Search include directories.
926-
const DirectoryLookup *NextDir;
927-
const FileEntry *File = LookupFile(Filename, isAngled, LookupFrom, NextDir);
951+
const DirectoryLookup *CurDir;
952+
const FileEntry *File = LookupFile(Filename, isAngled, LookupFrom, CurDir);
928953
if (File == 0)
929954
return Diag(FilenameTok, diag::err_pp_file_not_found);
930955

@@ -953,7 +978,7 @@ void Preprocessor::HandleIncludeDirective(LexerToken &IncludeTok,
953978
return Diag(FilenameTok, diag::err_pp_file_not_found);
954979

955980
// Finally, if all is good, enter the new file!
956-
EnterSourceFile(FileID, NextDir);
981+
EnterSourceFile(FileID, CurDir);
957982

958983
// Increment the number of times this file has been included.
959984
++FileInfo.NumIncludes;
@@ -967,12 +992,15 @@ void Preprocessor::HandleIncludeNextDirective(LexerToken &IncludeNextTok) {
967992
// #include_next is like #include, except that we start searching after
968993
// the current found directory. If we can't do this, issue a
969994
// diagnostic.
970-
const DirectoryLookup *Lookup = CurNextDirLookup;
995+
const DirectoryLookup *Lookup = CurDirLookup;
971996
if (IncludeStack.empty()) {
972997
Lookup = 0;
973998
Diag(IncludeNextTok, diag::pp_include_next_in_primary);
974999
} else if (Lookup == 0) {
9751000
Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
1001+
} else {
1002+
// Start looking up in the next directory.
1003+
++Lookup;
9761004
}
9771005

9781006
return HandleIncludeDirective(IncludeNextTok, Lookup);

clang/include/clang/Lex/Preprocessor.h

+25-16
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class Preprocessor {
9393
/// EnteringFile indicates whether this is because we are entering a new
9494
/// #include'd file (when true) or whether we're exiting one because we ran
9595
/// off the end (when false).
96-
void (*FileChangeHandler)(SourceLocation Loc, bool EnteringFile);
96+
void (*FileChangeHandler)(SourceLocation Loc, bool EnteringFile,
97+
DirectoryLookup::DirType FileType);
9798

9899
enum {
99100
/// MaxIncludeStackDepth - Maximum depth of #includes.
@@ -112,9 +113,10 @@ class Preprocessor {
112113
/// not expanding a macro. One of CurLexer and CurMacroExpander must be null.
113114
Lexer *CurLexer;
114115

115-
/// CurDirLookup - The next DirectoryLookup structure to search for a file if
116-
/// CurLexer is non-null. This allows us to implement #include_next.
117-
const DirectoryLookup *CurNextDirLookup;
116+
/// CurLookup - The DirectoryLookup structure used to find the current
117+
/// FileEntry, if CurLexer is non-null and if applicable. This allows us to
118+
/// implement #include_next and find directory-specific properties.
119+
const DirectoryLookup *CurDirLookup;
118120

119121
/// IncludeStack - This keeps track of the stack of files currently #included,
120122
/// not counting CurLexer.
@@ -139,14 +141,20 @@ class Preprocessor {
139141
/// PreFileInfo - The preprocessor keeps track of this information for each
140142
/// file that is #included.
141143
struct PerFileInfo {
142-
// isImport - True if this is a #import'd or #pragma once file.
143-
bool isImport;
144+
/// isImport - True if this is a #import'd or #pragma once file.
145+
bool isImport : 1;
144146

145-
// NumIncludes - This is the number of times the file has been included
146-
// already.
147+
/// DirInfo - Keep track of whether this is a system header, and if so,
148+
/// whether it is C++ clean or not. This can be set by the include paths or
149+
/// by #pragma gcc system_header.
150+
DirectoryLookup::DirType DirInfo : 2;
151+
152+
/// NumIncludes - This is the number of times the file has been included
153+
/// already.
147154
unsigned short NumIncludes;
148155

149-
PerFileInfo() : isImport(false), NumIncludes(0) {}
156+
PerFileInfo() : isImport(false), DirInfo(DirectoryLookup::NormalHeaderDir),
157+
NumIncludes(0) {}
150158
};
151159

152160
/// FileInfo - This contains all of the preprocessor-specific data about files
@@ -196,7 +204,8 @@ class Preprocessor {
196204
/// EnteringFile indicates whether this is because we are entering a new
197205
/// #include'd file (when true) or whether we're exiting one because we ran
198206
/// off the end (when false).
199-
void setFileChangeHandler(void (*Handler)(SourceLocation, bool)) {
207+
void setFileChangeHandler(void (*Handler)(SourceLocation, bool,
208+
DirectoryLookup::DirType)) {
200209
FileChangeHandler = Handler;
201210
}
202211

@@ -239,14 +248,14 @@ class Preprocessor {
239248
void AddKeywords();
240249

241250
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
242-
/// return null on failure. isSystem indicates whether the file reference is
243-
/// for system #include's or not. If successful, this returns 'UsedDir', the
251+
/// return null on failure. isAngled indicates whether the file reference is
252+
/// a <> reference. If successful, this returns 'UsedDir', the
244253
/// DirectoryLookup member the file was found in, or null if not applicable.
245-
/// If FromDir is non-null, the directory search should start with the entry
246-
/// after the indicated lookup. This is used to implement #include_next.
247-
const FileEntry *LookupFile(const std::string &Filename, bool isSystem,
254+
/// If CurDir is non-null, the file was found in the specified directory
255+
/// search location. This is used to implement #include_next.
256+
const FileEntry *LookupFile(const std::string &Filename, bool isAngled,
248257
const DirectoryLookup *FromDir,
249-
const DirectoryLookup *&NextDir);
258+
const DirectoryLookup *&CurDir);
250259

251260
/// EnterSourceFile - Add a source file to the top of the include stack and
252261
/// start lexing tokens from it instead of the current buffer.

0 commit comments

Comments
 (0)