Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:49

0001 //===- JsonSupport.h - JSON Output Utilities --------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_BASIC_JSONSUPPORT_H
0010 #define LLVM_CLANG_BASIC_JSONSUPPORT_H
0011 
0012 #include "clang/Basic/LLVM.h"
0013 #include "clang/Basic/SourceManager.h"
0014 #include "llvm/ADT/StringRef.h"
0015 #include "llvm/Support/Path.h"
0016 #include "llvm/Support/raw_ostream.h"
0017 #include <iterator>
0018 
0019 namespace clang {
0020 
0021 inline raw_ostream &Indent(raw_ostream &Out, const unsigned int Space,
0022                            bool IsDot) {
0023   for (unsigned int I = 0; I < Space * 2; ++I)
0024     Out << (IsDot ? "&nbsp;" : " ");
0025   return Out;
0026 }
0027 
0028 inline std::string JsonFormat(StringRef RawSR, bool AddQuotes) {
0029   if (RawSR.empty())
0030     return "null";
0031 
0032   // Trim special characters.
0033   std::string Str = RawSR.trim().str();
0034   size_t Pos = 0;
0035 
0036   // Escape backslashes.
0037   while (true) {
0038     Pos = Str.find('\\', Pos);
0039     if (Pos == std::string::npos)
0040       break;
0041 
0042     // Prevent bad conversions.
0043     size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
0044 
0045     // See whether the current backslash is not escaped.
0046     if (TempPos != Str.find("\\\\", Pos)) {
0047       Str.insert(Pos, "\\");
0048       ++Pos; // As we insert the backslash move plus one.
0049     }
0050 
0051     ++Pos;
0052   }
0053 
0054   // Escape double quotes.
0055   Pos = 0;
0056   while (true) {
0057     Pos = Str.find('\"', Pos);
0058     if (Pos == std::string::npos)
0059       break;
0060 
0061     // Prevent bad conversions.
0062     size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
0063 
0064     // See whether the current double quote is not escaped.
0065     if (TempPos != Str.find("\\\"", Pos)) {
0066       Str.insert(Pos, "\\");
0067       ++Pos; // As we insert the escape-character move plus one.
0068     }
0069 
0070     ++Pos;
0071   }
0072 
0073   // Remove new-lines.
0074   llvm::erase(Str, '\n');
0075 
0076   if (!AddQuotes)
0077     return Str;
0078 
0079   return '\"' + Str + '\"';
0080 }
0081 
0082 inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc,
0083                                       const SourceManager &SM,
0084                                       bool AddBraces = true) {
0085   // Mostly copy-pasted from SourceLocation::print.
0086   if (!Loc.isValid()) {
0087     Out << "null";
0088     return;
0089   }
0090 
0091   if (Loc.isFileID()) {
0092     PresumedLoc PLoc = SM.getPresumedLoc(Loc);
0093 
0094     if (PLoc.isInvalid()) {
0095       Out << "null";
0096       return;
0097     }
0098     // The macro expansion and spelling pos is identical for file locs.
0099     if (AddBraces)
0100       Out << "{ ";
0101     std::string filename(PLoc.getFilename());
0102     if (is_style_windows(llvm::sys::path::Style::native)) {
0103       // Remove forbidden Windows path characters
0104       llvm::erase_if(filename, [](auto Char) {
0105         static const char ForbiddenChars[] = "<>*?\"|";
0106         return llvm::is_contained(ForbiddenChars, Char);
0107       });
0108       // Handle windows-specific path delimiters.
0109       std::replace(filename.begin(), filename.end(), '\\', '/');
0110     }
0111     Out << "\"line\": " << PLoc.getLine()
0112         << ", \"column\": " << PLoc.getColumn()
0113         << ", \"file\": \"" << filename << "\"";
0114     if (AddBraces)
0115       Out << " }";
0116     return;
0117   }
0118 
0119   // We want 'location: { ..., spelling: { ... }}' but not
0120   // 'location: { ... }, spelling: { ... }', hence the dance
0121   // with braces.
0122   Out << "{ ";
0123   printSourceLocationAsJson(Out, SM.getExpansionLoc(Loc), SM, false);
0124   Out << ", \"spelling\": ";
0125   printSourceLocationAsJson(Out, SM.getSpellingLoc(Loc), SM, true);
0126   Out << " }";
0127 }
0128 } // namespace clang
0129 
0130 #endif // LLVM_CLANG_BASIC_JSONSUPPORT_H