aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2011-04-26 21:50:03 +0000
committerManuel Klimek <klimek@google.com>2011-04-26 21:50:03 +0000
commit0c69fd276063f80a39b885a60d7275391f9a314a (patch)
tree5377e53043e7d28c3dec26cdeeb58228f11520d8 /clang/lib
parent1355bbdd11127d3cb98e81a38f4758f1e10a62ef (diff)
downloadllvm-0c69fd276063f80a39b885a60d7275391f9a314a.zip
llvm-0c69fd276063f80a39b885a60d7275391f9a314a.tar.gz
llvm-0c69fd276063f80a39b885a60d7275391f9a314a.tar.bz2
To be able to replay compilations we need to accurately remodel how
includes get resolved, especially when they are found relatively to another include file. We also try to get it working for framework includes, but that part of the code is untested, as I don't have a code base that uses it. llvm-svn: 130246
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Lex/HeaderMap.cpp5
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp102
-rw-r--r--clang/lib/Lex/PPDirectives.cpp20
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp2
-rw-r--r--clang/lib/Lex/Pragma.cpp2
-rw-r--r--clang/lib/Lex/PreprocessingRecord.cpp3
6 files changed, 100 insertions, 34 deletions
diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp
index 90ed184..e102a6d 100644
--- a/clang/lib/Lex/HeaderMap.cpp
+++ b/clang/lib/Lex/HeaderMap.cpp
@@ -200,8 +200,7 @@ void HeaderMap::dump() const {
/// LookupFile - Check to see if the specified relative filename is located in
/// this HeaderMap. If so, open it and return its FileEntry.
const FileEntry *HeaderMap::LookupFile(
- llvm::StringRef Filename, FileManager &FM,
- llvm::SmallVectorImpl<char> *RawPath) const {
+ llvm::StringRef Filename, FileManager &FM) const {
const HMapHeader &Hdr = getHeader();
unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
@@ -224,8 +223,6 @@ const FileEntry *HeaderMap::LookupFile(
llvm::SmallString<1024> DestPath;
DestPath += getString(B.Prefix);
DestPath += getString(B.Suffix);
- if (RawPath != NULL)
- *RawPath = DestPath;
return FM.getFile(DestPath.str());
}
}
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index db91ba4..1fe0240 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -116,7 +116,9 @@ const char *DirectoryLookup::getName() const {
/// if it exists or returning null if not.
const FileEntry *DirectoryLookup::LookupFile(
llvm::StringRef Filename,
- HeaderSearch &HS, llvm::SmallVectorImpl<char> *RawPath) const {
+ HeaderSearch &HS,
+ llvm::SmallVectorImpl<char> *SearchPath,
+ llvm::SmallVectorImpl<char> *RelativePath) const {
llvm::SmallString<1024> TmpDir;
if (isNormalDir()) {
// Concatenate the requested file onto the directory.
@@ -124,16 +126,36 @@ const FileEntry *DirectoryLookup::LookupFile(
TmpDir += getDir()->getName();
TmpDir.push_back('/');
TmpDir.append(Filename.begin(), Filename.end());
- if (RawPath != NULL)
- *RawPath = TmpDir;
+ if (SearchPath != NULL) {
+ llvm::StringRef SearchPathRef(getDir()->getName());
+ SearchPath->clear();
+ SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
+ }
+ if (RelativePath != NULL) {
+ RelativePath->clear();
+ RelativePath->append(Filename.begin(), Filename.end());
+ }
return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true);
}
if (isFramework())
- return DoFrameworkLookup(Filename, HS, RawPath);
+ return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath);
assert(isHeaderMap() && "Unknown directory lookup");
- return getHeaderMap()->LookupFile(Filename, HS.getFileMgr(), RawPath);
+ const FileEntry * const Result = getHeaderMap()->LookupFile(
+ Filename, HS.getFileMgr());
+ if (Result) {
+ if (SearchPath != NULL) {
+ llvm::StringRef SearchPathRef(getDir()->getName());
+ SearchPath->clear();
+ SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
+ }
+ if (RelativePath != NULL) {
+ RelativePath->clear();
+ RelativePath->append(Filename.begin(), Filename.end());
+ }
+ }
+ return Result;
}
@@ -141,7 +163,9 @@ const FileEntry *DirectoryLookup::LookupFile(
/// DirectoryLookup, which is a framework directory.
const FileEntry *DirectoryLookup::DoFrameworkLookup(
llvm::StringRef Filename,
- HeaderSearch &HS, llvm::SmallVectorImpl<char> *RawPath) const {
+ HeaderSearch &HS,
+ llvm::SmallVectorImpl<char> *SearchPath,
+ llvm::SmallVectorImpl<char> *RelativePath) const {
FileManager &FileMgr = HS.getFileMgr();
// Framework names must have a '/' in the filename.
@@ -187,15 +211,25 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
FrameworkDirCache = getFrameworkDir();
}
+ if (RelativePath != NULL) {
+ RelativePath->clear();
+ RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
+ }
+
// Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
unsigned OrigSize = FrameworkName.size();
FrameworkName += "Headers/";
+
+ if (SearchPath != NULL) {
+ SearchPath->clear();
+ // Without trailing '/'.
+ SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
+ }
+
FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
/*openFile=*/true)) {
- if (RawPath != NULL)
- *RawPath = FrameworkName;
return FE;
}
@@ -203,8 +237,10 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
const char *Private = "Private";
FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
Private+strlen(Private));
- if (RawPath != NULL)
- *RawPath = FrameworkName;
+ if (SearchPath != NULL)
+ SearchPath->insert(SearchPath->begin()+OrigSize, Private,
+ Private+strlen(Private));
+
return FileMgr.getFile(FrameworkName.str(), /*openFile=*/true);
}
@@ -225,7 +261,8 @@ const FileEntry *HeaderSearch::LookupFile(
const DirectoryLookup *FromDir,
const DirectoryLookup *&CurDir,
const FileEntry *CurFileEnt,
- llvm::SmallVectorImpl<char> *RawPath) {
+ llvm::SmallVectorImpl<char> *SearchPath,
+ llvm::SmallVectorImpl<char> *RelativePath) {
// If 'Filename' is absolute, check to see if it exists and no searching.
if (llvm::sys::path::is_absolute(Filename)) {
CurDir = 0;
@@ -233,8 +270,12 @@ const FileEntry *HeaderSearch::LookupFile(
// If this was an #include_next "/absolute/file", fail.
if (FromDir) return 0;
- if (RawPath != NULL)
- llvm::Twine(Filename).toVector(*RawPath);
+ if (SearchPath != NULL)
+ SearchPath->clear();
+ if (RelativePath != NULL) {
+ RelativePath->clear();
+ RelativePath->append(Filename.begin(), Filename.end());
+ }
// Otherwise, just return the file.
return FileMgr.getFile(Filename, /*openFile=*/true);
}
@@ -260,8 +301,15 @@ const FileEntry *HeaderSearch::LookupFile(
// of evaluation.
unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
getFileInfo(FE).DirInfo = DirInfo;
- if (RawPath != NULL)
- *RawPath = TmpDir;
+ if (SearchPath != NULL) {
+ llvm::StringRef SearchPathRef(CurFileEnt->getDir()->getName());
+ SearchPath->clear();
+ SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
+ }
+ if (RelativePath != NULL) {
+ RelativePath->clear();
+ RelativePath->append(Filename.begin(), Filename.end());
+ }
return FE;
}
}
@@ -299,7 +347,7 @@ const FileEntry *HeaderSearch::LookupFile(
// Check each directory in sequence to see if it contains this file.
for (; i != SearchDirs.size(); ++i) {
const FileEntry *FE =
- SearchDirs[i].LookupFile(Filename, *this, RawPath);
+ SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath);
if (!FE) continue;
CurDir = &SearchDirs[i];
@@ -325,7 +373,8 @@ const FileEntry *HeaderSearch::LookupFile(
const FileEntry *HeaderSearch::
LookupSubframeworkHeader(llvm::StringRef Filename,
const FileEntry *ContextFileEnt,
- llvm::SmallVectorImpl<char> *RawPath) {
+ llvm::SmallVectorImpl<char> *SearchPath,
+ llvm::SmallVectorImpl<char> *RelativePath) {
assert(ContextFileEnt && "No context file?");
// Framework names must have a '/' in the filename. Find it.
@@ -373,21 +422,36 @@ LookupSubframeworkHeader(llvm::StringRef Filename,
const FileEntry *FE = 0;
+ if (RelativePath != NULL) {
+ RelativePath->clear();
+ RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
+ }
+
// Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
llvm::SmallString<1024> HeadersFilename(FrameworkName);
HeadersFilename += "Headers/";
+ if (SearchPath != NULL) {
+ SearchPath->clear();
+ // Without trailing '/'.
+ SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
+ }
+
HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) {
// Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
HeadersFilename = FrameworkName;
HeadersFilename += "PrivateHeaders/";
+ if (SearchPath != NULL) {
+ SearchPath->clear();
+ // Without trailing '/'.
+ SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
+ }
+
HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
return 0;
}
- if (RawPath != NULL)
- *RawPath = HeadersFilename;
// This file is a system header or C++ unfriendly if the old file is.
//
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index ac4f8e0..af3fa6e 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -474,7 +474,8 @@ const FileEntry *Preprocessor::LookupFile(
bool isAngled,
const DirectoryLookup *FromDir,
const DirectoryLookup *&CurDir,
- llvm::SmallVectorImpl<char> *RawPath) {
+ llvm::SmallVectorImpl<char> *SearchPath,
+ llvm::SmallVectorImpl<char> *RelativePath) {
// If the header lookup mechanism may be relative to the current file, pass in
// info about where the current file is.
const FileEntry *CurFileEnt = 0;
@@ -497,7 +498,8 @@ const FileEntry *Preprocessor::LookupFile(
// Do a standard file entry lookup.
CurDir = CurDirLookup;
const FileEntry *FE = HeaderInfo.LookupFile(
- Filename, isAngled, FromDir, CurDir, CurFileEnt, RawPath);
+ Filename, isAngled, FromDir, CurDir, CurFileEnt,
+ SearchPath, RelativePath);
if (FE) return FE;
// Otherwise, see if this is a subframework header. If so, this is relative
@@ -506,7 +508,7 @@ const FileEntry *Preprocessor::LookupFile(
if (IsFileLexer()) {
if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
- RawPath)))
+ SearchPath, RelativePath)))
return FE;
}
@@ -515,8 +517,8 @@ const FileEntry *Preprocessor::LookupFile(
if (IsFileLexer(ISEntry)) {
if ((CurFileEnt =
SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
- if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
- RawPath)))
+ if ((FE = HeaderInfo.LookupSubframeworkHeader(
+ Filename, CurFileEnt, SearchPath, RelativePath)))
return FE;
}
}
@@ -1171,11 +1173,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// Search include directories.
const DirectoryLookup *CurDir;
- llvm::SmallString<1024> RawPath;
+ llvm::SmallString<1024> SearchPath;
+ llvm::SmallString<1024> RelativePath;
// We get the raw path only if we have 'Callbacks' to which we later pass
// the path.
const FileEntry *File = LookupFile(
- Filename, isAngled, LookupFrom, CurDir, Callbacks ? &RawPath : NULL);
+ Filename, isAngled, LookupFrom, CurDir,
+ Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL);
if (File == 0) {
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
return;
@@ -1184,7 +1188,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// Notify the callback object that we've seen an inclusion directive.
if (Callbacks)
Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, File,
- End, RawPath);
+ End, SearchPath, RelativePath);
// The #included file will be considered to be a system header if either it is
// in a system include directory, or if the #includer is a system include
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 0e38e39..29f9cd6 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -668,7 +668,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
// Search include directories.
const DirectoryLookup *CurDir;
const FileEntry *File =
- PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL);
+ PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL);
// Get the result value. Result = true means the file exists.
bool Result = File != 0;
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index 5d6ad6e..0c18091 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -368,7 +368,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
// Search include directories for this file.
const DirectoryLookup *CurDir;
- const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL);
+ const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL);
if (File == 0) {
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
return;
diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp
index b7f6e75..9555611 100644
--- a/clang/lib/Lex/PreprocessingRecord.cpp
+++ b/clang/lib/Lex/PreprocessingRecord.cpp
@@ -153,7 +153,8 @@ void PreprocessingRecord::InclusionDirective(
bool IsAngled,
const FileEntry *File,
clang::SourceLocation EndLoc,
- const llvm::SmallVectorImpl<char> &RawPath) {
+ llvm::StringRef SearchPath,
+ llvm::StringRef RelativePath) {
InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {