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

1

2

3

4

5

6

7

12#include

13#include

14

15#define DEBUG_TYPE "mustache"

16

17using namespace llvm;

19

20namespace {

21

23

24static bool isFalsey(const json::Value &V) {

25 return V.getAsNull() || (V.getAsBoolean() && !V.getAsBoolean().value()) ||

26 (V.getAsArray() && V.getAsArray()->empty());

27}

28

29static bool isContextFalsey(const json::Value *V) {

30

31 if (!V)

32 return true;

33 return isFalsey(*V);

34}

35

37 size_t CurrentPos = 0;

38 while (CurrentPos < Str.size()) {

39

40 size_t DelimiterPos = Str.find('.', CurrentPos);

41

42

44 DelimiterPos = Str.size();

45

46

48

49

54 }

55

56

57 CurrentPos = DelimiterPos + 1;

58 }

59}

60

62

63

64

65

66

68 if (Str == ".") {

69

70

72 } else {

73 splitAndTrim(Str, Tokens);

74 }

75

77

79

81}

82}

83

85

87public:

90

93

94private:

95 void anchor() override;

96};

97

98void MustacheOutputStream::anchor() {}

99

101public:

103

104private:

106

107 void write_impl(const char *Ptr, size_t Size) override {

109 }

110 uint64_t current_pos() const override { return OS.tell(); }

111};

112

114public:

126

130

136 return;

137 StringRef AccessorStr(this->TokenBody);

139 AccessorStr = AccessorStr.substr(1);

141 }

142

144

146

148

150

152 switch (Identifier) {

153 case '#':

155 case '/':

157 case '^':

159 case '!':

161 case '>':

163 case '&':

165 case '=':

167 default:

169 }

170 }

171

173

175

179};

180

182

184public:

194

196 : Ctx(Ctx), Ty(Type::Root), Parent(nullptr), ParentContext(nullptr) {}

197

199 : Ctx(Ctx), Ty(Type::Text), Body(Body), Parent(Parent),

200 ParentContext(nullptr) {}

201

202

205 : Ctx(Ctx), Ty(Ty), Parent(Parent), AccessorValue(Accessor),

206 ParentContext(nullptr) {}

207

209

211

212 void setIndentation(size_t NewIndentation) { Indentation = NewIndentation; };

213

215

216private:

219

222

225

227

229

234 void renderUnescapeVariable(const json::Value &CurrentCtx,

237 void renderInvertSection(const json::Value &CurrentCtx,

239

242 size_t Indentation = 0;

249};

250

251

255

258 return new (Ctx.Allocator.Allocate<ASTNode>()) ASTNode(Ctx, T, A, Parent);

259}

260

263 return new (Ctx.Allocator.Allocate<ASTNode>()) ASTNode(Ctx, Body, Parent);

264}

265

266

267

268

269

270

271

272

273

274

275

276

277

279 if (Idx == 0)

280 return true;

281

282 size_t PrevIdx = Idx - 1;

284 return true;

285

286 const Token &PrevToken = Tokens[PrevIdx];

288 return !TokenBody.ends_with("\n") && !(TokenBody.empty() && Idx == 1);

289}

290

291

292

293

295 if (Idx >= Tokens.size() - 1)

296 return true;

297

298 size_t NextIdx = Idx + 1;

300 return true;

301

302 const Token &NextToken = Tokens[NextIdx];

305}

306

313

314

315

316

317

318

319

321 Token &NextToken = Tokens[Idx + 1];

323

326 else if (NextTokenBody.starts_with("\n"))

328}

329

330

331

332

333

334

335

338 Token &PrevToken = Tokens[Idx - 1];

340 StringRef Unindented = PrevTokenBody.rtrim(" \r\t\v");

341 size_t Indentation = PrevTokenBody.size() - Unindented.size();

342 PrevToken.TokenBody = Unindented;

344}

345

358

360 switch (K) {

362 return "None";

364 return "Normal";

366 return "Triple";

367 }

369}

370

372 switch (K) {

374 return "JSON_KIND_NULL";

376 return "JSON_KIND_BOOLEAN";

378 return "JSON_KIND_NUMBER";

380 return "JSON_KIND_STRING";

382 return "JSON_KIND_ARRAY";

384 return "JSON_KIND_OBJECT";

385 }

387}

388

389

