weimingz updated this revision to Diff 50300.
weimingz added a comment.

rebased


http://reviews.llvm.org/D17741

Files:
  include/clang/Driver/Options.td
  include/clang/Lex/Preprocessor.h
  include/clang/Lex/PreprocessorOptions.h
  lib/Driver/Tools.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Lex/PPMacroExpansion.cpp
  test/Lexer/file_basename.c

Index: test/Lexer/file_basename.c
===================================================================
--- /dev/null
+++ test/Lexer/file_basename.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -E %s | FileCheck %s --check-prefix=ALL --check-prefix=DEFAULT
+
+// RUN: %clang_cc1 -E -ffile-macro-prefix-to-remove=__ALL_DIR__ %s | FileCheck %s --check-prefix=ALL --check-prefix=NO-DIR
+// RUN:%clang -E -ffile-macro-prefix-to-remove=__ALL_DIR__ %s | FileCheck %s --check-prefix=ALL --check-prefix=NO-DIR
+
+// RUN: %clang_cc1 -E -ffile-macro-prefix-to-remove=%s %s | FileCheck %s --check-prefix=ALL --check-prefix=REMOVE-ALL
+// RUN: %clang -E -ffile-macro-prefix-to-remove=%s %s | FileCheck %s --check-prefix=ALL --check-prefix=REMOVE-ALL
+
+// RUN: %clang_cc1 -E -ffile-macro-prefix-to-remove=%s.xyz %s | FileCheck %s --check-prefix=ALL --check-prefix=MISMATCH
+// RUN: %clang -E -ffile-macro-prefix-to-remove= %s | FileCheck %s --check-prefix=ALL --check-prefix=MISMATCH
+
+const char *filename (const char *name) {
+  // ALL:  static const char this_file_basename[] = "file_basename.c";
+  static const char this_file_basename[] = __CLANG_FILE_BASENAME__;
+  // DEFAULT: static const char this_file[] = "{{.*}}/Lexer/file_basename.c";
+  // NO-DIR:  static const char this_file[] = "file_basename.c";
+  // REMOVE-ALL: static const char this_file[] = "";
+  // MISMATCH: static const char this_file[] = "{{.*}}/Lexer/file_basename.c";
+  static const char this_file[] = __FILE__;
+  return this_file;
+}
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -12,7 +12,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/Attributes.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
@@ -22,12 +21,15 @@
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/MacroArgs.h"
 #include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorOptions.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdio>
 #include <ctime>
@@ -292,6 +294,8 @@
 void Preprocessor::RegisterBuiltinMacros() {
   Ident__LINE__ = RegisterBuiltinMacro(*this, "__LINE__");
   Ident__FILE__ = RegisterBuiltinMacro(*this, "__FILE__");
+  Ident__CLANG_FILE_BASENAME__ =
+      RegisterBuiltinMacro(*this, "__CLANG_FILE_BASENAME__");
   Ident__DATE__ = RegisterBuiltinMacro(*this, "__DATE__");
   Ident__TIME__ = RegisterBuiltinMacro(*this, "__TIME__");
   Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__");
@@ -1509,7 +1513,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__CLANG_FILE_BASENAME__) {
     // 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());
@@ -1522,15 +1527,30 @@
         PLoc = SourceMgr.getPresumedLoc(NextLoc);
         if (PLoc.isInvalid())
           break;
-        
         NextLoc = PLoc.getIncludeLoc();
       }
     }
 
     // Escape this filename.  Turn '\' -> '\\' '"' -> '\"'
     SmallString<128> FN;
     if (PLoc.isValid()) {
-      FN += PLoc.getFilename();
+      const std::string &PrefixToRemove =
+          getPreprocessorOpts().__FILE__PrefixToRemove;
+      StringRef Filename(PLoc.getFilename());
+
+      if (II == Ident__CLANG_FILE_BASENAME__)
+        FN += llvm::sys::path::filename(Filename);
+      else if (II == Ident__FILE__ && !PrefixToRemove.empty()) {
+        if (PrefixToRemove == "__ALL_DIR__") {
+          FN += llvm::sys::path::filename(Filename);
+        }
+        else if (Filename.find(PrefixToRemove) == 0)
+          FN += Filename.substr(PrefixToRemove.size());
+        else
+          FN += Filename;
+      } else
+        FN += Filename;
+
       Lexer::Stringify(FN);
       OS << '"' << FN << '"';
     }
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2031,6 +2031,8 @@
     else
       Opts.ObjCXXARCStandardLibrary = (ObjCXXARCStandardLibraryKind)Library;
   }
