From 2afb63c0010ae69eefb34ce5926dcec21934e394 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 28 Aug 2013 20:35:38 +0000 Subject: Handle -D arguments ending in a backslash. 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". llvm-svn: 189511 --- clang/lib/Frontend/InitPreprocessor.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'clang/lib/Frontend') diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index dc3ab53eda0..2eb74e0825f 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -29,6 +29,12 @@ #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); -- cgit v1.2.3