Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- JsonSupport.h - JSON Output Utilities --------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_CLANG_BASIC_JSONSUPPORT_H
10
#define LLVM_CLANG_BASIC_JSONSUPPORT_H
11
 
12
#include "clang/Basic/LLVM.h"
13
#include "clang/Basic/SourceManager.h"
14
#include "llvm/ADT/StringRef.h"
15
#include "llvm/Support/Path.h"
16
#include "llvm/Support/raw_ostream.h"
17
#include <iterator>
18
 
19
namespace clang {
20
 
21
inline raw_ostream &Indent(raw_ostream &Out, const unsigned int Space,
22
                           bool IsDot) {
23
  for (unsigned int I = 0; I < Space * 2; ++I)
24
    Out << (IsDot ? "&nbsp;" : " ");
25
  return Out;
26
}
27
 
28
inline std::string JsonFormat(StringRef RawSR, bool AddQuotes) {
29
  if (RawSR.empty())
30
    return "null";
31
 
32
  // Trim special characters.
33
  std::string Str = RawSR.trim().str();
34
  size_t Pos = 0;
35
 
36
  // Escape backslashes.
37
  while (true) {
38
    Pos = Str.find('\\', Pos);
39
    if (Pos == std::string::npos)
40
      break;
41
 
42
    // Prevent bad conversions.
43
    size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
44
 
45
    // See whether the current backslash is not escaped.
46
    if (TempPos != Str.find("\\\\", Pos)) {
47
      Str.insert(Pos, "\\");
48
      ++Pos; // As we insert the backslash move plus one.
49
    }
50
 
51
    ++Pos;
52
  }
53
 
54
  // Escape double quotes.
55
  Pos = 0;
56
  while (true) {
57
    Pos = Str.find('\"', Pos);
58
    if (Pos == std::string::npos)
59
      break;
60
 
61
    // Prevent bad conversions.
62
    size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
63
 
64
    // See whether the current double quote is not escaped.
65
    if (TempPos != Str.find("\\\"", Pos)) {
66
      Str.insert(Pos, "\\");
67
      ++Pos; // As we insert the escape-character move plus one.
68
    }
69
 
70
    ++Pos;
71
  }
72
 
73
  // Remove new-lines.
74
  llvm::erase_value(Str, '\n');
75
 
76
  if (!AddQuotes)
77
    return Str;
78
 
79
  return '\"' + Str + '\"';
80
}
81
 
82
inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc,
83
                                      const SourceManager &SM,
84
                                      bool AddBraces = true) {
85
  // Mostly copy-pasted from SourceLocation::print.
86
  if (!Loc.isValid()) {
87
    Out << "null";
88
    return;
89
  }
90
 
91
  if (Loc.isFileID()) {
92
    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
93
 
94
    if (PLoc.isInvalid()) {
95
      Out << "null";
96
      return;
97
    }
98
    // The macro expansion and spelling pos is identical for file locs.
99
    if (AddBraces)
100
      Out << "{ ";
101
    std::string filename(PLoc.getFilename());
102
    if (is_style_windows(llvm::sys::path::Style::native)) {
103
      // Remove forbidden Windows path characters
104
      llvm::erase_if(filename, [](auto Char) {
105
        static const char ForbiddenChars[] = "<>*?\"|";
106
        return llvm::is_contained(ForbiddenChars, Char);
107
      });
108
      // Handle windows-specific path delimiters.
109
      std::replace(filename.begin(), filename.end(), '\\', '/');
110
    }
111
    Out << "\"line\": " << PLoc.getLine()
112
        << ", \"column\": " << PLoc.getColumn()
113
        << ", \"file\": \"" << filename << "\"";
114
    if (AddBraces)
115
      Out << " }";
116
    return;
117
  }
118
 
119
  // We want 'location: { ..., spelling: { ... }}' but not
120
  // 'location: { ... }, spelling: { ... }', hence the dance
121
  // with braces.
122
  Out << "{ ";
123
  printSourceLocationAsJson(Out, SM.getExpansionLoc(Loc), SM, false);
124
  Out << ", \"spelling\": ";
125
  printSourceLocationAsJson(Out, SM.getSpellingLoc(Loc), SM, true);
126
  Out << " }";
127
}
128
} // namespace clang
129
 
130
#endif // LLVM_CLANG_BASIC_JSONSUPPORT_H