123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- JsonSupport.h - JSON Output Utilities --------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_BASIC_JSONSUPPORT_H
- #define LLVM_CLANG_BASIC_JSONSUPPORT_H
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/SourceManager.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Support/Path.h"
- #include "llvm/Support/raw_ostream.h"
- #include <iterator>
- namespace clang {
- inline raw_ostream &Indent(raw_ostream &Out, const unsigned int Space,
- bool IsDot) {
- for (unsigned int I = 0; I < Space * 2; ++I)
- Out << (IsDot ? " " : " ");
- return Out;
- }
- inline std::string JsonFormat(StringRef RawSR, bool AddQuotes) {
- if (RawSR.empty())
- return "null";
- // Trim special characters.
- std::string Str = RawSR.trim().str();
- size_t Pos = 0;
- // Escape backslashes.
- while (true) {
- Pos = Str.find('\\', Pos);
- if (Pos == std::string::npos)
- break;
- // Prevent bad conversions.
- size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
- // See whether the current backslash is not escaped.
- if (TempPos != Str.find("\\\\", Pos)) {
- Str.insert(Pos, "\\");
- ++Pos; // As we insert the backslash move plus one.
- }
- ++Pos;
- }
- // Escape double quotes.
- Pos = 0;
- while (true) {
- Pos = Str.find('\"', Pos);
- if (Pos == std::string::npos)
- break;
- // Prevent bad conversions.
- size_t TempPos = (Pos != 0) ? Pos - 1 : 0;
- // See whether the current double quote is not escaped.
- if (TempPos != Str.find("\\\"", Pos)) {
- Str.insert(Pos, "\\");
- ++Pos; // As we insert the escape-character move plus one.
- }
- ++Pos;
- }
- // Remove new-lines.
- llvm::erase_value(Str, '\n');
- if (!AddQuotes)
- return Str;
- return '\"' + Str + '\"';
- }
- inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc,
- const SourceManager &SM,
- bool AddBraces = true) {
- // Mostly copy-pasted from SourceLocation::print.
- if (!Loc.isValid()) {
- Out << "null";
- return;
- }
- if (Loc.isFileID()) {
- PresumedLoc PLoc = SM.getPresumedLoc(Loc);
- if (PLoc.isInvalid()) {
- Out << "null";
- return;
- }
- // The macro expansion and spelling pos is identical for file locs.
- if (AddBraces)
- Out << "{ ";
- std::string filename(PLoc.getFilename());
- if (is_style_windows(llvm::sys::path::Style::native)) {
- // Remove forbidden Windows path characters
- auto RemoveIt =
- std::remove_if(filename.begin(), filename.end(), [](auto Char) {
- static const char ForbiddenChars[] = "<>*?\"|";
- return std::find(std::begin(ForbiddenChars),
- std::end(ForbiddenChars),
- Char) != std::end(ForbiddenChars);
- });
- filename.erase(RemoveIt, filename.end());
- // Handle windows-specific path delimiters.
- std::replace(filename.begin(), filename.end(), '\\', '/');
- }
- Out << "\"line\": " << PLoc.getLine()
- << ", \"column\": " << PLoc.getColumn()
- << ", \"file\": \"" << filename << "\"";
- if (AddBraces)
- Out << " }";
- return;
- }
- // We want 'location: { ..., spelling: { ... }}' but not
- // 'location: { ... }, spelling: { ... }', hence the dance
- // with braces.
- Out << "{ ";
- printSourceLocationAsJson(Out, SM.getExpansionLoc(Loc), SM, false);
- Out << ", \"spelling\": ";
- printSourceLocationAsJson(Out, SM.getSpellingLoc(Loc), SM, true);
- Out << " }";
- }
- } // namespace clang
- #endif // LLVM_CLANG_BASIC_JSONSUPPORT_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|