LLVM: lib/Support/JSON.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

17#include

18#include

19#include

20

21namespace llvm {

22namespace json {

23

25 return try_emplace(K, nullptr).first->getSecond();

26}

28 return try_emplace(std::move(K), nullptr).first->getSecond();

29}

32 if (I == end())

33 return nullptr;

34 return &I->second;

35}

38 if (I == end())

39 return nullptr;

40 return &I->second;

41}

43 if (auto *V = get(K))

44 return V->getAsNull();

45 return std::nullopt;

46}

48 if (auto *V = get(K))

49 return V->getAsBoolean();

50 return std::nullopt;

51}

53 if (auto *V = get(K))

54 return V->getAsNumber();

55 return std::nullopt;

56}

58 if (auto *V = get(K))

59 return V->getAsInteger();

60 return std::nullopt;

61}

63 if (auto *V = get(K))

64 return V->getAsString();

65 return std::nullopt;

66}

68 if (auto *V = get(K))

69 return V->getAsObject();

70 return nullptr;

71}

73 if (auto *V = get(K))

74 return V->getAsObject();

75 return nullptr;

76}

78 if (auto *V = get(K))

79 return V->getAsArray();

80 return nullptr;

81}

83 if (auto *V = get(K))

84 return V->getAsArray();

85 return nullptr;

86}

88 if (LHS.size() != RHS.size())

89 return false;

90 for (const auto &L : LHS) {

91 auto R = RHS.find(L.first);

92 if (R == RHS.end() || L.second != R->second)

93 return false;

94 }

95 return true;

96}

97

99 V.reserve(Elements.size());

100 for (const Value &V : Elements) {

102 back().moveFrom(std::move(V));

103 }

104}

105

108

109void Value::copyFrom(const Value &M) {

110 Type = M.Type;

111 switch (Type) {

112 case T_Null:

113 case T_Boolean:

114 case T_Double:

115 case T_Integer:

116 case T_UINT64:

117 memcpy(&Union, &M.Union, sizeof(Union));

118 break;

119 case T_StringRef:

120 create(M.as<StringRef>());

121 break;

122 case T_String:

123 createstd::string(M.asstd::string());

124 break;

125 case T_Object:

127 break;

128 case T_Array:

129 createjson::Array(M.as<json::Array>());

130 break;

131 }

132}

133

134void Value::moveFrom(const Value &&M) {

135 Type = M.Type;

136 switch (Type) {

137 case T_Null:

138 case T_Boolean:

139 case T_Double:

140 case T_Integer:

141 case T_UINT64:

142 memcpy(&Union, &M.Union, sizeof(Union));

143 break;

144 case T_StringRef:

145 create(M.as());

146 break;

147 case T_String:

148 createstd::string(std::move(M.asstd::string()));

149 M.Type = T_Null;

150 break;

151 case T_Object:

152 createjson::Object(std::move(M.asjson::Object()));

153 M.Type = T_Null;

154 break;

155 case T_Array:

156 createjson::Array(std::move(M.asjson::Array()));

157 M.Type = T_Null;

158 break;

159 }

160}

161

162void Value::destroy() {

163 switch (Type) {

164 case T_Null:

165 case T_Boolean:

166 case T_Double:

167 case T_Integer:

168 case T_UINT64:

169 break;

170 case T_StringRef:

171 as().~StringRef();

172 break;

173 case T_String:

174 asstd::string().~basic_string();

175 break;

176 case T_Object:

177 asjson::Object().~Object();

178 break;

179 case T_Array:

180 asjson::Array().~Array();

181 break;

182 }

183}

184

186 if (L.kind() != R.kind())

187 return false;

188 switch (L.kind()) {

190 return *L.getAsNull() == *R.getAsNull();

192 return *L.getAsBoolean() == *R.getAsBoolean();

194

195

196

197

198 if (L.Type == Value::T_Integer || R.Type == Value::T_Integer)

199 return L.getAsInteger() == R.getAsInteger();

200 return *L.getAsNumber() == *R.getAsNumber();

202 return *L.getAsString() == *R.getAsString();

204 return *L.getAsArray() == *R.getAsArray();

206 return *L.getAsObject() == *R.getAsObject();

207 }

