make getFileCharacteristic linetable aware. line markers that

play around with the 'is system header' bit now function correctly.

llvm-svn: 63720
This commit is contained in:
Chris Lattner 2009-02-04 05:33:01 +00:00
parent 0a1a8d8514
commit 95d9c5e778
3 changed files with 61 additions and 5 deletions

View File

@ -495,11 +495,15 @@ public:
unsigned getInstantiationLineNumber(SourceLocation Loc) const;
unsigned getSpellingLineNumber(SourceLocation Loc) const;
// FIXME: This should handle #line.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const {
FileID FID = getFileID(getSpellingLoc(Loc));
return getSLocEntry(FID).getFile().getFileCharacteristic();
}
/// getFileCharacteristic - return the file characteristic of the specified
/// source location, indicating whether this is a normal file, a system
/// header, or an "implicit extern C" system header.
///
/// This state can be modified with flags on GNU linemarker directives like:
/// # 4 "foo.h" 3
/// which changes all source locations in the current file after that to be
/// considered to be from a system header.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
/// getPresumedLoc - This method returns the "presumed" location of a
/// SourceLocation specifies. A "presumed location" can be modified by #line

View File

@ -82,6 +82,7 @@ struct LineEntry {
E.FileOffset = Offs;
E.LineNo = Line;
E.FilenameID = Filename;
E.FileKind = FileKind;
return E;
}
};
@ -754,6 +755,37 @@ unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc) const {
return getLineNumber(LocInfo.first, LocInfo.second);
}
/// getFileCharacteristic - return the file characteristic of the specified
/// source location, indicating whether this is a normal file, a system
/// header, or an "implicit extern C" system header.
///
/// This state can be modified with flags on GNU linemarker directives like:
/// # 4 "foo.h" 3
/// which changes all source locations in the current file after that to be
/// considered to be from a system header.
SrcMgr::CharacteristicKind
SourceManager::getFileCharacteristic(SourceLocation Loc) const {
assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!");
std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
// If there are no #line directives in this file, just return the whole-file
// state.
if (!FI.hasLineDirectives())
return FI.getFileCharacteristic();
assert(LineTable && "Can't have linetable entries without a LineTable!");
// See if there is a #line directive before the location.
const LineEntry *Entry =
LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second);
// If this is before the first line marker, use the file characteristic.
if (!Entry)
return FI.getFileCharacteristic();
return Entry->FileKind;
}
/// getPresumedLoc - This method returns the "presumed" location of a
/// SourceLocation specifies. A "presumed location" can be modified by #line

View File

@ -34,3 +34,23 @@
#error ABC // expected-error {{#error ABC}}
#error DEF // expected-error {{#error DEF}}
// Verify that linemarker diddling of the system header flag works.
# 192 "glomp.h" // not a system header.
typedef int x; // expected-note {{previous definition is here}}
typedef int x; // expected-error {{redefinition of 'x'}}
# 192 "glomp.h" 3 // System header.
typedef int y; // ok
typedef int y; // ok
#line 42 "blonk.h" // doesn't change system headerness.
typedef int z; // ok
typedef int z; // ok
# 42 "blonk.h" // DOES change system headerness.
typedef int w; // expected-note {{previous definition is here}}
typedef int w; // expected-error {{redefinition of 'w'}}