+  if (Arg *A = Args.getLastArg(OPT_FILE__prefix_to_remove))
+    Opts.__FILE__PrefixToRemove = A->getValue();
 }
 
 static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -567,6 +567,14 @@
   // Add CUDA include arguments, if needed.
   if (types::isCuda(Inputs[0].getType()))
     getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
+
+  // Add FILE macro prefix removing arguments.
+  if (const Arg *A = Args.getLastArg(options::OPT_FILE__prefix_to_remove)) {
+    StringRef Value = A->getValue();
+    if (!Value.empty())
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-ffile-macro-prefix-to-remove=") + Value));
+  }
 }
 
 // FIXME: Move to target hook.
Index: include/clang/Lex/PreprocessorOptions.h
===================================================================
--- include/clang/Lex/PreprocessorOptions.h
+++ include/clang/Lex/PreprocessorOptions.h
@@ -108,15 +108,20 @@
   /// the buffers associated with remapped files.
   ///
   /// This flag defaults to false; it can be set true only through direct
-  /// manipulation of the compiler invocation object, in cases where the 
+  /// manipulation of the compiler invocation object, in cases where the
   /// compiler invocation and its buffers will be reused.
   bool RetainRemappedFileBuffers;
-  
+
+  /// \brief This string will be used in expanding __FILE__ macro. If it
+  //  matches the prefix of __FILE__, the mathed part won't be expanded.
+  //  If it is "__ALL_DIR__", only the basename will be expanded.
+  std::string __FILE__PrefixToRemove;
+
   /// \brief The Objective-C++ ARC standard library that we should support,
   /// by providing appropriate definitions to retrofit the standard library
   /// with support for lifetime-qualified pointers.
   ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
-    
+
   /// \brief Records the set of modules
   class FailedModulesSet : public RefCountedBase<FailedModulesSet> {
     llvm::StringSet<> Failed;
@@ -140,14 +145,12 @@
   IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
 
 public:
-  PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
-                          DisablePCHValidation(false),
-                          AllowPCHWithCompilerErrors(false),
-                          DumpDeserializedPCHDecls(false),
-                          PrecompiledPreambleBytes(0, true),
-                          RemappedFilesKeepOriginalName(true),
-                          RetainRemappedFileBuffers(false),
-                          ObjCXXARCStandardLibrary(ARCXX_nolib) { }
+  PreprocessorOptions()
+      : UsePredefines(true), DetailedRecord(false), DisablePCHValidation(false),
+        AllowPCHWithCompilerErrors(false), DumpDeserializedPCHDecls(false),
+        PrecompiledPreambleBytes(0, true), RemappedFilesKeepOriginalName(true),
+        RetainRemappedFileBuffers(false), __FILE__PrefixToRemove(""),
+        ObjCXXARCStandardLibrary(ARCXX_nolib) {}
 
   void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); }
   void addMacroUndef(StringRef Name) { Macros.emplace_back(Name, true); }
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h
+++ include/clang/Lex/Preprocessor.h
@@ -119,6 +119,7 @@
 
   /// Identifiers for builtin macros and other builtins.
   IdentifierInfo *Ident__LINE__, *Ident__FILE__;   // __LINE__, __FILE__
+  IdentifierInfo *Ident__CLANG_FILE_BASENAME__;    //  __FILE_BASENAME__
   IdentifierInfo *Ident__DATE__, *Ident__TIME__;   // __DATE__, __TIME__
   IdentifierInfo *Ident__INCLUDE_LEVEL__;          // __INCLUDE_LEVEL__
   IdentifierInfo *Ident__BASE_FILE__;              // __BASE_FILE__
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -816,7 +816,9 @@
   Flag <["-"], "fno-implicit-modules">,
   Group<f_Group>, Flags<[DriverOption, CC1Option]>;
 def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>;
-
+def FILE__prefix_to_remove : Joined<["-"], "ffile-macro-prefix-to-remove=">,
+  Group<f_Group>, Flags<[DriverOption, CC1Option]>,
+  HelpText<"prefix to be removed from expanded string of __FILE__ macro. __ALL_DIR__ removes all dir">;
 def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>;
 def fmudflap : Flag<["-"], "fmudflap">, Group<f_Group>;
 def fnested_functions : Flag<["-"], "fnested-functions">, Group<f_Group>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to