Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit b9c3f96

Browse files
committed
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
1 parent 52c2908 commit b9c3f96

14 files changed

+230
-171
lines changed

Diff for: Driver/AnalysisConsumer.cpp

+7-11
Original file line numberDiff line numberDiff line change
@@ -257,18 +257,14 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break;
257257

258258
DisplayedFunction = true;
259259

260-
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(getCodeDecl())) {
260+
// FIXME: Is getCodeDecl() always a named decl?
261+
if (isa<FunctionDecl>(getCodeDecl()) ||
262+
isa<ObjCMethodDecl>(getCodeDecl())) {
263+
NamedDecl *ND = cast<NamedDecl>(getCodeDecl());
264+
SourceManager &SM = getContext().getSourceManager();
261265
llvm::cerr << "ANALYZE: "
262-
<< getContext().getSourceManager().getSourceName(FD->getLocation())
263-
<< ' '
264-
<< FD->getIdentifier()->getName()
265-
<< '\n';
266-
}
267-
else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(getCodeDecl())) {
268-
llvm::cerr << "ANALYZE (ObjC Method): "
269-
<< getContext().getSourceManager().getSourceName(MD->getLocation())
270-
<< " '"
271-
<< MD->getSelector().getAsString() << "'\n";
266+
<< SM.getPresumedLoc(ND->getLocation()).getFilename()
267+
<< ' ' << ND->getNameAsString() << '\n';
272268
}
273269
}
274270

Diff for: Driver/DependencyFile.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "clang.h"
1515
#include "clang/Basic/SourceManager.h"
16+
#include "clang/Basic/FileManager.h"
1617
#include "clang/Lex/Preprocessor.h"
1718
#include "clang/Lex/PPCallbacks.h"
1819
#include "clang/Lex/DirectoryLookup.h"
@@ -167,8 +168,14 @@ void DependencyFileCallback::FileChanged(SourceLocation Loc,
167168
SrcMgr::CharacteristicKind FileType) {
168169
if (Reason != PPCallbacks::EnterFile)
169170
return;
170-
171-
const char *Filename = PP->getSourceManager().getSourceName(Loc);
171+
172+
// Depedency generation really does want to go all the way to the file entry
173+
// for a source location to find out what is depended on. We do not want
174+
// #line markers to affect dependency generation!
175+
SourceManager &SM = PP->getSourceManager();
176+
177+
FileID FID = SM.getFileID(SM.getInstantiationLoc(Loc));
178+
const char *Filename = SM.getFileEntryForID(FID)->getName();
172179
if (!FileMatchesDepCriteria(Filename, FileType))
173180
return;
174181

Diff for: Driver/PrintPreprocessedOutput.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
150150
// #include directive was at.
151151
SourceManager &SourceMgr = PP.getSourceManager();
152152
if (Reason == PPCallbacks::EnterFile) {
153-
MoveToLine(SourceMgr.getIncludeLoc(Loc));
153+
MoveToLine(SourceMgr.getPresumedLoc(Loc).getIncludeLoc());
154154
} else if (Reason == PPCallbacks::SystemHeaderPragma) {
155155
MoveToLine(Loc);
156156

@@ -165,7 +165,7 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
165165
if (DisableLineMarkers) return;
166166

167167
CurFilename.clear();
168-
CurFilename += SourceMgr.getSourceName(Loc);
168+
CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename();
169169
Lexer::Stringify(CurFilename);
170170
FileType = NewFileType;
171171

@@ -540,7 +540,8 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP,
540540
const SourceManager &SourceMgr = PP.getSourceManager();
541541
do PP.Lex(Tok);
542542
while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() &&
543-
!strcmp(SourceMgr.getSourceName(Tok.getLocation()), "<predefines>"));
543+
!strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(),
544+
"<predefines>"));
544545

