clang  14.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/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  auto RemoveIt =
105  std::remove_if(filename.begin(), filename.end(), [](auto Char) {
106  static const char ForbiddenChars[] = "<>*?\"|";
107  return std::find(std::begin(ForbiddenChars),
108  std::end(ForbiddenChars),
109  Char) != std::end(ForbiddenChars);
110  });
111  filename.erase(RemoveIt, filename.end());
112  // Handle windows-specific path delimiters.
113  std::replace(filename.begin(), filename.end(), '\\', '/');
114  }
115  Out << "\"line\": " << PLoc.getLine()
116  << ", \"column\": " << PLoc.getColumn()
117  << ", \"file\": \"" << filename << "\"";
118  if (AddBraces)
119  Out << " }";
120  return;
121  }
122 
123  // We want 'location: { ..., spelling: { ... }}' but not
124  // 'location: { ... }, spelling: { ... }', hence the dance
125  // with braces.
126  Out << "{ ";
127  printSourceLocationAsJson(Out, SM.getExpansionLoc(Loc), SM, false);
128  Out << ", \"spelling\": ";
129  printSourceLocationAsJson(Out, SM.getSpellingLoc(Loc), SM, true);
130  Out << " }";
131 }
132 } // namespace clang
133 
134 #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:337
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
SourceManager.h
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:626
clang::PresumedLoc::getFilename
const char * getFilename() const
Return the presumed filename of this location.
Definition: SourceLocation.h:324
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:345
clang::printSourceLocationAsJson
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition: JsonSupport.h:82
clang::PresumedLoc::isInvalid
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Definition: SourceLocation.h:318
clang::Indent
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:21
LLVM.h
clang
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:28
clang::PresumedLoc
Represents an unpacked "presumed" location which can be presented to the user.
Definition: SourceLocation.h:302
SM
#define SM(sm)
Definition: Cuda.cpp:81