209}

210

212

213 unsigned Count = 0;

215 for (P = this; P->Parent != nullptr; P = P->Parent)

216 ++Count;

218

219 R->ErrorMessage = Msg;

220 R->ErrorPath.resize(Count);

221 auto It = R->ErrorPath.begin();

222 for (P = this; P->Parent != nullptr; P = P->Parent)

223 *It++ = P->Seg;

224}

225

227 std::string S;

229 OS << (ErrorMessage.empty() ? "invalid JSON contents" : ErrorMessage);

230 if (ErrorPath.empty()) {

231 if (!Name.empty())

232 OS << " when parsing " << Name;

233 } else {

234 OS << " at " << (Name.empty() ? "(root)" : Name);

235 for (const Path::Segment &S : llvm::reverse(ErrorPath)) {

236 if (S.isField())

237 OS << '.' << S.field();

238 else

239 OS << '[' << S.index() << ']';

240 }

241 }

243}

244

246 std::vector<const Object::value_type *> Elements;

247 for (const auto &E : O)

248 Elements.push_back(&E);

251 return L->first < R->first;

252 });

253 return Elements;

254}

255

256

257

258

260 switch (V.kind()) {

262 JOS.rawValue(V.getAsArray()->empty() ? "[]" : "[ ... ]");

263 break;

265 JOS.rawValue(V.getAsObject()->empty() ? "{}" : "{ ... }");

266 break;

269 if (S.size() < 40) {

271 } else {

273 Truncated.append("...");

274 JOS.value(Truncated);

275 }

276 break;

277 }

278 default:

280 }

281}

282

283

284

286 switch (V.kind()) {

289 for (const auto &I : *V.getAsArray())

291 });

292 break;

295 for (const auto *KV : sortedElements(*V.getAsObject())) {

296 JOS.attributeBegin(KV->first);

297 abbreviate(KV->second, JOS);

298 JOS.attributeEnd();

299 }

300 });

301 break;

302 default:

304 }

305}

306

308 OStream JOS(OS, 2);

309

310

311

312

314

315

316

317 auto HighlightCurrent = [&] {

318 std::string Comment = "error: ";

319 Comment.append(ErrorMessage.data(), ErrorMessage.size());

322 };

323 if (Path.empty())

324 return HighlightCurrent();

325 const Segment &S = Path.back();

326 if (S.isField()) {

327

329 const Object *O = V.getAsObject();

330 if (!O || !O->get(FieldName))

331 return HighlightCurrent();

336 Recurse(KV->second, Path.drop_back(), Recurse);

337 else

340 }

341 });

342 } else {

343

344 const Array *A = V.getAsArray();

345 if (A || S.index() >= A->size())

346 return HighlightCurrent();

348 unsigned Current = 0;

349 for (const auto &V : *A) {

350 if (Current++ == S.index())

351 Recurse(V, Path.drop_back(), Recurse);

352 else

354 }

355 });

356 }

357 };

358 PrintValue(R, ErrorPath, PrintValue);

359}

360

361namespace {

362

363class Parser {

364public:

366 : Start(JSON.begin()), P(JSON.begin()), End(JSON.end()) {}

367

368 bool checkUTF8() {

369 size_t ErrOffset;

371 return true;

372 P = Start + ErrOffset;

373 return parseError("Invalid UTF-8 sequence");

374 }

375

376 bool parseValue(Value &Out);

377

378 bool assertEnd() {

379 eatWhitespace();

380 if (P == End)

381 return true;

382 return parseError("Text after end of document");

383 }

384

385 Error takeError() {

387 return std::move(*Err);

388 }

389

390private:

391 void eatWhitespace() {

392 while (P != End && (*P == ' ' || *P == '\r' || *P == '\n' || *P == '\t'))

393 ++P;

394 }

395

396

397 bool parseNumber(char First, Value &Out);

398 bool parseString(std::string &Out);

399 bool parseUnicode(std::string &Out);

400 bool parseError(const char *Msg);

401

402 char next() { return P == End ? 0 : *P++; }

403 char peek() { return P == End ? 0 : *P; }

404 static bool isNumber(char C) {

405 return C == '0' || C == '1' || C == '2' || C == '3' || C == '4' ||

406 C == '5' || C == '6' || C == '7' || C == '8' || C == '9' ||

407 C == 'e' || C == 'E' || C == '+' || C == '-' || C == '.';

408 }

409

410 std::optional Err;

411 const char *Start, *P, *End;

412};

413}