545546
while (1) {
546547

Diff for: include/clang/Basic/SourceLocation.h

+48-9
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class SourceLocation {
133133

134134
/// ReadVal - Read a SourceLocation object from Bitcode.
135135
static SourceLocation ReadVal(llvm::Deserializer& D);
136+
137+
void dump(const SourceManager &SM) const;
136138
};
137139

138140
inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
@@ -182,21 +184,20 @@ class FullSourceLoc : public SourceLocation {
182184
explicit FullSourceLoc(SourceLocation Loc, SourceManager &SM)
183185
: SourceLocation(Loc), SrcMgr(&SM) {}
184186

185-
SourceManager& getManager() {
186-
assert (SrcMgr && "SourceManager is NULL.");
187+
SourceManager &getManager() {
188+
assert(SrcMgr && "SourceManager is NULL.");
187189
return *SrcMgr;
188190
}
189191

190-
const SourceManager& getManager() const {
191-
assert (SrcMgr && "SourceManager is NULL.");
192+
const SourceManager &getManager() const {
193+
assert(SrcMgr && "SourceManager is NULL.");
192194
return *SrcMgr;
193195
}
194196

195197
FileID getFileID() const;
196198

197199
FullSourceLoc getInstantiationLoc() const;
198200
FullSourceLoc getSpellingLoc() const;
199-
FullSourceLoc getIncludeLoc() const;
200201

201202
unsigned getLineNumber() const;
202203
unsigned getColumnNumber() const;
@@ -211,13 +212,11 @@ class FullSourceLoc : public SourceLocation {
211212

212213
const llvm::MemoryBuffer* getBuffer() const;
213214

214-
const char* getSourceName() const;
215-
216215
bool isInSystemHeader() const;
217216

218217
/// Prints information about this FullSourceLoc to stderr. Useful for
219218
/// debugging.
220-
void dump() const;
219+
void dump() const { SourceLocation::dump(*SrcMgr); }
221220

222221
friend inline bool
223222
operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
@@ -231,7 +230,47 @@ class FullSourceLoc : public SourceLocation {
231230
}
232231

233232
};
234-
233+
234+
/// PresumedLoc - This class represents an unpacked "presumed" location which
235+
/// can be presented to the user. A 'presumed' location can be modified by
236+
/// #line and GNU line marker directives and is always the instantiation point
237+
/// of a normal location.
238+
///
239+
/// You can get a PresumedLoc from a SourceLocation with SourceManager.
240+
class PresumedLoc {
241+
const char *Filename;
242+
unsigned Line, Col;
243+
SourceLocation IncludeLoc;
244+
public:
245+
PresumedLoc() : Filename(0) {}
246+
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
247+
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
248+
}
249+
250+
/// isInvalid - Return true if this object is invalid or uninitialized. This
251+
/// occurs when created with invalid source locations or when walking off
252+
/// the top of a #include stack.
253+
bool isInvalid() const { return Filename == 0; }
254+
bool isValid() const { return Filename != 0; }
255+
256+
/// getFilename - Return the presumed filename of this location. This can be
257+
/// affected by #line etc.
258+
const char *getFilename() const { return Filename; }
259+
260+
/// getLine - Return the presumed line number of this location. This can be
261+
/// affected by #line etc.
262+
unsigned getLine() const { return Line; }
263+
264+
/// getColumn - Return the presumed column number of this location. This can
265+
/// not be affected by #line, but is packaged here for convenience.
266+
unsigned getColumn() const { return Col; }
267+
268+
/// getIncludeLoc - Return the presumed include location of this location.
269+
/// This can be affected by GNU linemarker directives.
270+
SourceLocation getIncludeLoc() const { return IncludeLoc; }
271+
};
272+
273+
235274
} // end namespace clang
236275

237276
namespace llvm {

Diff for: include/clang/Basic/SourceManager.h

+8-12
Original file line numberDiff line numberDiff line change
@@ -404,14 +404,6 @@ class SourceManager {
404404
return SourceLocation::getFileLoc(FileOffset);
405405
}
406406

407-
/// getIncludeLoc - Return the location of the #include for the specified
408-
/// SourceLocation. If this is a macro expansion, this transparently figures
409-
/// out which file includes the file being expanded into.
410-
SourceLocation getIncludeLoc(SourceLocation ID) const {
411-
return getSLocEntry(getFileID(getInstantiationLoc(ID)))
412-
.getFile().getIncludeLoc();
413-
}
414-
415407
/// Given a SourceLocation object, return the instantiation location
416408
/// referenced by the ID.
417409
SourceLocation getInstantiationLoc(SourceLocation Loc) const {
@@ -518,10 +510,14 @@ class SourceManager {
518510
return getSLocEntry(FID).getFile().getFileCharacteristic();
519511
}
520512

521-
/// getSourceName - This method returns the name of the file or buffer that
522-
/// the SourceLocation specifies. This can be modified with #line directives,
523-
/// etc.
524-
const char *getSourceName(SourceLocation Loc) const;
513+
/// getPresumedLoc - This method returns the "presumed" location of a
514+
/// SourceLocation specifies. A "presumed location" can be modified by #line
515+
/// or GNU line marker directives. This provides a view on the data that a
516+
/// user should see in diagnostics, for example.
517+
///
518+
/// Note that a presumed location is always given as the instantiation point
519+
/// of an instantiation location, not at the spelling location.
520+
PresumedLoc getPresumedLoc(SourceLocation Loc) const;
525521

526522

527523

Diff for: include/clang/Driver/TextDiagnosticPrinter.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace clang {
2626
class SourceManager;
2727

2828
class TextDiagnosticPrinter : public DiagnosticClient {
29-
FullSourceLoc LastWarningLoc;
29+
SourceLocation LastWarningLoc;
3030
FullSourceLoc LastLoc;
3131
llvm::raw_ostream &OS;
3232
bool ShowColumn;
@@ -36,7 +36,7 @@ class TextDiagnosticPrinter : public DiagnosticClient {
3636
bool caretDiagnistics = true)
3737
: OS(os), ShowColumn(showColumn), CaretDiagnostics(caretDiagnistics) {}
3838

39-
void PrintIncludeStack(FullSourceLoc Pos);
39+
void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
4040

4141
void HighlightRange(const SourceRange &R,
4242
const SourceManager& SrcMgr,

Diff for: lib/AST/StmtDumper.cpp

+16-11
Original file line numberDiff line numberDiff line change
@@ -153,21 +153,26 @@ namespace {
153153

154154
void StmtDumper::DumpLocation(SourceLocation Loc) {
155155
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
156+
157+
if (SpellingLoc.isInvalid()) {
158+
fprintf(stderr, "<invalid sloc>");
159+
return;
160+
}
156161

157162
// The general format we print out is filename:line:col, but we drop pieces
158163
// that haven't changed since the last loc printed.
159-
const char *Filename = SM->getSourceName(SpellingLoc);
160-
unsigned LineNo = SM->getLineNumber(SpellingLoc);
161-
unsigned ColNo = SM->getColumnNumber(SpellingLoc);
162-
if (strcmp(Filename, LastLocFilename) != 0) {
163-
fprintf(stderr, "%s:%u:%u", Filename, LineNo, ColNo);
164-
LastLocFilename = Filename;
165-
LastLocLine = LineNo;
166-
} else if (LineNo != LastLocLine) {
167-
fprintf(stderr, "line:%u:%u", LineNo, ColNo);
168-
LastLocLine = LineNo;
164+
PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
165+
166+
if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
167+
fprintf(stderr, "%s:%u:%u", PLoc.getFilename(), PLoc.getLine(),
168+
PLoc.getColumn());
169+
LastLocFilename = PLoc.getFilename();
170+
LastLocLine = PLoc.getLine();
171+
} else if (PLoc.getLine() != LastLocLine) {
172+
fprintf(stderr, "line:%u:%u", PLoc.getLine(), PLoc.getColumn());
173+
LastLocLine = PLoc.getLine();
169174
} else {
170-
fprintf(stderr, "col:%u", ColNo);
175+
fprintf(stderr, "col:%u", PLoc.getColumn());
171176
}
172177
}
173178

Diff for: lib/Analysis/LiveVariables.cpp

+3-7
Original file line numberDiff line numberDiff line change
@@ -358,13 +358,9 @@ void LiveVariables::dumpLiveness(const ValTy& V, SourceManager& SM) const {
358358
for (AnalysisDataTy::decl_iterator I = AD.begin_decl(),
359359
E = AD.end_decl(); I!=E; ++I)
360360
if (V.getDeclBit(I->second)) {
361-
SourceLocation SpellingLoc = SM.getSpellingLoc(I->first->getLocation());
362-
363-
fprintf(stderr, " %s <%s:%u:%u>\n",
364-
I->first->getIdentifier()->getName(),
365-
SM.getSourceName(SpellingLoc),
366-
SM.getLineNumber(SpellingLoc),
367-
SM.getColumnNumber(SpellingLoc));
361+
fprintf(stderr, " %s <", I->first->getIdentifier()->getName());
362+
I->first->getLocation().dump(SM);
363+
fprintf(stderr, ">\n");
368364
}
369365
}
370366

Diff for: lib/Basic/SourceLocation.cpp

+23-29
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,29 @@ SourceLocation SourceLocation::ReadVal(llvm::Deserializer& D) {
2626
return SourceLocation::getFromRawEncoding(D.ReadInt());
2727
}
2828

29+
void SourceLocation::dump(const SourceManager &SM) const {
30+
if (!isValid()) {
31+
fprintf(stderr, "<invalid loc>");
32+
return;
33+
}
34+
35+
if (isFileID()) {
36+
PresumedLoc PLoc = SM.getPresumedLoc(*this);
37+
38+
// The instantiation and spelling pos is identical for file locs.
39+
fprintf(stderr, "%s:%d:%d",
40+
PLoc.getFilename(), PLoc.getLine(), PLoc.getColumn());
41+
return;
42+
}
43+
44+
SM.getInstantiationLoc(*this).dump(SM);
45+
46+
fprintf(stderr, " <Spelling=");
47+
SM.getSpellingLoc(*this).dump(SM);
48+
fprintf(stderr, ">");
49+
}
50+
51+
2952
void SourceRange::Emit(llvm::Serializer& S) const {
3053
B.Emit(S);
3154
E.Emit(S);
@@ -53,11 +76,6 @@ FullSourceLoc FullSourceLoc::getSpellingLoc() const {
5376
return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
5477
}
5578

56-
FullSourceLoc FullSourceLoc::getIncludeLoc() const {
57-
assert(isValid());
58-
return FullSourceLoc(SrcMgr->getIncludeLoc(*this), *SrcMgr);
59-
}
60-
6179
unsigned FullSourceLoc::getLineNumber() const {
6280
assert(isValid());
6381
return SrcMgr->getLineNumber(*this);
@@ -89,11 +107,6 @@ unsigned FullSourceLoc::getSpellingColumnNumber() const {
89107
return SrcMgr->getSpellingColumnNumber(*this);
90108
}
91109

92-
const char* FullSourceLoc::getSourceName() const {
93-
assert(isValid());
94-
return SrcMgr->getSourceName(*this);
95-
}
96-
97110
bool FullSourceLoc::isInSystemHeader() const {
98111
assert(isValid());
99112
return SrcMgr->isInSystemHeader(*this);
@@ -109,22 +122,3 @@ const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const {
109122
return SrcMgr->getBuffer(SrcMgr->getFileID(*this));
110123
}
111124

112-
void FullSourceLoc::dump() const {
113-
if (!isValid()) {
114-
fprintf(stderr, "Invalid Loc\n");
115-
return;
116-
}
117-
118-
if (isFileID()) {
119-
// The instantiation and spelling pos is identical for file locs.
120-
fprintf(stderr, "File Loc from '%s': %d: %d\n",
121-
getSourceName(), getInstantiationLineNumber(),
122-
getInstantiationColumnNumber());
123-
} else {
124-
fprintf(stderr, "Macro Loc (\n Spelling: ");
125-
getSpellingLoc().dump();
126-
fprintf(stderr, " Instantiation: ");
127-
getInstantiationLoc().dump();
128-
fprintf(stderr, ")\n");
129-
}
130-
}

0 commit comments

Comments
 (0)