clang 20.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
19namespace clang {
20
21inline 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
28inline 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(Str, '\n');
75
76 if (!AddQuotes)
77 return Str;
78
79 return '\"' + Str + '\"';
80}
81
82inline 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
#define SM(sm)
Definition: Cuda.cpp:83
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the SourceManager interface.
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
The JSON file list parser is used to communicate input to InstallAPI.
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition: JsonSupport.h:82
std::string JsonFormat(StringRef RawSR, bool AddQuotes)
Definition: JsonSupport.h:28