414

415bool Parser::parseValue(Value &Out) {

416 eatWhitespace();

417 if (P == End)

418 return parseError("Unexpected EOF");

419 switch (char C = next()) {

420

421 case 'n':

422 Out = nullptr;

423 return (next() == 'u' && next() == 'l' && next() == 'l') ||

424 parseError("Invalid JSON value (null?)");

425 case 't':

426 Out = true;

427 return (next() == 'r' && next() == 'u' && next() == 'e') ||

428 parseError("Invalid JSON value (true?)");

429 case 'f':

430 Out = false;

431 return (next() == 'a' && next() == 'l' && next() == 's' && next() == 'e') ||

432 parseError("Invalid JSON value (false?)");

433 case '"': {

434 std::string S;

435 if (parseString(S)) {

436 Out = std::move(S);

437 return true;

438 }

439 return false;

440 }

441 case '[': {

443 Array &A = *Out.getAsArray();

444 eatWhitespace();

445 if (peek() == ']') {

446 ++P;

447 return true;

448 }

449 for (;;) {

450 A.emplace_back(nullptr);

451 if (!parseValue(A.back()))

452 return false;

453 eatWhitespace();

454 switch (next()) {

455 case ',':

456 eatWhitespace();

457 continue;

458 case ']':

459 return true;

460 default:

461 return parseError("Expected , or ] after array element");

462 }

463 }

464 }

465 case '{': {

467 Object &O = *Out.getAsObject();

468 eatWhitespace();

469 if (peek() == '}') {

470 ++P;

471 return true;

472 }

473 for (;;) {

474 if (next() != '"')

475 return parseError("Expected object key");

476 std::string K;

477 if (!parseString(K))

478 return false;

479 eatWhitespace();

480 if (next() != ':')

481 return parseError("Expected : after object key");

482 eatWhitespace();

483 if (!parseValue(O[std::move(K)]))

484 return false;

485 eatWhitespace();

486 switch (next()) {

487 case ',':

488 eatWhitespace();

489 continue;

490 case '}':

491 return true;

492 default:

493 return parseError("Expected , or } after object property");

494 }

495 }

496 }

497 default:

498 if (isNumber(C))

499 return parseNumber(C, Out);

500 return parseError("Invalid JSON value");

501 }

502}

503

504bool Parser::parseNumber(char First, Value &Out) {

505

506 SmallString<24> S;

507 S.push_back(First);

508 while (isNumber(peek()))

509 S.push_back(next());

510 char *End;

511

512

513

514 errno = 0;

515 int64_t I = std::strtoll(S.c_str(), &End, 10);

516 if (End == S.end() && errno != ERANGE) {

517 Out = int64_t(I);

518 return true;

519 }

520

521

522

523 if (First != '-') {

524 errno = 0;

525 uint64_t UI = std::strtoull(S.c_str(), &End, 10);

526 if (End == S.end() && errno != ERANGE) {

527 Out = UI;

528 return true;

529 }

530 }

531

532 Out = std::strtod(S.c_str(), &End);

533 return End == S.end() || parseError("Invalid JSON value (number?)");

534}

535

536bool Parser::parseString(std::string &Out) {

537

538 for (char C = next(); C != '"'; C = next()) {

540 return parseError("Unterminated string");

542 return parseError("Control character in string");

544 Out.push_back(C);

545 continue;

546 }

547

548 switch (C = next()) {

549 case '"':

550 case '\\':

551 case '/':

552 Out.push_back(C);

553 break;

554 case 'b':

555 Out.push_back('\b');

556 break;

557 case 'f':

558 Out.push_back('\f');

559 break;

560 case 'n':

561 Out.push_back('\n');

562 break;

563 case 'r':

564 Out.push_back('\r');

565 break;

566 case 't':

567 Out.push_back('\t');

568 break;

569 case 'u':

570 if (!parseUnicode(Out))

571 return false;

572 break;

573 default:

574 return parseError("Invalid escape sequence");

575 }

576 }

