[cfe-commits] r124374 - in /cfe/trunk: lib/Basic/FileManager.cpp lib/Frontend/TextDiagnosticPrinter.cpp lib/Serialization/ASTReader.cpp test/PCH/missing-file.cpp
Axel Naumann
Axel.Naumann at cern.ch
Thu Jan 27 02:55:51 PST 2011
Author: axel
Date: Thu Jan 27 04:55:51 2011
New Revision: 124374
URL: http://llvm.org/viewvc/llvm-project?rev=124374&view=rev
Log:
TextDiagnosticPrinter.cpp: Show diagnostics as far as possible even with invalid PresomedLoc, instead of just silencing it.
FileManager.cpp: Allow virtual files in nonexistent directories.
FileManager.cpp: Close FileDescriptor for virtual files that correspond to actual files.
FileManager.cpp: Enable virtual files to be created even for files that were flagged as NON_EXISTENT_FILE, e.g. by a prior (unsuccessful) addFile().
ASTReader.cpp: Read a PCH even if the original source files cannot be found.
Add a test for reading a PCH of a file that has been removed and diagnostics referencing that file.
Added:
cfe/trunk/test/PCH/missing-file.cpp
Modified:
cfe/trunk/lib/Basic/FileManager.cpp
cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
Modified: cfe/trunk/lib/Basic/FileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileManager.cpp?rev=124374&r1=124373&r2=124374&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/FileManager.cpp (original)
+++ cfe/trunk/lib/Basic/FileManager.cpp Thu Jan 27 04:55:51 2011
@@ -350,18 +350,17 @@
FileEntries.GetOrCreateValue(Filename);
// See if there is already an entry in the map.
- if (NamedFileEnt.getValue())
- return NamedFileEnt.getValue() == NON_EXISTENT_FILE
- ? 0 : NamedFileEnt.getValue();
+ if (NamedFileEnt.getValue() && NamedFileEnt.getValue() != NON_EXISTENT_FILE)
+ return NamedFileEnt.getValue();
++NumFileCacheMisses;
// By default, initialize it to invalid.
NamedFileEnt.setValue(NON_EXISTENT_FILE);
+ // We allow the directory to not exist. If it does exist we store it.
+ //
const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename);
- if (DirInfo == 0) // Directory doesn't exist, file can't exist.
- return 0;
FileEntry *UFE = new FileEntry();
VirtualFileEntries.push_back(UFE);
@@ -381,8 +380,13 @@
// newly-created file entry.
int FileDescriptor = -1;
struct stat StatBuf;
- if (getStatValue(InterndFileName, StatBuf, &FileDescriptor))
+ if (getStatValue(InterndFileName, StatBuf, &FileDescriptor)) {
+ // If the stat process opened the file, close it to avoid a FD leak.
+ if (FileDescriptor != -1)
+ close(FileDescriptor);
+
return UFE;
+ }
UFE->FD = FileDescriptor;
llvm::SmallString<128> FilePath(UFE->Name);
Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=124374&r1=124373&r2=124374&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Thu Jan 27 04:55:51 2011
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Lex/Lexer.h"
@@ -139,8 +140,9 @@
(SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
--EndColNo;
- // If the start/end passed each other, then we are trying to highlight a range
- // that just exists in whitespace, which must be some sort of other bug.
+ // If the start/end passed each other, then we are trying to highlight a
+ // range that just exists in whitespace, which must be some sort of other
+ // bug.
assert(StartColNo <= EndColNo && "Trying to highlight whitespace??");
}
@@ -781,78 +783,94 @@
if (Info.getLocation().isValid()) {
const SourceManager &SM = Info.getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation());
- if (PLoc.isInvalid())
- return;
-
- unsigned LineNo = PLoc.getLine();
-
- // First, if this diagnostic is not in the main file, print out the
- // "included from" lines.
- if (LastWarningLoc != PLoc.getIncludeLoc()) {
- LastWarningLoc = PLoc.getIncludeLoc();
- PrintIncludeStack(LastWarningLoc, SM);
- StartOfLocationInfo = OS.tell();
- }
-
- // Compute the column number.
- if (DiagOpts->ShowLocation && PLoc.isValid()) {
- if (DiagOpts->ShowColors)
- OS.changeColor(savedColor, true);
+ if (PLoc.isInvalid()) {
+ // At least print the file name if available:
+ FileID FID = SM.getFileID(Info.getLocation());
+ if (!FID.isInvalid()) {
+ const FileEntry* FE = SM.getFileEntryForID(FID);
+ if (FE && FE->getName()) {
+ OS << FE->getName();
+ if (FE->getDevice() == 0 && FE->getInode() == 0
+ && FE->getFileMode() == 0) {
+ // in PCH is a guess, but a good one:
+ OS << " (in PCH)";
+ }
+ OS << ": ";
+ }
+ }
+ } else {
+ unsigned LineNo = PLoc.getLine();
- // Emit a Visual Studio compatible line number syntax.
- if (LangOpts && LangOpts->Microsoft) {
- OS << PLoc.getFilename() << '(' << LineNo << ')';
- OS << " : ";
- } else {
- OS << PLoc.getFilename() << ':' << LineNo << ':';
- if (DiagOpts->ShowColumn)
- if (unsigned ColNo = PLoc.getColumn())
- OS << ColNo << ':';
+ // First, if this diagnostic is not in the main file, print out the
+ // "included from" lines.
+ if (LastWarningLoc != PLoc.getIncludeLoc()) {
+ LastWarningLoc = PLoc.getIncludeLoc();
+ PrintIncludeStack(LastWarningLoc, SM);
+ StartOfLocationInfo = OS.tell();
}
- if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) {
- FileID CaretFileID =
- SM.getFileID(SM.getInstantiationLoc(Info.getLocation()));
- bool PrintedRange = false;
-
- for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) {
- // Ignore invalid ranges.
- if (!Info.getRange(i).isValid()) continue;
-
- SourceLocation B = Info.getRange(i).getBegin();
- SourceLocation E = Info.getRange(i).getEnd();
- B = SM.getInstantiationLoc(B);
- E = SM.getInstantiationLoc(E);
-
- // If the End location and the start location are the same and are a
- // macro location, then the range was something that came from a macro
- // expansion or _Pragma. If this is an object-like macro, the best we
- // can do is to highlight the range. If this is a function-like
- // macro, we'd also like to highlight the arguments.
- if (B == E && Info.getRange(i).getEnd().isMacroID())
- E = SM.getInstantiationRange(Info.getRange(i).getEnd()).second;
-
- std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
- std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
-
- // If the start or end of the range is in another file, just discard
- // it.
- if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
- continue;
-
- // Add in the length of the token, so that we cover multi-char tokens.
- unsigned TokSize = 0;
- if (Info.getRange(i).isTokenRange())
- TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts);
-
- OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
- << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
- << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
- << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize) << '}';
- PrintedRange = true;
+
+ // Compute the column number.
+ if (DiagOpts->ShowLocation && PLoc.isValid()) {
+ if (DiagOpts->ShowColors)
+ OS.changeColor(savedColor, true);
+
+ // Emit a Visual Studio compatible line number syntax.
+ if (LangOpts && LangOpts->Microsoft) {
+ OS << PLoc.getFilename() << '(' << LineNo << ')';
+ OS << " : ";
+ } else {
+ OS << PLoc.getFilename() << ':' << LineNo << ':';
+ if (DiagOpts->ShowColumn)
+ if (unsigned ColNo = PLoc.getColumn())
+ OS << ColNo << ':';
}
+ if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) {
+ FileID CaretFileID =
+ SM.getFileID(SM.getInstantiationLoc(Info.getLocation()));
+ bool PrintedRange = false;
+
+ for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) {
+ // Ignore invalid ranges.
+ if (!Info.getRange(i).isValid()) continue;
+
+ SourceLocation B = Info.getRange(i).getBegin();
+ SourceLocation E = Info.getRange(i).getEnd();
+ B = SM.getInstantiationLoc(B);
+ E = SM.getInstantiationLoc(E);
+
+ // If the End location and the start location are the same and are a
+ // macro location, then the range was something that came from a
+ // macro expansion or _Pragma. If this is an object-like macro, the
+ // best we can do is to highlight the range. If this is a
+ // function-like macro, we'd also like to highlight the arguments.
+ if (B == E && Info.getRange(i).getEnd().isMacroID())
+ E = SM.getInstantiationRange(Info.getRange(i).getEnd()).second;
+
+ std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
+ std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
+
+ // If the start or end of the range is in another file, just discard
+ // it.
+ if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
+ continue;
+
+ // Add in the length of the token, so that we cover multi-char
+ // tokens.
+ unsigned TokSize = 0;
+ if (Info.getRange(i).isTokenRange())
+ TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts);
+
+ OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
+ << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
+ << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
+ << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize)
+ << '}';
+ PrintedRange = true;
+ }
- if (PrintedRange)
- OS << ':';
+ if (PrintedRange)
+ OS << ':';
+ }
}
OS << ' ';
if (DiagOpts->ShowColors)
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=124374&r1=124373&r2=124374&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Jan 27 04:55:51 2011
@@ -1232,6 +1232,9 @@
std::string Filename(BlobStart, BlobStart + BlobLen);
MaybeAddSystemRootToFilename(Filename);
const FileEntry *File = FileMgr.getFile(Filename);
+ if (File == 0)
+ File = FileMgr.getVirtualFile(Filename, (off_t)Record[4],
+ (time_t)Record[5]);
if (File == 0) {
std::string ErrorStr = "could not find file '";
ErrorStr += Filename;
Added: cfe/trunk/test/PCH/missing-file.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/missing-file.cpp?rev=124374&view=auto
==============================================================================
--- cfe/trunk/test/PCH/missing-file.cpp (added)
+++ cfe/trunk/test/PCH/missing-file.cpp Thu Jan 27 04:55:51 2011
@@ -0,0 +1,32 @@
+// Test reading of PCH without original input files.
+
+// Generate the PCH, removing the original file:
+// RUN: echo 'struct S{char c; int i; }; void foo() {}' > %t.h
+// RUN: echo 'template <typename T> void tf() { T::foo(); }' >> %t.h
+// RUN: echo '#define RETURN return &i' >> %t.h
+// RUN: %clang_cc1 -x c++ -emit-pch -o %t.h.pch %t.h
+// RUN: rm %t.h
+
+// Check diagnostic with location in original source:
+// RUN: %clang_cc1 -include-pch %t.h.pch -Wpadded -emit-obj %s 2> %t.stderr
+// RUN: grep 'bytes to align' %t.stderr
+
+// Check diagnostic with 2nd location in original source:
+// RUN: not %clang_cc1 -DREDECL -include-pch %t.h.pch -emit-obj %s 2> %t.stderr
+// RUN: grep 'previous definition is here' %t.stderr
+
+// Check diagnostic with instantiation location in original source:
+// RUN: not %clang_cc1 -DINSTANTIATION -include-pch %t.h.pch -emit-obj %s 2> %t.stderr
+// RUN: grep 'cannot be used prior to' %t.stderr
+
+void qq(S*) {}
+
+#ifdef REDECL
+float foo() {return 0f;}
+#endif
+
+#ifdef INSTANTIATION
+void f() {
+ tf<int>();
+}
+#endif
More information about the cfe-commits
mailing list