395 size_t Cursor = 0;

396 size_t TextStart = 0;

397

400

401 while (Cursor < Template.size()) {

405

406

407 if (TemplateSuffix.starts_with(TripleOpen)) {

409 TagOpen = TripleOpen;

410 TagClose = TripleClose;

411 } else if (TemplateSuffix.starts_with(Open)) {

413 TagOpen = Open;

414 TagClose = Close;

415 } else {

416

417 ++Cursor;

418 continue;

419 }

420

421

422 if (Cursor > TextStart)

424

425

426 size_t EndPos = Template.find(TagClose, Cursor + TagOpen.size());

428

430 TextStart = Cursor = Template.size();

431 break;

432 }

433

434

435 size_t ContentStart = Cursor + TagOpen.size();

436 StringRef Content = Template.substr(ContentStart, EndPos - ContentStart);

438 Template.substr(Cursor, (EndPos + TagClose.size()) - Cursor);

439

440

441 LLVM_DEBUG(dbgs() << "[Tag] " << FullMatch << ", Content: " << Content

444 Tokens.emplace_back(FullMatch, Ctx.Saver.save("&" + Content), '&', Ctx);

445 } else {

446 StringRef Interpolated = Content;

448 char Front = Interpolated.empty() ? ' ' : Interpolated.trim().front();

449 Tokens.emplace_back(FullMatch, Interpolated, Front, Ctx);

450 } else {

451 Tokens.emplace_back(FullMatch, Interpolated, '=', Ctx);

454 DelimSpec = DelimSpec.take_until([](char C) { return C == '='; });

455 DelimSpec = DelimSpec.trim();

456

457 auto [NewOpen, NewClose] = DelimSpec.split(' ');

458 LLVM_DEBUG(dbgs() << "[Set Delimiter] NewOpen: " << NewOpen

459 << ", NewClose: " << NewClose << "\n");

460 Open = NewOpen;

461 Close = NewClose;

462 }

463 }

464

465

466 Cursor += FullMatch.size();

467 TextStart = Cursor;

468 }

469

470

471 if (TextStart < Template.size())

473

474

475 size_t LastIdx = Tokens.size() - 1;

476 for (size_t Idx = 0, End = Tokens.size(); Idx < End; ++Idx) {

477 Token &CurrentToken = Tokens[Idx];

480 continue;

481

483 bool HasTextAhead = hasTextAhead(Idx, Tokens);

484

485 if ((!HasTextAhead && !HasTextBehind) || (!HasTextAhead && Idx == 0))

487

488 if ((!HasTextBehind && !HasTextAhead) || (!HasTextBehind && Idx == LastIdx))

490 }

491 return Tokens;

492}

493

494

496public:

499 : Escape(Escape), EscapeChars(Escape.keys().begin(), Escape.keys().end()),

500 WrappedStream(WrappedStream) {

502 }

503

504protected:

507 size_t Start = 0;

508 while (Start < Size) {

509

510 size_t Next = Data.find_first_of(EscapeChars.str(), Start);

511

512

514 WrappedStream << Data.substr(Start);

515 return;

516 }

517

518

519 if (Next > Start)

520 WrappedStream << Data.substr(Start, Next - Start);

521

522

523 WrappedStream << Escape[Data[Next]];

524 Start = Next + 1;

525 }

526 }

527

529

530private:

534};

535

536

538public:

540 size_t Indentation)

541 : Indentation(Indentation), WrappedStream(WrappedStream),

542 NeedsIndent(true), IsSuspended(false) {

544 }

545

548

549protected:

553 Indent.resize(Indentation, ' ');

554

555 for (char C : Data) {

556 LLVM_DEBUG(dbgs() << "[Indentation Stream] NeedsIndent:" << NeedsIndent

557 << ", C:'" << C << "', Indentation:" << Indentation

558 << "\n");

559 if (NeedsIndent && C != '\n') {

560 WrappedStream << Indent;

561 NeedsIndent = false;

562 }

563 WrappedStream << C;

564 if (C == '\n' && !IsSuspended)

565 NeedsIndent = true;

566 }

567 }

568

570

571private:

572 size_t Indentation;

574 bool NeedsIndent;

575 bool IsSuspended;

576};

577

579public:

581 : Ctx(Ctx), TemplateStr(TemplateStr) {}

582

584

