[cfe-commits] r110440 - in /cfe/trunk: include/clang/Lex/HeaderSearch.h lib/Lex/HeaderSearch.cpp lib/Lex/PPDirectives.cpp test/Frontend/stdin2.c
Douglas Gregor
dgregor at apple.com
Fri Aug 6 05:06:13 PDT 2010
Author: dgregor
Date: Fri Aug 6 07:06:13 2010
New Revision: 110440
URL: http://llvm.org/viewvc/llvm-project?rev=110440&view=rev
Log:
Fix the #include search path when reading from stdin, from Jon Simons!
Fixes PR4897.
Added:
cfe/trunk/test/Frontend/stdin2.c (with props)
Modified:
cfe/trunk/include/clang/Lex/HeaderSearch.h
cfe/trunk/lib/Lex/HeaderSearch.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=110440&r1=110439&r2=110440&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Fri Aug 6 07:06:13 2010
@@ -16,6 +16,7 @@
#include "clang/Lex/DirectoryLookup.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/System/Path.h"
#include <vector>
namespace clang {
@@ -144,16 +145,16 @@
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
/// return null on failure. isAngled indicates whether the file reference is
- /// a <> reference. If successful, this returns 'UsedDir', the
+ /// a <> reference. If successful, this returns 'CurDir', the
/// DirectoryLookup member the file was found in, or null if not applicable.
/// If CurDir is non-null, the file was found in the specified directory
- /// search location. This is used to implement #include_next. CurFileEnt, if
- /// non-null, indicates where the #including file is, in case a relative
+ /// search location. This is used to implement #include_next. RelSearchPath,
+ /// if non-empty, indicates where the #including file is, in case a relative
/// search is needed.
const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled,
const DirectoryLookup *FromDir,
const DirectoryLookup *&CurDir,
- const FileEntry *CurFileEnt);
+ const llvm::sys::Path &RelSearchPath);
/// LookupSubframeworkHeader - Look up a subframework for the specified
/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=110440&r1=110439&r2=110440&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Fri Aug 6 07:06:13 2010
@@ -203,14 +203,14 @@
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
/// return null on failure. isAngled indicates whether the file reference is
-/// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if
-/// non-null, indicates where the #including file is, in case a relative search
-/// is needed.
+/// for system #include's or not (i.e. using <> instead of ""). RelSearchDir,
+/// if non-empty, indicates where the #including file is, in case a relative
+/// search is needed.
const FileEntry *HeaderSearch::LookupFile(llvm::StringRef Filename,
bool isAngled,
const DirectoryLookup *FromDir,
const DirectoryLookup *&CurDir,
- const FileEntry *CurFileEnt) {
+ const llvm::sys::Path &RelPath) {
// If 'Filename' is absolute, check to see if it exists and no searching.
if (llvm::sys::Path::isAbsolute(Filename.begin(), Filename.size())) {
CurDir = 0;
@@ -223,25 +223,29 @@
}
// Step #0, unless disabled, check to see if the file is in the #includer's
- // directory. This has to be based on CurFileEnt, not CurDir, because
- // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
+ // directory. This has to be based on RelPath, not CurDir, because
+ // RelPath could be a #include of a subdirectory (#include "foo/bar.h") and
// a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
// This search is not done for <> headers.
- if (CurFileEnt && !isAngled && !NoCurDirSearch) {
- llvm::SmallString<1024> TmpDir;
- // Concatenate the requested file onto the directory.
- // FIXME: Portability. Filename concatenation should be in sys::Path.
- TmpDir += CurFileEnt->getDir()->getName();
- TmpDir.push_back('/');
- TmpDir.append(Filename.begin(), Filename.end());
- if (const FileEntry *FE = FileMgr.getFile(TmpDir.str())) {
+ if (!RelPath.isEmpty() && !isAngled && !NoCurDirSearch) {
+
+ // Default SrcMgr::CharacteristicKind
+ unsigned DirInfo = SrcMgr::C_User;
+ llvm::sys::Path TmpPath(RelPath);
+
+ // Update DirInfo if needed and remove filename from path if
+ // treating actual file (the non-stdin case)
+ if (!TmpPath.isDirectory()) {
+ const FileEntry *MainFile = FileMgr.getFile(TmpPath.c_str());
+ DirInfo = getFileInfo(MainFile).DirInfo;
+ TmpPath.eraseComponent();
+ }
+
+ // Formulate path to try
+ TmpPath.appendComponent(Filename);
+ llvm::StringRef RelSearchFilename(TmpPath.c_str());
+ if (const FileEntry *FE = FileMgr.getFile(RelSearchFilename)) {
// Leave CurDir unset.
- // This file is a system header or C++ unfriendly if the old file is.
- //
- // Note that the temporary 'DirInfo' is required here, as either call to
- // getFileInfo could resize the vector and we don't want to rely on order
- // of evaluation.
- unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
getFileInfo(FE).DirInfo = DirInfo;
return FE;
}
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=110440&r1=110439&r2=110440&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Aug 6 07:06:13 2010
@@ -19,6 +19,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/System/Path.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -416,33 +417,49 @@
const DirectoryLookup *&CurDir) {
// 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;
+ llvm::sys::Path RelSearchPath;
+
if (!FromDir) {
FileID FID = getCurrentFileLexer()->getFileID();
- CurFileEnt = SourceMgr.getFileEntryForID(FID);
+ const FileEntry *CurFileEnt = SourceMgr.getFileEntryForID(FID);
// If there is no file entry associated with this file, it must be the
// predefines buffer. Any other file is not lexed with a normal lexer, so
- // it won't be scanned for preprocessor directives. If we have the
- // predefines buffer, resolve #include references (which come from the
- // -include command line argument) as if they came from the main file, this
- // affects file lookup etc.
- if (CurFileEnt == 0) {
+ // it won't be scanned for preprocessor directives.
+ //
+ // If we have the predefines buffer, resolve #include references (which
+ // come from the -include command line argument) as if they came from the
+ // main file. When the main file is actually stdin, resolve references
+ // as if they came from the current working directory.
+ if (CurFileEnt) {
+ if (!RelSearchPath.set(CurFileEnt->getDir()->getName())) {
+ assert("Main file somehow invalid path?");
+ }
+ } else {
FID = SourceMgr.getMainFileID();
CurFileEnt = SourceMgr.getFileEntryForID(FID);
+
+ if (CurFileEnt) {
+ // 'main file' case
+ RelSearchPath.set(CurFileEnt->getDir()->getName());
+ } else {
+ // stdin case
+ RelSearchPath = llvm::sys::Path::GetCurrentDirectory();
+ }
}
}
// Do a standard file entry lookup.
CurDir = CurDirLookup;
const FileEntry *FE =
- HeaderInfo.LookupFile(Filename, isAngled, FromDir, CurDir, CurFileEnt);
+ HeaderInfo.LookupFile(Filename, isAngled, FromDir, CurDir, RelSearchPath);
if (FE) return FE;
// Otherwise, see if this is a subframework header. If so, this is relative
// to one of the headers on the #include stack. Walk the list of the current
// headers on the #include stack and pass them to HeaderInfo.
if (IsFileLexer()) {
+ const FileEntry *CurFileEnt = 0;
if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
return FE;
@@ -451,6 +468,7 @@
for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
if (IsFileLexer(ISEntry)) {
+ const FileEntry *CurFileEnt = 0;
if ((CurFileEnt =
SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
Added: cfe/trunk/test/Frontend/stdin2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/stdin2.c?rev=110440&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/stdin2.c (added)
+++ cfe/trunk/test/Frontend/stdin2.c Fri Aug 6 07:06:13 2010
@@ -0,0 +1,11 @@
+// RUN: cd %S && %clang_cc1 -E - < stdin2.c
+
+/*
+ * Bug 4897; current working directory should be searched
+ * for #includes when input is stdin.
+ */
+
+#ifndef BUG_4897
+#define BUG_4897
+#include "stdin2.c"
+#endif
Propchange: cfe/trunk/test/Frontend/stdin2.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Frontend/stdin2.c
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Frontend/stdin2.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list