Introduce a new PresumedLoc class to represent the concept of a location
as reported to the user and as manipulated by #line. This is what __FILE__,
__INCLUDE_LEVEL__, diagnostics and other things should follow (but not
dependency generation!).
This patch also includes several cleanups along the way:
- SourceLocation now has a dump method, and several other places
that did similar things now use it.
- I cleaned up some code in AnalysisConsumer, but it should probably be
simplified further now that NamedDecl is better.
- TextDiagnosticPrinter is now simplified and cleaned up a bit.
This patch is a prerequisite for #line, but does not actually provide
any #line functionality.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63098 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 8eada60..a517b1d 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -454,28 +454,37 @@
Tok.clearFlag(Token::NeedsCleaning);
if (II == Ident__LINE__) {
+ // C99 6.10.8: "__LINE__: The presumed line number (within the current
+ // source file) of the current source line (an integer constant)". This can
+ // be affected by #line.
+ PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+
// __LINE__ expands to a simple numeric value. Add a space after it so that
// it will tokenize as a number (and not run into stuff after it in the temp
// buffer).
- sprintf(TmpBuffer, "%u ",
- SourceMgr.getInstantiationLineNumber(Tok.getLocation()));
+ sprintf(TmpBuffer, "%u ", PLoc.getLine());
unsigned Length = strlen(TmpBuffer)-1;
Tok.setKind(tok::numeric_constant);
CreateString(TmpBuffer, Length+1, Tok, Tok.getLocation());
Tok.setLength(Length); // Trim off space.
} else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
- SourceLocation Loc = Tok.getLocation();
+ // C99 6.10.8: "__FILE__: The presumed name of the current source file (a
+ // character string literal)". This can be affected by #line.
+ PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+
+ // __BASE_FILE__ is a GNU extension that returns the top of the presumed
+ // #include stack instead of the current file.
if (II == Ident__BASE_FILE__) {
Diag(Tok, diag::ext_pp_base_file);
- SourceLocation NextLoc = SourceMgr.getIncludeLoc(Loc);
+ SourceLocation NextLoc = PLoc.getIncludeLoc();
while (NextLoc.isValid()) {
- Loc = NextLoc;
- NextLoc = SourceMgr.getIncludeLoc(Loc);
+ PLoc = SourceMgr.getPresumedLoc(NextLoc);
+ NextLoc = PLoc.getIncludeLoc();
}
}
// Escape this filename. Turn '\' -> '\\' '"' -> '\"'
- std::string FN =SourceMgr.getSourceName(SourceMgr.getInstantiationLoc(Loc));
+ std::string FN = PLoc.getFilename();
FN = '"' + Lexer::Stringify(FN) + '"';
Tok.setKind(tok::string_literal);
CreateString(&FN[0], FN.size(), Tok, Tok.getLocation());
@@ -496,11 +505,14 @@
} else if (II == Ident__INCLUDE_LEVEL__) {
Diag(Tok, diag::ext_pp_include_level);
- // Compute the include depth of this token.
+ // Compute the presumed include depth of this token. This can be affected
+ // by GNU line markers.
unsigned Depth = 0;
- SourceLocation Loc = SourceMgr.getIncludeLoc(Tok.getLocation());
- for (; Loc.isValid(); ++Depth)
- Loc = SourceMgr.getIncludeLoc(Loc);
+
+ PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+ PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
+ for (; PLoc.isValid(); ++Depth)
+ PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
// __INCLUDE_LEVEL__ expands to a simple numeric value. Add a space after
// it so that it will tokenize as a number (and not run into stuff after it
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index e6bf177..48fdd68 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -142,17 +142,7 @@
}
void Preprocessor::DumpLocation(SourceLocation Loc) const {
- SourceLocation LogLoc = SourceMgr.getInstantiationLoc(Loc);
- llvm::cerr << SourceMgr.getSourceName(LogLoc) << ':'
- << SourceMgr.getLineNumber(LogLoc) << ':'
- << SourceMgr.getColumnNumber(LogLoc);
-
- SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(Loc);
- if (SpellingLoc != LogLoc) {
- llvm::cerr << " <SpellingLoc=";
- DumpLocation(SpellingLoc);
- llvm::cerr << ">";
- }
+ Loc.dump(SourceMgr);
}
void Preprocessor::DumpMacro(const MacroInfo &MI) const {