585private:

586 void parseMustache(ASTNode *Parent);

588

591 size_t CurrentPtr;

593};

594

596 const Accessor &A) {

598 size_t Start = CurrentPtr;

599 parseMustache(CurrentNode);

600 const size_t End = CurrentPtr - 1;

601

602 size_t RawBodySize = 0;

603 for (size_t I = Start; I < End; ++I)

604 RawBodySize += Tokens[I].RawBody.size();

605

607 RawBody.reserve(RawBodySize);

608 for (std::size_t I = Start; I < End; ++I)

609 RawBody += Tokens[I].RawBody;

610

612 Parent->addChild(CurrentNode);

613}

614

616 Tokens = tokenize(TemplateStr, Ctx);

617 CurrentPtr = 0;

619 parseMustache(RootNode);

620 return RootNode;

621}

622

623void Parser::parseMustache(ASTNode *Parent) {

624

625 while (CurrentPtr < Tokens.size()) {

626 Token CurrentToken = Tokens[CurrentPtr];

627 CurrentPtr++;

630

631 switch (CurrentToken.getType()) {

634 Parent->addChild(CurrentNode);

635 break;

636 }

639 Parent->addChild(CurrentNode);

640 break;

641 }

644 Parent->addChild(CurrentNode);

645 break;

646 }

650 Parent->addChild(CurrentNode);

651 break;

652 }

655 break;

656 }

659 break;

660 }

663 break;

665 return;

666 }

667 }

668}

672 << "\n");

673 switch (Data.kind()) {

675 return;

677 auto Num = *Data.getAsNumber();

678 std::ostringstream SS;

679 SS << Num;

680 OS << SS.str();

681 return;

682 }

684 OS << *Data.getAsString();

685 return;

686 }

687

689 auto Arr = *Data.getAsArray();

690 if (Arr.empty())

691 return;

692 [[fallthrough]];

693 }

698 break;

699 }

700 }

701}

702

703void ASTNode::renderRoot(const json::Value &CurrentCtx,

705 renderChild(CurrentCtx, OS);

706}

707

709

710void ASTNode::renderPartial(const json::Value &CurrentCtx,

712 LLVM_DEBUG(dbgs() << "[Render Partial] Accessor:" << AccessorValue[0]

713 << ", Indentation:" << Indentation << "\n");

714 auto Partial = Ctx.Partials.find(AccessorValue[0]);

715 if (Partial != Ctx.Partials.end())

716 renderPartial(CurrentCtx, OS, Partial->getValue());

717}

718

719void ASTNode::renderVariable(const json::Value &CurrentCtx,

721 auto Lambda = Ctx.Lambdas.find(AccessorValue[0]);

722 if (Lambda != Ctx.Lambdas.end()) {

723 renderLambdas(CurrentCtx, OS, Lambda->getValue());

724 } else if (const json::Value *ContextPtr = findContext()) {

725 EscapeStringStream ES(OS, Ctx.Escapes);

727 }

728}

729

730void ASTNode::renderUnescapeVariable(const json::Value &CurrentCtx,

732 LLVM_DEBUG(dbgs() << "[Render UnescapeVariable] Accessor:" << AccessorValue[0]

733 << "\n");

734 auto Lambda = Ctx.Lambdas.find(AccessorValue[0]);

735 if (Lambda != Ctx.Lambdas.end()) {

736 renderLambdas(CurrentCtx, OS, Lambda->getValue());

737 } else if (const json::Value *ContextPtr = findContext()) {

741 }

742}

743

744void ASTNode::renderSection(const json::Value &CurrentCtx,

746 auto SectionLambda = Ctx.SectionLambdas.find(AccessorValue[0]);

748 renderSectionLambdas(CurrentCtx, OS, SectionLambda->getValue());

749 return;

750 }

751

752 const json::Value *ContextPtr = findContext();

753 if (isContextFalsey(ContextPtr))

754 return;

755

756 if (const json::Array *Arr = ContextPtr->getAsArray()) {

757 for (const json::Value &V : *Arr)

758 renderChild(V, OS);

759 return;

760 }

761 renderChild(*ContextPtr, OS);

762}

763