577 return true;

578}

579

581 if (Rune < 0x80) {

582 Out.push_back(Rune & 0x7F);

583 } else if (Rune < 0x800) {

584 uint8_t FirstByte = 0xC0 | ((Rune & 0x7C0) >> 6);

585 uint8_t SecondByte = 0x80 | (Rune & 0x3F);

586 Out.push_back(FirstByte);

587 Out.push_back(SecondByte);

588 } else if (Rune < 0x10000) {

589 uint8_t FirstByte = 0xE0 | ((Rune & 0xF000) >> 12);

590 uint8_t SecondByte = 0x80 | ((Rune & 0xFC0) >> 6);

591 uint8_t ThirdByte = 0x80 | (Rune & 0x3F);

592 Out.push_back(FirstByte);

593 Out.push_back(SecondByte);

594 Out.push_back(ThirdByte);

595 } else if (Rune < 0x110000) {

596 uint8_t FirstByte = 0xF0 | ((Rune & 0x1F0000) >> 18);

597 uint8_t SecondByte = 0x80 | ((Rune & 0x3F000) >> 12);

598 uint8_t ThirdByte = 0x80 | ((Rune & 0xFC0) >> 6);

599 uint8_t FourthByte = 0x80 | (Rune & 0x3F);

600 Out.push_back(FirstByte);

601 Out.push_back(SecondByte);

602 Out.push_back(ThirdByte);

603 Out.push_back(FourthByte);

604 } else {

606 }

607}

608

609

610

611

612

613bool Parser::parseUnicode(std::string &Out) {

614

615 auto Invalid = [&] { Out.append( {'\xef', '\xbf', '\xbd'}); };

616

617 auto Parse4Hex = [this](uint16_t &Out) -> bool {

618 Out = 0;

619 char Bytes[] = {next(), next(), next(), next()};

620 for (unsigned char C : Bytes) {

621 if (!std::isxdigit(C))

622 return parseError("Invalid \\u escape sequence");

623 Out <<= 4;

624 Out |= (C > '9') ? (C & ~0x20) - 'A' + 10 : (C - '0');

625 }

626 return true;

627 };

628 uint16_t First;

629 if (!Parse4Hex(First))

630 return false;

631

632

633 while (true) {

634

635 if (LLVM_LIKELY(First < 0xD800 || First >= 0xE000)) {

637 return true;

638 }

639

640

643 return true;

644 }

645

646

647

649 Invalid();

650 return true;

651 }

652 P += 2;

654 if (!Parse4Hex(Second))

655 return false;

656

657 if (LLVM_UNLIKELY(Second < 0xDC00 || Second >= 0xE000)) {

658 Invalid();

659 First = Second;

660 continue;

661 }

662

663 encodeUtf8(0x10000 | ((First - 0xD800) << 10) | (Second - 0xDC00), Out);

664 return true;

665 }

666}

667

668bool Parser::parseError(const char *Msg) {

669 int Line = 1;

670 const char *StartOfLine = Start;

671 for (const char *X = Start; X < P; ++X) {

672 if (*X == 0x0A) {

674 StartOfLine = X + 1;

675 }

676 }

677 Err.emplace(

678 std::make_unique(Msg, Line, P - StartOfLine, P - Start));

679 return false;

680}

681

683 Parser P(JSON);

685 if (P.checkUTF8())

686 if (P.parseValue(E))

687 if (P.assertEnd())

688 return std::move(E);

689 return P.takeError();

690}

692

694

696 return true;

697

700 return true;

701

702 if (ErrOffset)

703 *ErrOffset = Rest - Data;

704 return false;

705}

706

708

709 std::vector Codepoints(S.size());

710 const UTF8 *In8 = reinterpret_cast<const UTF8 *>(S.data());

711 UTF32 *Out32 = Codepoints.data();

714 Codepoints.resize(Out32 - Codepoints.data());

