]> granicus.if.org Git - clang/commitdiff
Handle -D arguments ending in a backslash.
authorEli Friedman <eli.friedman@gmail.com>
Wed, 28 Aug 2013 20:35:38 +0000 (20:35 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 28 Aug 2013 20:35:38 +0000 (20:35 +0000)
We translate these into #define directives; to preserve gcc-compatible
semantics (where the expanded macro includes the backslash), we add
an extra "\\\n" to the end of the synthesized "#define".

<rdar://problem/14810220>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189511 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Frontend/InitPreprocessor.cpp
test/Preprocessor/macro_backslash.c [new file with mode: 0644]

index dc3ab53eda094b64fef76e20fbe874628cf133ef..2eb74e0825f157a1187a9fa213735ebd29b1c17b 100644 (file)
 #include "llvm/Support/Path.h"
 using namespace clang;
 
+static bool MacroBodyEndsInBackslash(StringRef MacroBody) {
+  while (!MacroBody.empty() && isWhitespace(MacroBody.back()))
+    MacroBody = MacroBody.drop_back();
+  return !MacroBody.empty() && MacroBody.back() == '\\';
+}
+
 // Append a #define line to Buf for Macro.  Macro should be of the form XXX,
 // in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
 // "#define XXX Y z W".  To get a #define with no value, use "XXX=".
@@ -43,7 +49,14 @@ static void DefineBuiltinMacro(MacroBuilder &Builder, StringRef Macro,
     if (End != StringRef::npos)
       Diags.Report(diag::warn_fe_macro_contains_embedded_newline)
         << MacroName;
-    Builder.defineMacro(MacroName, MacroBody.substr(0, End));
+    MacroBody = MacroBody.substr(0, End);
+    // We handle macro bodies which end in a backslash by appending an extra
+    // backslash+newline.  This makes sure we don't accidentally treat the
+    // backslash as a line continuation marker.
+    if (MacroBodyEndsInBackslash(MacroBody))
+      Builder.defineMacro(MacroName, Twine(MacroBody) + "\\\n");
+    else
+      Builder.defineMacro(MacroName, MacroBody);
   } else {
     // Push "macroname 1".
     Builder.defineMacro(Macro);
diff --git a/test/Preprocessor/macro_backslash.c b/test/Preprocessor/macro_backslash.c
new file mode 100644 (file)
index 0000000..76f5d41
--- /dev/null
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -E %s -Dfoo='bar\' | FileCheck %s
+// CHECK: TTA bar\ TTB
+TTA foo TTB