764void ASTNode::renderInvertSection(const json::Value &CurrentCtx,

766 bool IsLambda = Ctx.SectionLambdas.contains(AccessorValue[0]);

767 const json::Value *ContextPtr = findContext();

768 if (isContextFalsey(ContextPtr) && !IsLambda) {

769 renderChild(CurrentCtx, OS);

770 }

771}

772

774 if (Ty != Root && Ty != Text && AccessorValue.empty())

775 return;

776

777

778 ParentContext = &Data;

779

780 switch (Ty) {

782 renderRoot(Data, OS);

783 return;

785 renderText(OS);

786 return;

788 renderPartial(Data, OS);

789 return;

791 renderVariable(Data, OS);

792 return;

794 renderUnescapeVariable(Data, OS);

795 return;

797 renderSection(Data, OS);

798 return;

800 renderInvertSection(Data, OS);

801 return;

802 }

804}

805

806const json::Value *ASTNode::findContext() {

807

808

809

810

811

812 if (AccessorValue.empty())

813 return nullptr;

814 if (AccessorValue[0] == ".")

815 return ParentContext;

816

818 StringRef CurrentAccessor = AccessorValue[0];

819 ASTNode *CurrentParent = Parent;

820

821 while (!CurrentContext || !CurrentContext->get(CurrentAccessor)) {

822 if (CurrentParent->Ty != Root) {

823 CurrentContext = CurrentParent->ParentContext->getAsObject();

824 CurrentParent = CurrentParent->Parent;

825 continue;

826 }

827 return nullptr;

828 }

830 for (auto [Idx, Acc] : enumerate(AccessorValue)) {

831 const json::Value *CurrentValue = CurrentContext->get(Acc);

832 if (!CurrentValue)

833 return nullptr;

834 if (Idx < AccessorValue.size() - 1) {

835 CurrentContext = CurrentValue->getAsObject();

836 if (!CurrentContext)

837 return nullptr;

838 } else {

840 }

841 }

843}

844

845void ASTNode::renderChild(const json::Value &Contexts,

847 for (ASTNode &Child : Children)

848 Child.render(Contexts, OS);

849}

850

851void ASTNode::renderPartial(const json::Value &Contexts,

853 LLVM_DEBUG(dbgs() << "[Render Partial Indentation] Indentation: " << Indentation << "\n");

854 AddIndentationStringStream IS(OS, Indentation);

855 Partial->render(Contexts, IS);

856}

857

858void ASTNode::renderLambdas(const llvm::json::Value &Contexts,

860 json::Value LambdaResult = L();

861 std::string LambdaStr;

862 raw_string_ostream Output(LambdaStr);

864 Parser P(LambdaStr, Ctx);

865 AstPtr LambdaNode = P.parse();

866

867 EscapeStringStream ES(OS, Ctx.Escapes);

869 LambdaNode->render(Contexts, ES);

870 return;

871 }

872 LambdaNode->render(Contexts, OS);

873}

874

875void ASTNode::renderSectionLambdas(const llvm::json::Value &Contexts,

877 json::Value Return = L(RawBody.str());

878 if (isFalsey(Return))

879 return;

880 std::string LambdaStr;

881 raw_string_ostream Output(LambdaStr);

883 Parser P(LambdaStr, Ctx);

884 AstPtr LambdaNode = P.parse();

885 LambdaNode->render(Contexts, OS);

886}

887

890 Tree->render(Data, MOS);

891}

892

894 StringRef SavedPartial = Ctx.Saver.save(Partial);

895 Parser P(SavedPartial, Ctx);

896 AstPtr PartialTree = P.parse();

897 Ctx.Partials.insert(std::make_pair(Name, PartialTree));

898}

899

901 Ctx.Lambdas[Name] = L;

902}

903

905 Ctx.SectionLambdas[Name] = L;

906}

907

909 Ctx.Escapes = std::move(E);

910}

911

913 Parser P(TemplateStr, Ctx);

914 Tree = P.parse();

915

