Coverage Report

Created: 2020-09-19 12:23

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Basic/JsonSupport.h
Line
Count
Source (jump to first uncovered line)
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/raw_ostream.h"
16
#include <iterator>
17
18
namespace clang {
19
20
inline raw_ostream &Indent(raw_ostream &Out, const unsigned int Space,
21
2.98k
                           bool IsDot) {
22
15.9k
  for (unsigned int I = 0; I < Space * 2; 
++I12.9k
)
23
12.9k
    Out << (IsDot ? 
"&nbsp;"10.7k
:
" "2.21k
);
24
2.98k
  return Out;
25
2.98k
}
26
27
567
inline std::string JsonFormat(StringRef RawSR, bool AddQuotes) {
28
567
  if (RawSR.empty())
29
28
    return "null";
30
539
31
  // Trim special characters.
32
539
  std::string Str = RawSR.trim().str();
33
539
  size_t Pos = 0;
34
539
35
  // Escape backslashes.
36
579
  while (true) {
37
579
    Pos = Str.find('\\', Pos);
38
579
    if (Pos == std::string::npos)
39
539
      break;
40
40
41
    // Prevent bad conversions.
42
40
    size_t TempPos = (Pos != 0) ? Pos - 1 : 
00
;
43
40
44
    // See whether the current backslash is not escaped.
45
40
    if (TempPos != Str.find("\\\\", Pos)) {
46
40
      Str.insert(Pos, "\\");
47
40
      ++Pos; // As we insert the backslash move plus one.
48
40
    }
49
40
50
40
    ++Pos;
51
40
  }
52
539
53
  // Escape double quotes.
54
539
  Pos = 0;
55
615
  while (true) {
56
615
    Pos = Str.find('\"', Pos);
57
615
    if (Pos == std::string::npos)
58
539
      break;
59
76
60
    // Prevent bad conversions.
61
76
    size_t TempPos = (Pos != 0) ? 
Pos - 162
:
014
;
62
76
63
    // See whether the current double quote is not escaped.
64
76
    if (TempPos != Str.find("\\\"", Pos)) {
65
76
      Str.insert(Pos, "\\");
66
76
      ++Pos; // As we insert the escape-character move plus one.
67
76
    }
68
76
69
76
    ++Pos;
70
76
  }
71
539
72
  // Remove new-lines.
73
539
  Str.erase(std::remove(Str.begin(), Str.end(), '\n'), Str.end());
74
539
75
539
  if (!AddQuotes)
76
0
    return Str;
77
539
78
539
  return '\"' + Str + '\"';
79
539
}
80
81
inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc,
82
                                      const SourceManager &SM,
83
168
                                      bool AddBraces = true) {
84
  // Mostly copy-pasted from SourceLocation::print.
85
168
  if (!Loc.isValid()) {
86
0
    Out << "null";
87
0
    return;
88
0
  }
89
168
90
168
  if (Loc.isFileID()) {
91
163
    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
92
163
93
163
    if (PLoc.isInvalid()) {
94
0
      Out << "null";
95
0
      return;
96
0
    }
97
    // The macro expansion and spelling pos is identical for file locs.
98
163
    if (AddBraces)
99
158
      Out << "{ ";
100
163
    std::string filename(PLoc.getFilename());
101
#ifdef _WIN32
102
    // Remove forbidden Windows path characters
103
    auto RemoveIt =
104
        std::remove_if(filename.begin(), filename.end(), [](auto Char) {
105
          static const char ForbiddenChars[] = "<>*?\"|";
106
          return std::find(std::begin(ForbiddenChars), std::end(ForbiddenChars),
107
                           Char) != std::end(ForbiddenChars);
108
        });
109
    filename.erase(RemoveIt, filename.end());
110
    // Handle windows-specific path delimiters.
111
    std::replace(filename.begin(), filename.end(), '\\', '/');
112
#endif
113
163
    Out << "\"line\": " << PLoc.getLine()
114
163
        << ", \"column\": " << PLoc.getColumn()
115
163
        << ", \"file\": \"" << filename << "\"";
116
163
    if (AddBraces)
117
158
      Out << " }";
118
163
    return;
119
163
  }
120
5
121
  // We want 'location: { ..., spelling: { ... }}' but not
122
  // 'location: { ... }, spelling: { ... }', hence the dance
123
  // with braces.
124
5
  Out << "{ ";
125
5
  printSourceLocationAsJson(Out, SM.getExpansionLoc(Loc), SM, false);
126
5
  Out << ", \"spelling\": ";
127
5
  printSourceLocationAsJson(Out, SM.getSpellingLoc(Loc), SM, true);
128
5
  Out << " }";
129
5
}
130
} // namespace clang
131
132
#endif // LLVM_CLANG_BASIC_JSONSUPPORT_H