kristina updated this revision to Diff 199104.
kristina edited the summary of this revision.
kristina added a comment.

Actually I got it wrong, the path is normalized to use regular slashes at that 
point, so there is no point in handling backslashes in paths at all even with 
Microsoft extensions.

After running it with a hack to dump the paths to stderr they seem to be the 
same regardless.

  [FILENAME] 
/llvm-tainted/tools/clang/test/Preprocessor/Inputs/include-subdir/subdir1/hdr1.h
  [FILENAME] 
/llvm-tainted/tools/clang/test/Preprocessor/Inputs/include-subdir/subdir1/hdr2.h

I've also extended the tests to cover scenarios with mixed slashes in MS 
compatibility mode and removed the unnecessary check.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61756/new/

https://reviews.llvm.org/D61756

Files:
  include/clang/Lex/Preprocessor.h
  lib/Lex/PPMacroExpansion.cpp
  test/Preprocessor/Inputs/include-subdir/file_name_macro_include.h
  test/Preprocessor/Inputs/include-subdir/h
  test/Preprocessor/Inputs/include-subdir/subdir1/hdr1.h
  test/Preprocessor/Inputs/include-subdir/subdir1/hdr2.h
  test/Preprocessor/file_name_macro.c

Index: test/Preprocessor/file_name_macro.c
===================================================================
--- test/Preprocessor/file_name_macro.c
+++ test/Preprocessor/file_name_macro.c
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -E %s -I%S/Inputs | FileCheck -strict-whitespace %s
+// RUN: %clang_cc1 -fms-compatibility -DMS -E %s -I%S/Inputs | FileCheck -check-prefix=CHECK-MS -strict-whitespace %s 
+// RUN: %clang_cc1 -E %s -I%S/Inputs -DBADINC -verify
+
+#ifdef BADINC
+
+// Paranoia.
+
+__FILE_NAME__
+#include <include-subdir/> // expected-error {{file not found}}
+__FILE_NAME__
+
+#else
+
+// Reference.
+1: "file_name_macro.c"
+
+// Ensure it expands correctly for this file.
+2: __FILE_NAME__
+
+// CHECK: {{^}}1: "file_name_macro.c"
+// CHECK: {{^}}2: "file_name_macro.c"
+
+// Test if inclusion works right.
+#ifdef MS
+#include <include-subdir\file_name_macro_include.h>
+// MS compatibility allows for mixed separators in paths.
+#include <include-subdir/subdir1\hdr1.h>
+#include <include-subdir\subdir1/hdr2.h>
+#else
+#include <include-subdir/file_name_macro_include.h>
+#endif
+
+#include <include-subdir/h>
+
+// CHECK: {{^}}3: "file_name_macro_include.h"
+// CHECK: {{^}}4: "file_name_macro_include.h"
+// CHECK-NOT: {{^}}5: "file_name_macro_include.h"
+// CHECK-MS: {{^}}5: "file_name_macro_include.h"
+// CHECK: {{^}}6: "h"
+// CHECK-MS: {{^}}7: "hdr1.h"
+// CHECK-MS: {{^}}8: "hdr2.h"
+
+#endif
Index: test/Preprocessor/Inputs/include-subdir/subdir1/hdr2.h
===================================================================
--- test/Preprocessor/Inputs/include-subdir/subdir1/hdr2.h
+++ test/Preprocessor/Inputs/include-subdir/subdir1/hdr2.h
@@ -0,0 +1 @@
+8: __FILE_NAME__
Index: test/Preprocessor/Inputs/include-subdir/subdir1/hdr1.h
===================================================================
--- test/Preprocessor/Inputs/include-subdir/subdir1/hdr1.h
+++ test/Preprocessor/Inputs/include-subdir/subdir1/hdr1.h
@@ -0,0 +1 @@
+7: __FILE_NAME__
Index: test/Preprocessor/Inputs/include-subdir/h
===================================================================
--- test/Preprocessor/Inputs/include-subdir/h
+++ test/Preprocessor/Inputs/include-subdir/h
@@ -0,0 +1 @@
+6: __FILE_NAME__
Index: test/Preprocessor/Inputs/include-subdir/file_name_macro_include.h
===================================================================
--- test/Preprocessor/Inputs/include-subdir/file_name_macro_include.h
+++ test/Preprocessor/Inputs/include-subdir/file_name_macro_include.h
@@ -0,0 +1,6 @@
+3: __FILE_NAME__
+4: "file_name_macro_include.h"
+#ifdef MS
+// Should be the same even when included with backslash.
+5: __FILE_NAME__
+#endif
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -363,6 +363,7 @@
   }
 
   // Clang Extensions.
+  Ident__FILE_NAME__      = RegisterBuiltinMacro(*this, "__FILE_NAME__");
   Ident__has_feature      = RegisterBuiltinMacro(*this, "__has_feature");
   Ident__has_extension    = RegisterBuiltinMacro(*this, "__has_extension");
   Ident__has_builtin      = RegisterBuiltinMacro(*this, "__has_builtin");
@@ -1474,7 +1475,8 @@
     // __LINE__ expands to a simple numeric value.
     OS << (PLoc.isValid()? PLoc.getLine() : 1);
     Tok.setKind(tok::numeric_constant);
-  } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
+  } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__ ||
+             II == Ident__FILE_NAME__) {
     // C99 6.10.8: "__FILE__: The presumed name of the current source file (a
     // character string literal)". This can be affected by #line.
     PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
@@ -1495,7 +1497,21 @@
     // Escape this filename.  Turn '\' -> '\\' '"' -> '\"'
     SmallString<128> FN;
     if (PLoc.isValid()) {
-      FN += PLoc.getFilename();
+      // __FILE_NAME__ is a Clang-specific extension that expands to the
+      // the last part of __FILE__.
+      if (II == Ident__FILE_NAME__) {
+        // Try to get the last path component.
+        StringRef PLFileName = PLoc.getFilename(); 
+        size_t LastSep = PLFileName.find_last_of('/');        
+        // Skip the separator and get the last part, otherwise fall back on
+        // returning the original full filename.
+        if (LastSep != StringRef::npos)
+          FN += PLFileName.substr(LastSep+1);
+        else
+          FN += PLFileName;
+      } else {
+        FN += PLoc.getFilename();
+      }
       Lexer::Stringify(FN);
       OS << '"' << FN << '"';
     }
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h
+++ include/clang/Lex/Preprocessor.h
@@ -147,6 +147,7 @@
   IdentifierInfo *Ident__DATE__, *Ident__TIME__;   // __DATE__, __TIME__
   IdentifierInfo *Ident__INCLUDE_LEVEL__;          // __INCLUDE_LEVEL__
   IdentifierInfo *Ident__BASE_FILE__;              // __BASE_FILE__
+  IdentifierInfo *Ident__FILE_NAME__;              // __FILE_NAME__
   IdentifierInfo *Ident__TIMESTAMP__;              // __TIMESTAMP__
   IdentifierInfo *Ident__COUNTER__;                // __COUNTER__
   IdentifierInfo *Ident_Pragma, *Ident__pragma;    // _Pragma, __pragma
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to