Index: test/Frontend/stdin2.c
===================================================================
--- test/Frontend/stdin2.c	(revision 0)
+++ test/Frontend/stdin2.c	(revision 0)
@@ -0,0 +1,11 @@
+// RUN: %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
Index: include/clang/Lex/HeaderSearch.h
===================================================================
--- include/clang/Lex/HeaderSearch.h	(revision 105899)
+++ include/clang/Lex/HeaderSearch.h	(working copy)
@@ -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
Index: lib/Lex/PPDirectives.cpp
===================================================================
--- lib/Lex/PPDirectives.cpp	(revision 105899)
+++ lib/Lex/PPDirectives.cpp	(working copy)
@@ -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)))
Index: lib/Lex/HeaderSearch.cpp
===================================================================
--- lib/Lex/HeaderSearch.cpp	(revision 105899)
+++ lib/Lex/HeaderSearch.cpp	(working copy)
@@ -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;
     }
