]> granicus.if.org Git - llvm/commitdiff
[DiagnosticInfo] Add support for preserving newlines in remark arguments.
authorFlorian Hahn <flo@fhahn.com>
Fri, 25 Jan 2019 16:59:06 +0000 (16:59 +0000)
committerFlorian Hahn <flo@fhahn.com>
Fri, 25 Jan 2019 16:59:06 +0000 (16:59 +0000)
This patch adds a new type StringBlockVal which can be used to emit a
YAML block scalar, which preserves newlines in a multiline string. It
also updates  MappingTraits<DiagnosticInfoOptimizationBase::Argument> to
use it for argument values with more than a single newline.

This is helpful for remarks that want to display more in-depth
information in a more structured way.

Reviewers: thegameg, anemet

Reviewed By: anemet

Subscribers: hfinkel, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D57159

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

lib/IR/DiagnosticInfo.cpp

index b7409983b395dc908a0efc545ba6d5debc603f63..14bee35dc2929ec6060c63c8e6fdc1cdb44c8151 100644 (file)
@@ -438,11 +438,33 @@ template <> struct MappingTraits<DiagnosticLocation> {
   static const bool flow = true;
 };
 
+/// Helper struct for multiline string block literals. Use this type to preserve
+/// newlines in strings.
+struct StringBlockVal {
+  StringRef Value;
+  StringBlockVal(const std::string &Value) : Value(Value) {}
+};
+
+template <> struct BlockScalarTraits<StringBlockVal> {
+  static void output(const StringBlockVal &S, void *Ctx, raw_ostream &OS) {
+    return ScalarTraits<StringRef>::output(S.Value, Ctx, OS);
+  }
+
+  static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S) {
+    return ScalarTraits<StringRef>::input(Scalar, Ctx, S.Value);
+  }
+};
+
 // Implement this as a mapping for now to get proper quotation for the value.
 template <> struct MappingTraits<DiagnosticInfoOptimizationBase::Argument> {
   static void mapping(IO &io, DiagnosticInfoOptimizationBase::Argument &A) {
     assert(io.outputting() && "input not yet implemented");
-    io.mapRequired(A.Key.data(), A.Val);
+    // Emit a string block scalar for multiline strings, to preserve newlines.
+    if (StringRef(A.Val).count('\n') > 1) {
+      StringBlockVal S(A.Val);
+      io.mapRequired(A.Key.data(), S);
+    } else
+      io.mapRequired(A.Key.data(), A.Val);
     if (A.Loc.isValid())
       io.mapOptional("DebugLoc", A.Loc);
   }