clang  13.0.0git
JsonSupport.h
Go to the documentation of this file.
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"
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  bool IsDot) {
22  for (unsigned int I = 0; I < Space * 2; ++I)
23  Out << (IsDot ? "&nbsp;" : " ");
24  return Out;
25 }
26 
27 inline std::string JsonFormat(StringRef RawSR, bool AddQuotes) {
28  if (RawSR.empty())
29  return "null";
30 
31  // Trim special characters.
32  std::string Str = RawSR.trim().str();
33  size_t Pos = 0;
34 
35  // Escape backslashes.
36  while (true) {
37  Pos = Str.find('\\', Pos);
38  if (Pos == std::string::npos)
39  break;
40 
41  // Prevent bad conversions.
42  size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
43 
44  // See whether the current backslash is not escaped.
45  if (TempPos != Str.find("\\\\", Pos)) {
46  Str.insert(Pos, "\\");
47  ++Pos; // As we insert the backslash move plus one.
48  }
49 
50  ++Pos;
51  }
52 
53  // Escape double quotes.
54  Pos = 0;
55  while (true) {
56  Pos = Str.find('\"', Pos);
57  if (Pos == std::string::npos)
58  break;
59 
60  // Prevent bad conversions.
61  size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
62 
63  // See whether the current double quote is not escaped.
64  if (TempPos != Str.find("\\\"", Pos)) {
65  Str.insert(Pos, "\\");
66  ++Pos; // As we insert the escape-character move plus one.
67  }
68 
69  ++Pos;
70  }
71 
72  // Remove new-lines.
73  Str.erase(std::remove(Str.begin(), Str.end(), '\n'), Str.end());
74 
75  if (!AddQuotes)
76  return Str;
77 
78  return '\"' + Str + '\"';
79 }
80 
81 inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc,
82  const SourceManager &SM,
83  bool AddBraces = true) {
84  // Mostly copy-pasted from SourceLocation::print.
85  if (!Loc.isValid()) {
86  Out << "null";
87  return;
88  }
89 
90  if (Loc.isFileID()) {
91  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
92 
93  if (PLoc.isInvalid()) {
94  Out << "null";
95  return;
96  }
97  // The macro expansion and spelling pos is identical for file locs.
98  if (AddBraces)
99  Out << "{ ";
100  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  Out << "\"line\": " << PLoc.getLine()
114  << ", \"column\": " << PLoc.getColumn()
115  << ", \"file\": \"" << filename << "\"";
116  if (AddBraces)
117  Out << " }";
118  return;
119  }
120 
121  // We want 'location: { ..., spelling: { ... }}' but not
122  // 'location: { ... }, spelling: { ... }', hence the dance
123  // with braces.
124  Out << "{ ";
125  printSourceLocationAsJson(Out, SM.getExpansionLoc(Loc), SM, false);
126  Out << ", \"spelling\": ";
127  printSourceLocationAsJson(Out, SM.getSpellingLoc(Loc), SM, true);
128  Out << " }";
129 }
130 } // namespace clang
131 
132 #endif // LLVM_CLANG_BASIC_JSONSUPPORT_H
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::PresumedLoc::getLine
unsigned getLine() const
Return the presumed line number of this location.
Definition: SourceLocation.h:339
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:89
SourceManager.h
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:624
clang::PresumedLoc::getFilename
const char * getFilename() const
Return the presumed filename of this location.
Definition: SourceLocation.h:326
clang::SourceLocation::isFileID
bool isFileID() const
Definition: SourceLocation.h:102
clang::PresumedLoc::getColumn
unsigned getColumn() const
Return the presumed column number of this location.
Definition: SourceLocation.h:347
clang::printSourceLocationAsJson
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition: JsonSupport.h:81
clang::PresumedLoc::isInvalid
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Definition: SourceLocation.h:320
clang::transformer::remove
ASTEdit remove(RangeSelector S)
Removes the source selected by S.
Definition: RewriteRule.cpp:146
clang::Indent
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:20
LLVM.h
clang
Dataflow Directional Tag Classes.
Definition: CalledOnceCheck.h:17
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
clang::JsonFormat
std::string JsonFormat(StringRef RawSR, bool AddQuotes)
Definition: JsonSupport.h:27
clang::PresumedLoc
Represents an unpacked "presumed" location which can be presented to the user.
Definition: SourceLocation.h:304
SM
#define SM(sm)
Definition: Cuda.cpp:68