715 std::string Res(4 * Codepoints.size(), 0);

716 const UTF32 *In32 = Codepoints.data();

717 UTF8 *Out8 = reinterpret_cast<UTF8 *>(&Res[0]);

718 ConvertUTF32toUTF8(&In32, In32 + Codepoints.size(), &Out8, Out8 + Res.size(),

720 Res.resize(reinterpret_cast<char *>(Out8) - Res.data());

721 return Res;

722}

723

725 OS << '\"';

726 for (unsigned char C : S) {

727 if (C == 0x22 || C == 0x5C)

728 OS << '\\';

729 if (C >= 0x20) {

731 continue;

732 }

733 OS << '\\';

734 switch (C) {

735

736 case '\t':

737 OS << 't';

738 break;

739 case '\n':

740 OS << 'n';

741 break;

742 case '\r':

743 OS << 'r';

744 break;

745 default:

746 OS << 'u';

748 break;

749 }

750 }

751 OS << '\"';

752}

753

755 switch (V.kind()) {

757 valueBegin();

758 OS << "null";

759 return;

761 valueBegin();

762 OS << (*V.getAsBoolean() ? "true" : "false");

763 return;

765 valueBegin();

766 if (V.Type == Value::T_Integer)

767 OS << *V.getAsInteger();

768 else if (V.Type == Value::T_UINT64)

769 OS << *V.getAsUINT64();

770 else

771 OS << format("%.*g", std::numeric_limits::max_digits10,

772 *V.getAsNumber());

773 return;

775 valueBegin();

776 quote(OS, *V.getAsString());

777 return;

779 return array([&] {

780 for (const Value &E : *V.getAsArray())

782 });

784 return object([&] {

786 attribute(E->first, E->second);

787 });

788 }

789}

790

791void llvm::json::OStream::valueBegin() {

792 assert(Stack.back().Ctx != Object && "Only attributes allowed here");

793 if (Stack.back().HasValue) {

794 assert(Stack.back().Ctx != Singleton && "Only one value allowed here");

795 OS << ',';

796 }

797 if (Stack.back().Ctx == Array)

798 newline();

799 flushComment();

800 Stack.back().HasValue = true;

801}

802

804 assert(PendingComment.empty() && "Only one comment per value!");

805 PendingComment = Comment;

806}

807

808void OStream::flushComment() {

809 if (PendingComment.empty())

810 return;

811 OS << (IndentSize ? "/* " : "/*");

812

813 while (!PendingComment.empty()) {

814 auto Pos = PendingComment.find("*/");

816 OS << PendingComment;

817 PendingComment = "";

818 } else {

819 OS << PendingComment.take_front(Pos) << "* /";

820 PendingComment = PendingComment.drop_front(Pos + 2);

821 }

822 }

823 OS << (IndentSize ? " */" : "*/");

824

825 if (Stack.size() > 1 && Stack.back().Ctx == Singleton) {

826 if (IndentSize)

827 OS << ' ';

828 } else {

829 newline();

830 }

831}

832

833void llvm::json::OStream::newline() {

834 if (IndentSize) {

835 OS.write('\n');

836 OS.indent(Indent);

837 }

838}

839

841 valueBegin();

842 Stack.emplace_back();

843 Stack.back().Ctx = Array;

844 Indent += IndentSize;

845 OS << '[';

846}

847

850 Indent -= IndentSize;

851 if (Stack.back().HasValue)

852 newline();

853 OS << ']';

854 assert(PendingComment.empty());

855 Stack.pop_back();

856 assert(!Stack.empty());

857}

858

860 valueBegin();

861 Stack.emplace_back();

862 Stack.back().Ctx = Object;

863 Indent += IndentSize;

864 OS << '{';

865}

866

869 Indent -= IndentSize;

870 if (Stack.back().HasValue)

871 newline();

872 OS << '}';

873 assert(PendingComment.empty());

874 Stack.pop_back();

875 assert(!Stack.empty());

876}

877

880 if (Stack.back().HasValue)

881 OS << ',';

882 newline();

883 flushComment();

884 Stack.back().HasValue = true;