916 const EscapeMap HtmlEntities = {{'&', "&"},

917 {'<', "<"},

918 {'>', ">"},

919 {'"', """},

920 {'\'', "'"}};

922}

923

926 Other.Tree = nullptr;

927}

928

930

931}

932

933#undef DEBUG_TYPE

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

This file defines the SmallVector class.

static SymbolRef::Type getType(const Symbol *Sym)

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

size_t size() const

size - Get the array size.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

reference emplace_back(ArgTypes &&... Args)

void reserve(size_type N)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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.

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

LLVM_ABI size_t find_last_not_of(char C, size_t From=npos) const

Find the last character in the string that is not C, or npos if not found.

static constexpr size_t npos

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef drop_front(size_t N=1) const

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

StringRef slice(size_t Start, size_t End) const

Return a reference to the substring from [Start, End).

constexpr size_t size() const

size - Get the string size.

char front() const

front - Get the first character in the string.

StringRef ltrim(char Char) const

Return string with consecutive Char characters starting from the the left removed.

StringRef rtrim(char Char) const

Return string with consecutive Char characters starting from the right removed.

StringRef take_until(function_ref< bool(char)> F) const

Return the longest prefix of 'this' such that no character in the prefix satisfies the given predicat...

StringRef trim(char Char) const

Return string with consecutive Char characters starting from the left and right removed.

bool ends_with(StringRef Suffix) const

Check if this string ends with the given Suffix.

LLVM_ABI size_t find_first_not_of(char C, size_t From=0) const

Find the first character in the string that is not C or npos if not found.

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

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

LLVM_ABI void value(const Value &V)

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

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

LLVM_ABI Value * get(StringRef K)

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...

const json::Object * getAsObject() const

const json::Array * getAsArray() const

Definition Mustache.cpp:183

ASTNode(MustacheContext &Ctx, Type Ty, ArrayRef< StringRef > Accessor, ASTNode *Parent)

Definition Mustache.cpp:203

ASTNode(MustacheContext &Ctx)

Definition Mustache.cpp:195

Type

Definition Mustache.cpp:185

@ Variable

Definition Mustache.cpp:189

@ Section

Definition Mustache.cpp:191

@ Root

Definition Mustache.cpp:186

@ InvertSection

Definition Mustache.cpp:192

@ Partial

Definition Mustache.cpp:188

@ Text

Definition Mustache.cpp:187

@ UnescapeVariable

Definition Mustache.cpp:190

void setIndentation(size_t NewIndentation)

Definition Mustache.cpp:212

ASTNode(MustacheContext &Ctx, StringRef Body, ASTNode *Parent)

Definition Mustache.cpp:198

void setRawBody(StringRef NewBody)

Definition Mustache.cpp:210

void render(const llvm::json::Value &Data, MustacheOutputStream &OS)

Definition Mustache.cpp:773

void addChild(AstPtr Child)

Definition Mustache.cpp:208

void resumeIndentation() override

Definition Mustache.cpp:547

AddIndentationStringStream(raw_ostream &WrappedStream, size_t Indentation)

Definition Mustache.cpp:539

uint64_t current_pos() const override

Return the current position within the stream, not counting the bytes currently in the buffer.

Definition Mustache.cpp:569

void write_impl(const char *Ptr, size_t Size) override

The is the piece of the class that is implemented by subclasses.

Definition Mustache.cpp:550

void suspendIndentation() override

Definition Mustache.cpp:546

uint64_t current_pos() const override

Return the current position within the stream, not counting the bytes currently in the buffer.

Definition Mustache.cpp:528

void write_impl(const char *Ptr, size_t Size) override

The is the piece of the class that is implemented by subclasses.

Definition Mustache.cpp:505

EscapeStringStream(llvm::raw_ostream &WrappedStream, EscapeMap &Escape)

Definition Mustache.cpp:497

Definition Mustache.cpp:86

MustacheOutputStream()=default

virtual void suspendIndentation()

Definition Mustache.cpp:91

~MustacheOutputStream() override=default

virtual void resumeIndentation()

Definition Mustache.cpp:92

Definition Mustache.cpp:578

Parser(StringRef TemplateStr, MustacheContext &Ctx)

Definition Mustache.cpp:580

AstPtr parse()

Definition Mustache.cpp:615

Definition Mustache.cpp:100

RawMustacheOutputStream(raw_ostream &OS)

Definition Mustache.cpp:102

LLVM_ABI void registerPartial(std::string Name, std::string Partial)

Definition Mustache.cpp:893

LLVM_ABI void registerLambda(std::string Name, Lambda Lambda)

Definition Mustache.cpp:900

LLVM_ABI Template(StringRef TemplateStr, MustacheContext &Ctx)

Definition Mustache.cpp:912

LLVM_ABI void render(const llvm::json::Value &Data, llvm::raw_ostream &OS)

Definition Mustache.cpp:888

LLVM_ABI void overrideEscapeCharacters(DenseMap< char, std::string > Escapes)

Definition Mustache.cpp:908

Definition Mustache.cpp:113

Type getType() const

Definition Mustache.cpp:145

size_t getIndentation() const

Definition Mustache.cpp:149

StringRef RawBody

Definition Mustache.cpp:174

Type

Definition Mustache.cpp:115

@ Comment

Definition Mustache.cpp:123

@ Partial

Definition Mustache.cpp:118

@ Variable

Definition Mustache.cpp:117

@ SetDelimiter

Definition Mustache.cpp:124

@ SectionClose

Definition Mustache.cpp:120

@ InvertSectionOpen

Definition Mustache.cpp:121

@ Text

Definition Mustache.cpp:116

@ UnescapeVariable

Definition Mustache.cpp:122

@ SectionOpen

Definition Mustache.cpp:119

Token(StringRef Str)

Definition Mustache.cpp:127

Token(StringRef RawBody, StringRef TokenBody, char Identifier, MustacheContext &Ctx)

Definition Mustache.cpp:131

void setIndentation(size_t NewIndentation)

Definition Mustache.cpp:147

Type TokenType

Definition Mustache.cpp:172

StringRef TokenBody

Definition Mustache.cpp:176

static Type getTokenType(char Identifier)

Definition Mustache.cpp:151

ArrayRef< StringRef > AccessorValue

Definition Mustache.cpp:177

ArrayRef< StringRef > getAccessor() const

Definition Mustache.cpp:143

size_t Indentation

Definition Mustache.cpp:178

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

raw_ostream(bool unbuffered=false, OStreamKind K=OStreamKind::OK_OStream)

uint64_t tell() const

tell - Return the current offset with the file.

raw_ostream & write(unsigned char C)

void SetUnbuffered()

Set the stream to be unbuffered.

#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 bool hasTextAhead(size_t Idx, const ArrayRef< Token > &Tokens)

Definition Mustache.cpp:294

static AstPtr createRootNode(MustacheContext &Ctx)

Definition Mustache.cpp:252

static const char * tagKindToString(Tag::Kind K)

Definition Mustache.cpp:359

void stripTokenBefore(SmallVectorImpl< Token > &Tokens, size_t Idx, Token &CurrentToken, Token::Type CurrentType)

Definition Mustache.cpp:336

iplist< ASTNode > ASTNodeList

static AstPtr createTextNode(MustacheContext &Ctx, StringRef Body, ASTNode *Parent)

Definition Mustache.cpp:261

static const char * jsonKindToString(json::Value::Kind K)

Definition Mustache.cpp:371

std::function< llvm::json::Value(std::string)> SectionLambda

static AstPtr createNode(MustacheContext &Ctx, ASTNode::Type T, ArrayRef< StringRef > A, ASTNode *Parent)

Definition Mustache.cpp:256

static void stripTokenAhead(SmallVectorImpl< Token > &Tokens, size_t Idx)

Definition Mustache.cpp:320

std::function< llvm::json::Value()> Lambda

static bool hasTextBehind(size_t Idx, const ArrayRef< Token > &Tokens)

Definition Mustache.cpp:278

static bool requiresCleanUp(Token::Type T)

Definition Mustache.cpp:307

static SmallVector< Token > tokenize(StringRef Template, MustacheContext &Ctx)

Definition Mustache.cpp:390

DenseMap< char, std::string > EscapeMap

static void toMustacheString(const json::Value &Data, raw_ostream &OS)

Definition Mustache.cpp:669

This is an optimization pass for GlobalISel generic memory operations.

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

FunctionAddr VTableAddr Next

ArrayRef(const T &OneElt) -> ArrayRef< T >

OutputIt copy(R &&Range, OutputIt Out)

Definition Mustache.cpp:346

size_t StartPosition

Definition Mustache.cpp:356

StringRef Content

Definition Mustache.cpp:354

StringRef FullMatch

Definition Mustache.cpp:355

Kind

Definition Mustache.cpp:347

@ Triple

Definition Mustache.cpp:350

@ None

Definition Mustache.cpp:348

@ Normal

Definition Mustache.cpp:349

Kind TagKind

Definition Mustache.cpp:353