[cfe-commits] r90329 - in /cfe/trunk: include/clang/Basic/FileManager.h lib/Basic/FileManager.cpp lib/Frontend/InitPreprocessor.cpp test/Misc/Inputs/remapped-file-2 test/Misc/Inputs/remapped-file-3 test/Misc/remap-file.c
Douglas Gregor
dgregor at apple.com
Wed Dec 2 10:12:29 PST 2009
Author: dgregor
Date: Wed Dec 2 12:12:28 2009
New Revision: 90329
URL: http://llvm.org/viewvc/llvm-project?rev=90329&view=rev
Log:
Extend -remap-file=from;to to permit mapping from a non-existent
file. This is accomplished by introducing the notion of a "virtual"
file into the file manager, which provides a FileEntry* for a named
file whose size and modification time are known but which may not
exist on disk.
Added a cute little test that remaps both a .c file and a .h file it
includes to alternative files.
Added:
cfe/trunk/test/Misc/Inputs/remapped-file-2
cfe/trunk/test/Misc/Inputs/remapped-file-3
Modified:
cfe/trunk/include/clang/Basic/FileManager.h
cfe/trunk/lib/Basic/FileManager.cpp
cfe/trunk/lib/Frontend/InitPreprocessor.cpp
cfe/trunk/test/Misc/remap-file.c
Modified: cfe/trunk/include/clang/Basic/FileManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileManager.h?rev=90329&r1=90328&r2=90329&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/FileManager.h (original)
+++ cfe/trunk/include/clang/Basic/FileManager.h Wed Dec 2 12:12:28 2009
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_FILEMANAGER_H
#define LLVM_CLANG_FILEMANAGER_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/OwningPtr.h"
@@ -151,6 +152,9 @@
///
unsigned NextFileUID;
+ /// \brief The virtual files that we have allocated.
+ llvm::SmallVector<FileEntry *, 4> VirtualFileEntries;
+
// Statistics.
unsigned NumDirLookups, NumFileLookups;
unsigned NumDirCacheMisses, NumFileCacheMisses;
@@ -199,6 +203,11 @@
const FileEntry *getFile(const char *FilenameStart,
const char *FilenameEnd);
+ /// \brief Retrieve a file entry for a "virtual" file that acts as
+ /// if there were a file with the given name on disk. The file
+ /// itself is not accessed.
+ const FileEntry *getVirtualFile(const llvm::StringRef &Filename,
+ off_t Size, time_t ModificationTime);
void PrintStats() const;
};
Modified: cfe/trunk/lib/Basic/FileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileManager.cpp?rev=90329&r1=90328&r2=90329&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/FileManager.cpp (original)
+++ cfe/trunk/lib/Basic/FileManager.cpp Wed Dec 2 12:12:28 2009
@@ -147,6 +147,12 @@
FileManager::~FileManager() {
delete &UniqueDirs;
delete &UniqueFiles;
+ for (llvm::SmallVectorImpl<FileEntry *>::iterator
+ V = VirtualFileEntries.begin(),
+ VEnd = VirtualFileEntries.end();
+ V != VEnd;
+ ++V)
+ delete *V;
}
void FileManager::addStatCache(StatSysCallCache *statCache, bool AtBeginning) {
@@ -184,6 +190,30 @@
assert(false && "Stat cache not found for removal");
}
+/// \brief Retrieve the directory that the given file name resides in.
+static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
+ const char *NameStart,
+ const char *NameEnd) {
+ // Figure out what directory it is in. If the string contains a / in it,
+ // strip off everything after it.
+ // FIXME: this logic should be in sys::Path.
+ const char *SlashPos = NameEnd-1;
+ while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
+ --SlashPos;
+ // Ignore duplicate //'s.
+ while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1]))
+ --SlashPos;
+
+ if (SlashPos < NameStart) {
+ // Use the current directory if file has no path component.
+ const char *Name = ".";
+ return FileMgr.getDirectory(Name, Name+1);
+ } else if (SlashPos == NameEnd-1)
+ return 0; // If filename ends with a /, it's a directory.
+ else
+ return FileMgr.getDirectory(NameStart, SlashPos);
+}
+
/// getDirectory - Lookup, cache, and verify the specified directory. This
/// returns null if the directory doesn't exist.
///
@@ -252,33 +282,16 @@
// By default, initialize it to invalid.
NamedFileEnt.setValue(NON_EXISTENT_FILE);
- // Figure out what directory it is in. If the string contains a / in it,
- // strip off everything after it.
- // FIXME: this logic should be in sys::Path.
- const char *SlashPos = NameEnd-1;
- while (SlashPos >= NameStart && !IS_DIR_SEPARATOR_CHAR(SlashPos[0]))
- --SlashPos;
- // Ignore duplicate //'s.
- while (SlashPos > NameStart && IS_DIR_SEPARATOR_CHAR(SlashPos[-1]))
- --SlashPos;
-
- const DirectoryEntry *DirInfo;
- if (SlashPos < NameStart) {
- // Use the current directory if file has no path component.
- const char *Name = ".";
- DirInfo = getDirectory(Name, Name+1);
- } else if (SlashPos == NameEnd-1)
- return 0; // If filename ends with a /, it's a directory.
- else
- DirInfo = getDirectory(NameStart, SlashPos);
-
- if (DirInfo == 0) // Directory doesn't exist, file can't exist.
- return 0;
// Get the null-terminated file name as stored as the key of the
// FileEntries map.
const char *InterndFileName = NamedFileEnt.getKeyData();
+ const DirectoryEntry *DirInfo
+ = getDirectoryFromFile(*this, NameStart, NameEnd);
+ if (DirInfo == 0) // Directory doesn't exist, file can't exist.
+ return 0;
+
// FIXME: Use the directory info to prune this, before doing the stat syscall.
// FIXME: This will reduce the # syscalls.
@@ -312,6 +325,44 @@
return &UFE;
}
+const FileEntry *
+FileManager::getVirtualFile(const llvm::StringRef &Filename,
+ off_t Size, time_t ModificationTime) {
+ const char *NameStart = Filename.begin(), *NameEnd = Filename.end();
+
+ ++NumFileLookups;
+
+ // See if there is already an entry in the map.
+ llvm::StringMapEntry<FileEntry *> &NamedFileEnt =
+ FileEntries.GetOrCreateValue(NameStart, NameEnd);
+
+ // See if there is already an entry in the map.
+ if (NamedFileEnt.getValue())
+ return NamedFileEnt.getValue() == NON_EXISTENT_FILE
+ ? 0 : NamedFileEnt.getValue();
+
+ ++NumFileCacheMisses;
+
+ // By default, initialize it to invalid.
+ NamedFileEnt.setValue(NON_EXISTENT_FILE);
+
+ const DirectoryEntry *DirInfo
+ = getDirectoryFromFile(*this, NameStart, NameEnd);
+ if (DirInfo == 0) // Directory doesn't exist, file can't exist.
+ return 0;
+
+ FileEntry *UFE = new FileEntry();
+ VirtualFileEntries.push_back(UFE);
+ NamedFileEnt.setValue(UFE);
+
+ UFE->Name = NamedFileEnt.getKeyData();
+ UFE->Size = Size;
+ UFE->ModTime = ModificationTime;
+ UFE->Dir = DirInfo;
+ UFE->UID = NextFileUID++;
+ return UFE;
+}
+
void FileManager::PrintStats() const {
llvm::errs() << "\n*** File Manager Stats:\n";
llvm::errs() << UniqueFiles.size() << " files found, "
Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=90329&r1=90328&r2=90329&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Wed Dec 2 12:12:28 2009
@@ -19,6 +19,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/System/Path.h"
@@ -502,11 +503,11 @@
continue;
}
- // Find the file that we're mapping from.
- const FileEntry *FromFile = FileMgr.getFile(Remap->first);
+ // Create the file entry for the file that we're mapping from.
+ const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
+ ToFile->getSize(),
+ 0);
if (!FromFile) {
- // FIXME: We could actually recover from this, by faking a
- // FileEntry based on the "ToFile".
Diags.Report(diag::err_fe_remap_missing_from_file)
<< Remap->first;
continue;
Added: cfe/trunk/test/Misc/Inputs/remapped-file-2
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/Inputs/remapped-file-2?rev=90329&view=auto
==============================================================================
--- cfe/trunk/test/Misc/Inputs/remapped-file-2 (added)
+++ cfe/trunk/test/Misc/Inputs/remapped-file-2 Wed Dec 2 12:12:28 2009
@@ -0,0 +1,3 @@
+#include "nonexistent.h"
+
+int *f() { return fp; }
Added: cfe/trunk/test/Misc/Inputs/remapped-file-3
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/Inputs/remapped-file-3?rev=90329&view=auto
==============================================================================
--- cfe/trunk/test/Misc/Inputs/remapped-file-3 (added)
+++ cfe/trunk/test/Misc/Inputs/remapped-file-3 Wed Dec 2 12:12:28 2009
@@ -0,0 +1,2 @@
+extern float *fp;
+
Modified: cfe/trunk/test/Misc/remap-file.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/remap-file.c?rev=90329&r1=90328&r2=90329&view=diff
==============================================================================
--- cfe/trunk/test/Misc/remap-file.c (original)
+++ cfe/trunk/test/Misc/remap-file.c Wed Dec 2 12:12:28 2009
@@ -1,5 +1,8 @@
-// RUN: clang-cc -remap-file="%s;%S/Inputs/remapped-file" -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: remap-file.c:1:28: warning: incompatible pointer types
+// RUN: clang-cc -remap-file="%s;%S/Inputs/remapped-file" -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-EXIST %s
+// RUN: clang-cc -remap-file="%S/nonexistent.c;%S/Inputs/remapped-file" -fsyntax-only %S/nonexistent.c 2>&1 | FileCheck -check-prefix=CHECK-NONEXIST %s
+// RUN: clang-cc -remap-file="%S/nonexistent.c;%S/Inputs/remapped-file-2" -remap-file="%S/nonexistent.h;%S/Inputs/remapped-file-3" -fsyntax-only %S/nonexistent.c 2>&1 | FileCheck -check-prefix=CHECK-HEADER %s
+// CHECK-EXIST: remap-file.c:1:28: warning: incompatible pointer types
+// CHECK-NONEXIST: nonexistent.c:1:28: warning: incompatible pointer types
+// CHECK-HEADER: nonexistent.c:3:19: warning: incompatible pointer types
int
More information about the cfe-commits
mailing list