885 Stack.emplace_back();

886 Stack.back().Ctx = Singleton;

889 } else {

890 assert(false && "Invalid UTF-8 in attribute key");

892 }

893 OS.write(':');

894 if (IndentSize)

895 OS.write(' ');

896}

897

899 assert(Stack.back().Ctx == Singleton);

900 assert(Stack.back().HasValue && "Attribute must have a value");

901 assert(PendingComment.empty());

902 Stack.pop_back();

904}

905

907 valueBegin();

908 Stack.emplace_back();

909 Stack.back().Ctx = RawValue;

910 return OS;

911}

912

914 assert(Stack.back().Ctx == RawValue);

915 Stack.pop_back();

916}

917

918}

919}

920

923 unsigned IndentAmount = 0;

924 if (Options.empty() && Options.getAsInteger(10, IndentAmount))

925 llvm_unreachable("json::Value format options should be an integer");

927}

928

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

#define LLVM_UNLIKELY(EXPR)

#define LLVM_LIKELY(EXPR)

Given that RA is a live value

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

This file supports working with JSON data.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static bool peek(struct InternalInstruction *insn, uint8_t &byte)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

Lightweight error class with error context and mandatory checking.

Tagged union holding either a T or a Error.

A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

StringRef take_front(size_t N=1) const

Return a StringRef equal to 'this' but with only the first N elements remaining.

static constexpr size_t npos

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

An Array is a JSON array, which contains heterogeneous JSON values.

void emplace_back(Args &&...A)

json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...

void object(Block Contents)

Emit an object whose elements are emitted in the provided Block.

void rawValue(llvm::function_ref< void(raw_ostream &)> Contents)

Emit an externally-serialized value.

void attributeBegin(llvm::StringRef Key)

raw_ostream & rawValueBegin()

void comment(llvm::StringRef)

Emit a JavaScript comment associated with the next printed value.

void array(Block Contents)

Emit an array whose elements are emitted in the provided Block.

void value(const Value &V)

Emit a self-contained value (number, string, vector etc).

ObjectKey is a used to capture keys in Object.

An Object is a JSON object, which maps strings to heterogenous JSON values.

std::optional< bool > getBoolean(StringRef K) const

Value & operator[](const ObjectKey &K)

std::optional< double > getNumber(StringRef K) const

const json::Object * getObject(StringRef K) const

std::optional< llvm::StringRef > getString(StringRef K) const

Storage::value_type value_type

std::optional< int64_t > getInteger(StringRef K) const

std::optional< std::nullptr_t > getNull(StringRef K) const

std::pair< iterator, bool > try_emplace(const ObjectKey &K, Ts &&... Args)

iterator find(StringRef K)

const json::Array * getArray(StringRef K) const

The root is the trivial Path to the root value.

void printErrorContext(const Value &, llvm::raw_ostream &) const

Print the root value with the error shown inline as a comment.

Error getError() const

Returns the last error reported, or else a generic error.

A "cursor" marking a position within a Value.

void report(llvm::StringLiteral Message)

Records that the value at the current path is invalid.

A Value is an JSON value of unknown type.

@ Number

Number values can store both int64s and doubles at full precision, depending on what they were constr...

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ C

The default llvm calling convention, compatible with C.

static void abbreviateChildren(const Value &V, OStream &JOS)

static void abbreviate(const Value &V, OStream &JOS)

bool isUTF8(llvm::StringRef S, size_t *ErrOffset=nullptr)

Returns true if S is valid UTF-8, which is required for use as JSON.

std::vector< const Object::value_type * > sortedElements(const Object &O)

static void quote(llvm::raw_ostream &OS, llvm::StringRef S)

std::string fixUTF8(llvm::StringRef S)

Replaces invalid UTF-8 sequences in S with the replacement character (U+FFFD).

static void encodeUtf8(uint32_t Rune, std::string &Out)

This is an optimization pass for GlobalISel generic memory operations.

ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)

Convert a partial UTF8 sequence to UTF32.

std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)

auto reverse(ContainerTy &&C)

void sort(IteratorTy Start, IteratorTy End)

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)

ConversionResult ConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)

Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd)