MLIR: lib/Tools/mlir-lsp-server/MLIRServer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

20#include "llvm/ADT/StringExtras.h"

21#include "llvm/Support/Base64.h"

22#include "llvm/Support/LSP/Logging.h"

23#include "llvm/Support/SourceMgr.h"

24#include

25

26using namespace mlir;

27

28

29

30

34

35

36

40 lsp::URIForFile::fromFile(loc.getFilename(), uriScheme);

41 if (!sourceURI) {

42 llvm::lsp::Logger::error("Failed to create URI for file `{0}`: {1}",

44 llvm::toString(sourceURI.takeError()));

45 return std::nullopt;

46 }

47

48 lsp::Position position;

49 position.line = loc.getLine() - 1;

51 return lsp::Location{*sourceURI, lsp::Range(position)};

52}

53

54

55

56

57

58static std::optionallsp::Location

60 StringRef uriScheme, const lsp::URIForFile *uri = nullptr) {

61 std::optionallsp::Location location;

63 FileLineColLoc fileLoc = dyn_cast(nestedLoc);

64 if (!fileLoc)

66

67 std::optionallsp::Location sourceLoc =

69 if (sourceLoc && (!uri || sourceLoc->uri == *uri)) {

70 location = *sourceLoc;

71 SMLoc loc = sourceMgr.FindLocForLineAndColumn(

72 sourceMgr.getMainFileID(), fileLoc.getLine(), fileLoc.getColumn());

73

74

75

76 location->range.end.character += 1;

78 auto lineCol = sourceMgr.getLineAndColumn(range->End);

79 location->range.end.character =

80 std::max(fileLoc.getColumn() + 1, lineCol.second - 1);

81 }

83 }

85 });

86 return location;

87}

88

89

90

92 std::vectorlsp::Location &locations,

93 const lsp::URIForFile &uri) {

96 FileLineColLoc fileLoc = dyn_cast(nestedLoc);

97 if (!fileLoc || !visitedLocs.insert(nestedLoc))

99

100 std::optionallsp::Location sourceLoc =

102 if (sourceLoc && sourceLoc->uri != uri)

103 locations.push_back(*sourceLoc);

105 });

106}

107

108

109

110

111static bool contains(SMRange range, SMLoc loc) {

112 return range.Start.getPointer() <= loc.getPointer() &&

113 loc.getPointer() <= range.End.getPointer();

114}

115

116

117

118

120 SMRange *overlappedRange = nullptr) {

121

123 if (overlappedRange)

124 *overlappedRange = def.loc;

125 return true;

126 }

127

128

129 const auto *useIt = llvm::find_if(

130 def.uses, [&](const SMRange &range) { return contains(range, loc); });

131 if (useIt != def.uses.end()) {

132 if (overlappedRange)

133 *overlappedRange = *useIt;

134 return true;

135 }

136 return false;

137}

138

139

140

142

143 auto isIdentifierChar = [](char c) {

144 return isalnum(c) || c == '%' || c == '$' || c == '.' || c == '_' ||

145 c == '-';

146 };

147 const char *curPtr = loc.getPointer();

148 while (isIdentifierChar(*curPtr))

149 ++curPtr;

150

151

152

153 if (*curPtr != '#')

154 return std::nullopt;

155

156

157 const char *numberStart = ++curPtr;

158 while (llvm::isDigit(*curPtr))

159 ++curPtr;

160 StringRef numberStr(numberStart, curPtr - numberStart);

161 unsigned resultNumber = 0;

162 return numberStr.consumeInteger(10, resultNumber) ? std::optional()

163 : resultNumber;

164}

165

166

167

169 if (!range.isValid())

170 return std::nullopt;

171 const char *startPtr = range.Start.getPointer();

172 return StringRef(startPtr, range.End.getPointer() - startPtr);

173}

174

175

177 return std::distance(block->getParent()->begin(), block->getIterator());

178}

179

180

181

183

185 if (text && text->starts_with("^")) {

186 os << *text;

187 return;

188 }

189

190

192}

197

198

201 const lsp::URIForFile &uri) {

202 lsp::Diagnostic lspDiag;

203 lspDiag.source = "mlir";

204

205

206

207 lspDiag.category = "Parse Error";

208

209

210

211

212 StringRef uriScheme = uri.scheme();

213 std::optionallsp::Location lspLocation =

215 if (lspLocation)

216 lspDiag.range = lspLocation->range;

217

218

219 switch (diag.getSeverity()) {

221 llvm_unreachable("expected notes to be handled separately");

223 lspDiag.severity = llvm::lsp::DiagnosticSeverity::Warning;

224 break;

226 lspDiag.severity = llvm::lsp::DiagnosticSeverity::Error;

227 break;

229 lspDiag.severity = llvm::lsp::DiagnosticSeverity::Information;

230 break;

231 }

232 lspDiag.message = diag.str();

233

234

235 std::vectorllvm::lsp::DiagnosticRelatedInformation relatedDiags;

237 lsp::Location noteLoc;

238 if (std::optionallsp::Location loc =

240 noteLoc = *loc;

241 else

242 noteLoc.uri = uri;

243 relatedDiags.emplace_back(noteLoc, note.str());

244 }

245 if (!relatedDiags.empty())

246 lspDiag.relatedInformation = std::move(relatedDiags);

247

248 return lspDiag;

249}

250

251

252

253

254

255namespace {

256

257

258struct MLIRDocument {

259 MLIRDocument(MLIRContext &context, const lsp::URIForFile &uri,

260 StringRef contents, std::vectorlsp::Diagnostic &diagnostics);

261 MLIRDocument(const MLIRDocument &) = delete;

262 MLIRDocument &operator=(const MLIRDocument &) = delete;

263

264

265

266

267

268 void getLocationsOf(const lsp::URIForFile &uri, const lsp::Position &defPos,

269 std::vectorlsp::Location &locations);

270 void findReferencesOf(const lsp::URIForFile &uri, const lsp::Position &pos,

271 std::vectorlsp::Location &references);

272

273

274

275

276

277 std::optionallsp::Hover findHover(const lsp::URIForFile &uri,

278 const lsp::Position &hoverPos);

279 std::optionallsp::Hover

280 buildHoverForOperation(SMRange hoverRange,

281 const AsmParserState::OperationDefinition &op);

282 lsp::Hover buildHoverForOperationResult(SMRange hoverRange, Operation *op,

283 unsigned resultStart,

284 unsigned resultEnd, SMLoc posLoc);

285 lsp::Hover buildHoverForBlock(SMRange hoverRange,

286 const AsmParserState::BlockDefinition &block);

287 lsp::Hover

288 buildHoverForBlockArgument(SMRange hoverRange, BlockArgument arg,

289 const AsmParserState::BlockDefinition &block);

290

291 lsp::Hover buildHoverForAttributeAlias(

292 SMRange hoverRange, const AsmParserState::AttributeAliasDefinition &attr);

293 lsp::Hover

294 buildHoverForTypeAlias(SMRange hoverRange,

295 const AsmParserState::TypeAliasDefinition &type);

296

297

298

299

300

301 void findDocumentSymbols(std::vectorlsp::DocumentSymbol &symbols);

302 void findDocumentSymbols(Operation *op,

303 std::vectorlsp::DocumentSymbol &symbols);

304

305

306

307

308

309 lsp::CompletionList getCodeCompletion(const lsp::URIForFile &uri,

310 const lsp::Position &completePos,

311 const DialectRegistry &registry);

312

313

314

315

316

317 void getCodeActionForDiagnostic(const lsp::URIForFile &uri,

318 lsp::Position &pos, StringRef severity,

319 StringRef message,

320 std::vectorllvm::lsp::TextEdit &edits);

321

322

323

324

325

326 llvm::Expectedlsp::MLIRConvertBytecodeResult convertToBytecode();

327

328

329

330

331

332

333

334 AsmParserState asmState;

335

336

338

339

340

341 FallbackAsmResourceMap fallbackResourceMap;

342

343

344 llvm::SourceMgr sourceMgr;

345};

346}

347

348MLIRDocument::MLIRDocument(MLIRContext &context, const lsp::URIForFile &uri,

349 StringRef contents,

350 std::vectorlsp::Diagnostic &diagnostics) {

351 ScopedDiagnosticHandler handler(&context, [&](Diagnostic &diag) {

353 });

354

355

356 auto memBuffer = llvm::MemoryBuffer::getMemBufferCopy(contents, uri.file());

357 if (!memBuffer) {

358 llvm::lsp::Logger::error("Failed to create memory buffer for file",

359 uri.file());

360 return;

361 }

362

363 ParserConfig config(&context, true,

364 &fallbackResourceMap);

365 sourceMgr.AddNewSourceBuffer(std::move(memBuffer), SMLoc());

367

368 parsedIR.clear();

369 asmState = AsmParserState();

370 fallbackResourceMap = FallbackAsmResourceMap();

371 return;

372 }

373}

374

375

376

377

378

379void MLIRDocument::getLocationsOf(const lsp::URIForFile &uri,

380 const lsp::Position &defPos,

381 std::vectorlsp::Location &locations) {

382 SMLoc posLoc = defPos.getAsSMLoc(sourceMgr);

383

384

385 auto containsPosition = [&](const AsmParserState::SMDefinition &def) {

387 return false;

388 locations.emplace_back(uri, sourceMgr, def.loc);

389 return true;

390 };

391

392

393 for (const AsmParserState::OperationDefinition &op : asmState.getOpDefs()) {

394 if (contains(op.loc, posLoc))

396 for (const auto &result : op.resultGroups)

397 if (containsPosition(result.definition))

399 for (const auto &symUse : op.symbolUses) {

400 if (contains(symUse, posLoc)) {

401 locations.emplace_back(uri, sourceMgr, op.loc);

403 }

404 }

405 }

406

407

408 for (const AsmParserState::BlockDefinition &block : asmState.getBlockDefs()) {

409 if (containsPosition(block.definition))

410 return;

411 for (const AsmParserState::SMDefinition &arg : block.arguments)

412 if (containsPosition(arg))

413 return;

414 }

415

416

417 for (const AsmParserState::AttributeAliasDefinition &attr :

419 if (containsPosition(attr.definition))

420 return;

421 }

422 for (const AsmParserState::TypeAliasDefinition &type :

424 if (containsPosition(type.definition))

425 return;

426 }

427}

428

429void MLIRDocument::findReferencesOf(const lsp::URIForFile &uri,

430 const lsp::Position &pos,

431 std::vectorlsp::Location &references) {

432

433

434 auto appendSMDef = [&](const AsmParserState::SMDefinition &def) {

435 references.emplace_back(uri, sourceMgr, def.loc);

436 for (const SMRange &use : def.uses)

437 references.emplace_back(uri, sourceMgr, use);

438 };

439

440 SMLoc posLoc = pos.getAsSMLoc(sourceMgr);

441

442

443 for (const AsmParserState::OperationDefinition &op : asmState.getOpDefs()) {

444 if (contains(op.loc, posLoc)) {

445 for (const auto &result : op.resultGroups)

446 appendSMDef(result.definition);

447 for (const auto &symUse : op.symbolUses)

448 if (contains(symUse, posLoc))

449 references.emplace_back(uri, sourceMgr, symUse);

450 return;

451 }

452 for (const auto &result : op.resultGroups)

454 return appendSMDef(result.definition);

455 for (const auto &symUse : op.symbolUses) {

456 if (contains(symUse, posLoc))

457 continue;

458 for (const auto &symUse : op.symbolUses)

459 references.emplace_back(uri, sourceMgr, symUse);

460 return;

461 }

462 }

463

464

465 for (const AsmParserState::BlockDefinition &block : asmState.getBlockDefs()) {

466 if (isDefOrUse(block.definition, posLoc))

467 return appendSMDef(block.definition);

468

469 for (const AsmParserState::SMDefinition &arg : block.arguments)

471 return appendSMDef(arg);

472 }

473

474

475 for (const AsmParserState::AttributeAliasDefinition &attr :

477 if (isDefOrUse(attr.definition, posLoc))

478 return appendSMDef(attr.definition);

479 }

480 for (const AsmParserState::TypeAliasDefinition &type :

482 if (isDefOrUse(type.definition, posLoc))

483 return appendSMDef(type.definition);

484 }

485}

486

487

488

489

490

491std::optionallsp::Hover

492MLIRDocument::findHover(const lsp::URIForFile &uri,

493 const lsp::Position &hoverPos) {

494 SMLoc posLoc = hoverPos.getAsSMLoc(sourceMgr);

495 SMRange hoverRange;

496

497

498 for (const AsmParserState::OperationDefinition &op : asmState.getOpDefs()) {

499

500 if (contains(op.loc, posLoc))

501 return buildHoverForOperation(op.loc, op);

502

503

504 for (auto &use : op.symbolUses)

506 return buildHoverForOperation(use, op);

507

508

509 for (unsigned i = 0, e = op.resultGroups.size(); i < e; ++i) {

510 const auto &result = op.resultGroups[i];

512 continue;

513

514

515 unsigned resultStart = result.startIndex;

516 unsigned resultEnd = (i == e - 1) ? op.op->getNumResults()

517 : op.resultGroups[i + 1].startIndex;

518 return buildHoverForOperationResult(hoverRange, op.op, resultStart,

519 resultEnd, posLoc);

520 }

521 }

522

523

524 for (const AsmParserState::BlockDefinition &block : asmState.getBlockDefs()) {

525 if (isDefOrUse(block.definition, posLoc, &hoverRange))

526 return buildHoverForBlock(hoverRange, block);

527

528 for (const auto &arg : llvm::enumerate(block.arguments)) {

529 if (isDefOrUse(arg.value(), posLoc, &hoverRange))

530 continue;

531

532 return buildHoverForBlockArgument(

533 hoverRange, block.block->getArgument(arg.index()), block);

534 }

535 }

536

537

538 for (const AsmParserState::AttributeAliasDefinition &attr :

540 if (isDefOrUse(attr.definition, posLoc, &hoverRange))

541 return buildHoverForAttributeAlias(hoverRange, attr);

542 }

543 for (const AsmParserState::TypeAliasDefinition &type :

545 if (isDefOrUse(type.definition, posLoc, &hoverRange))

546 return buildHoverForTypeAlias(hoverRange, type);

547 }

548

549 return std::nullopt;

550}

551

552std::optionallsp::Hover MLIRDocument::buildHoverForOperation(

553 SMRange hoverRange, const AsmParserState::OperationDefinition &op) {

554 lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));

555 llvm::raw_string_ostream os(hover.contents.value);

556

557

558 os << "\"" << op.op->getName() << "\"";

559 if (SymbolOpInterface symbol = dyn_cast(op.op))

560 os << " : " << symbol.getVisibility() << " @" << symbol.getName() << "";

561 os << "\n\n";

562

563 os << "Generic Form:\n\n```mlir\n";

564

565 op.op->print(os, OpPrintingFlags()

566 .printGenericOpForm()

567 .elideLargeElementsAttrs()

568 .skipRegions());

569 os << "\n```\n";

570

571 return hover;

572}

573

574lsp::Hover MLIRDocument::buildHoverForOperationResult(SMRange hoverRange,

575 Operation *op,

576 unsigned resultStart,

577 unsigned resultEnd,

578 SMLoc posLoc) {

579 lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));

580 llvm::raw_string_ostream os(hover.contents.value);

581

582

583 os << "Operation: \"" << op->getName() << "\"\n\n";

584

585

586

588 if ((resultStart + *resultNumber) < resultEnd) {

589 resultStart += *resultNumber;

590 resultEnd = resultStart + 1;

591 }

592 }

593

594

595 if ((resultStart + 1) == resultEnd) {

596 os << "Result #" << resultStart << "\n\n"

597 << "Type: `" << op->getResult(resultStart).getType() << "`\n\n";

598 } else {

599 os << "Result #[" << resultStart << ", " << (resultEnd - 1) << "]\n\n"

600 << "Types: ";

601 llvm::interleaveComma(

602 op->getResults().slice(resultStart, resultEnd), os,

603 [&](Value result) { os << "`" << result.getType() << "`"; });

604 }

605

606 return hover;

607}

608

609lsp::Hover

610MLIRDocument::buildHoverForBlock(SMRange hoverRange,

611 const AsmParserState::BlockDefinition &block) {

612 lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));

613 llvm::raw_string_ostream os(hover.contents.value);

614

615

616 auto printBlockToHover = [&](Block *newBlock) {

617 if (const auto *def = asmState.getBlockDef(newBlock))

619 else

621 };

622

623

627 os << "Predecessors: ";

629 printBlockToHover);

630 os << "\n\n";

631 }

633 os << "Successors: ";

634 llvm::interleaveComma(block.block->getSuccessors(), os, printBlockToHover);

635 os << "\n\n";

636 }

637

638 return hover;

639}

640

641lsp::Hover MLIRDocument::buildHoverForBlockArgument(

642 SMRange hoverRange, BlockArgument arg,

643 const AsmParserState::BlockDefinition &block) {

644 lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));

645 llvm::raw_string_ostream os(hover.contents.value);

646

647

649 << "Block: ";

651 os << "\n\nArgument #" << arg.getArgNumber() << "\n\n"

652 << "Type: `" << arg.getType() << "`\n\n";

653

654 return hover;

655}

656

657lsp::Hover MLIRDocument::buildHoverForAttributeAlias(

658 SMRange hoverRange, const AsmParserState::AttributeAliasDefinition &attr) {

659 lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));

660 llvm::raw_string_ostream os(hover.contents.value);

661

662 os << "Attribute Alias: \"" << attr.name << "\n\n";

663 os << "Value: ```mlir\n" << attr.value << "\n```\n\n";

664

665 return hover;

666}

667

668lsp::Hover MLIRDocument::buildHoverForTypeAlias(

669 SMRange hoverRange, const AsmParserState::TypeAliasDefinition &type) {

670 lsp::Hover hover(lsp::Range(sourceMgr, hoverRange));

671 llvm::raw_string_ostream os(hover.contents.value);

672

673 os << "Type Alias: \"" << type.name << "\n\n";

674 os << "Value: ```mlir\n" << type.value << "\n```\n\n";

675

676 return hover;

677}

678

679

680

681

682

683void MLIRDocument::findDocumentSymbols(

684 std::vectorlsp::DocumentSymbol &symbols) {

685 for (Operation &op : parsedIR)

686 findDocumentSymbols(&op, symbols);

687}

688

689void MLIRDocument::findDocumentSymbols(

690 Operation *op, std::vectorlsp::DocumentSymbol &symbols) {

691 std::vectorlsp::DocumentSymbol *childSymbols = &symbols;

692

693

694 if (const AsmParserState::OperationDefinition *def = asmState.getOpDef(op)) {

695

696 if (SymbolOpInterface symbol = dyn_cast(op)) {

697 symbols.emplace_back(symbol.getName(),

698 isa(op)

699 ? llvm::lsp::SymbolKind::Function

700 : llvm::lsp::SymbolKind::Class,

701 lsp::Range(sourceMgr, def->scopeLoc),

702 lsp::Range(sourceMgr, def->loc));

703 childSymbols = &symbols.back().children;

704

705 } else if (op->hasTraitOpTrait::SymbolTable()) {

706

708 llvm::lsp::SymbolKind::Namespace,

709 llvm::lsp::Range(sourceMgr, def->scopeLoc),

710 llvm::lsp::Range(sourceMgr, def->loc));

711 childSymbols = &symbols.back().children;

712 }

713 }

714

715

717 return;

718 for (Region &region : op->getRegions())

719 for (Operation &childOp : region.getOps())

720 findDocumentSymbols(&childOp, *childSymbols);

721}

722

723

724

725

726

727namespace {

728class LSPCodeCompleteContext : public AsmParserCodeCompleteContext {

729public:

730 LSPCodeCompleteContext(SMLoc completeLoc, lsp::CompletionList &completionList,

731 MLIRContext *ctx)

732 : AsmParserCodeCompleteContext(completeLoc),

733 completionList(completionList), ctx(ctx) {}

734

735

736 void completeDialectName(StringRef prefix) final {

738 llvm::lsp::CompletionItem item(prefix + dialect,

739 llvm::lsp::CompletionItemKind::Module,

740 "3");

741 item.detail = "dialect";

742 completionList.items.emplace_back(item);

743 }

744 }

746

747

748 void completeOperationName(StringRef dialectName) final {

750 if (!dialect)

751 return;

752

755 continue;

756

757 llvm::lsp::CompletionItem item(

758 op.getStringRef().drop_front(dialectName.size() + 1),

759 llvm::lsp::CompletionItemKind::Field,

760 "1");

761 item.detail = "operation";

762 completionList.items.emplace_back(item);

763 }

764 }

765

766

767

768 void appendSSAValueCompletion(StringRef name, std::string typeData) final {

769

770 bool stripPrefix = getCodeCompleteLoc().getPointer()[-1] == '%';

771

772 llvm::lsp::CompletionItem item(name,

773 llvm::lsp::CompletionItemKind::Variable);

774 if (stripPrefix)

775 item.insertText = name.drop_front(1).str();

776 item.detail = std::move(typeData);

777 completionList.items.emplace_back(item);

778 }

779

780

781

782 void appendBlockCompletion(StringRef name) final {

783

784 bool stripPrefix = getCodeCompleteLoc().getPointer()[-1] == '^';

785

786 llvm::lsp::CompletionItem item(name, llvm::lsp::CompletionItemKind::Field);

787 if (stripPrefix)

788 item.insertText = name.drop_front(1).str();

789 completionList.items.emplace_back(item);

790 }

791

792

793 void completeExpectedTokens(ArrayRef tokens, bool optional) final {

794 for (StringRef token : tokens) {

795 llvm::lsp::CompletionItem item(token,

796 llvm::lsp::CompletionItemKind::Keyword,

797 "0");

798 item.detail = optional ? "optional" : "";

799 completionList.items.emplace_back(item);

800 }

801 }

802

803

804 void completeAttribute(const llvm::StringMap &aliases) override {

805 appendSimpleCompletions({"affine_set", "affine_map", "dense",

806 "dense_resource", "false", "loc", "sparse", "true",

807 "unit"},

808 llvm::lsp::CompletionItemKind::Field,

809 "1");

810

811 completeDialectName("#");

812 completeAliases(aliases, "#");

813 }

814 void completeDialectAttributeOrAlias(

815 const llvm::StringMap &aliases) override {

816 completeDialectName();

817 completeAliases(aliases);

818 }

819

820

821 void completeType(const llvm::StringMap &aliases) override {

822

823 appendSimpleCompletions({"memref", "tensor", "complex", "tuple", "vector",

824 "bf16", "f16", "f32", "f64", "f80", "f128",

825 "index", "none"},

826 llvm::lsp::CompletionItemKind::Field,

827 "1");

828

829

830 for (StringRef type : {"i", "si", "ui"}) {

831 llvm::lsp::CompletionItem item(type + "",

832 llvm::lsp::CompletionItemKind::Field,

833 "1");

834 item.insertText = type.str();

835 completionList.items.emplace_back(item);

836 }

837

838

839 completeDialectName("!");

840 completeAliases(aliases, "!");

841 }

842 void

843 completeDialectTypeOrAlias(const llvm::StringMap &aliases) override {

844 completeDialectName();

845 completeAliases(aliases);

846 }

847

848

849 template

850 void completeAliases(const llvm::StringMap &aliases,

851 StringRef prefix = "") {

852 for (const auto &alias : aliases) {

853 llvm::lsp::CompletionItem item(prefix + alias.getKey(),

854 llvm::lsp::CompletionItemKind::Field,

855 "2");

856 llvm::raw_string_ostream(item.detail) << "alias: " << alias.getValue();

857 completionList.items.emplace_back(item);

858 }

859 }

860

861

862 void appendSimpleCompletions(ArrayRef completions,

863 llvm::lsp::CompletionItemKind kind,

864 StringRef sortText = "") {

865 for (StringRef completion : completions)

866 completionList.items.emplace_back(completion, kind, sortText);

867 }

868

869private:

870 lsp::CompletionList &completionList;

871 MLIRContext *ctx;

872};

873}

874

875lsp::CompletionList

876MLIRDocument::getCodeCompletion(const lsp::URIForFile &uri,

877 const lsp::Position &completePos,

878 const DialectRegistry &registry) {

879 SMLoc posLoc = completePos.getAsSMLoc(sourceMgr);

880 if (!posLoc.isValid())

881 return lsp::CompletionList();

882

883

884

885 MLIRContext tmpContext(registry, MLIRContext::Threading::DISABLED);

886 tmpContext.allowUnregisteredDialects();

887 lsp::CompletionList completionList;

888 LSPCodeCompleteContext lspCompleteContext(posLoc, completionList,

889 &tmpContext);

890

892 AsmParserState tmpState;

894 &lspCompleteContext);

895 return completionList;

896}

897

898

899

900

901

902void MLIRDocument::getCodeActionForDiagnostic(

903 const lsp::URIForFile &uri, lsp::Position &pos, StringRef severity,

904 StringRef message, std::vectorllvm::lsp::TextEdit &edits) {

905

906

907

908 if (message.starts_with("see current operation: "))

909 return;

910

911

912 const auto &buffer = sourceMgr.getBufferInfo(sourceMgr.getMainFileID());

913 const char *lineStart = buffer.getPointerForLineNumber(pos.line + 1);

914 if (!lineStart)

915 return;

916 StringRef line(lineStart, pos.character);

917

918

919

920 llvm::lsp::TextEdit edit;

921 edit.range = lsp::Range(lsp::Position(pos.line, 0));

922

923

924 size_t indent = line.find_first_not_of(' ');

925 if (indent == StringRef::npos)

926 indent = line.size();

927

928 edit.newText.append(indent, ' ');

929 llvm::raw_string_ostream(edit.newText)

930 << "// expected-" << severity << " @below {{" << message << "}}\n";

931 edits.emplace_back(std::move(edit));

932}

933

934

935

936

937

938llvm::Expectedlsp::MLIRConvertBytecodeResult

939MLIRDocument::convertToBytecode() {

940

941

942 if (!llvm::hasSingleElement(parsedIR)) {

943 if (parsedIR.empty()) {

944 return llvm::make_errorllvm::lsp::LSPError(

945 "expected a single and valid top-level operation, please ensure "

946 "there are no errors",

947 llvm::lsp::ErrorCode::RequestFailed);

948 }

949 return llvm::make_errorllvm::lsp::LSPError(

950 "expected a single top-level operation",

951 llvm::lsp::ErrorCode::RequestFailed);

952 }

953

954 lsp::MLIRConvertBytecodeResult result;

955 {

956 BytecodeWriterConfig writerConfig(fallbackResourceMap);

957

958 std::string rawBytecodeBuffer;

959 llvm::raw_string_ostream os(rawBytecodeBuffer);

960

962 result.output = llvm::encodeBase64(rawBytecodeBuffer);

963 }

965}

966

967

968

969

970

971namespace {

972

973struct MLIRTextFileChunk {

974 MLIRTextFileChunk(MLIRContext &context, uint64_t lineOffset,

975 const lsp::URIForFile &uri, StringRef contents,

976 std::vectorlsp::Diagnostic &diagnostics)

977 : lineOffset(lineOffset), document(context, uri, contents, diagnostics) {}

978

979

980

981 void adjustLocForChunkOffset(lsp::Range &range) {

982 adjustLocForChunkOffset(range.start);

983 adjustLocForChunkOffset(range.end);

984 }

985

986

987 void adjustLocForChunkOffset(lsp::Position &pos) { pos.line += lineOffset; }

988

989

990 uint64_t lineOffset;

991

992 MLIRDocument document;

993};

994}

995

996

997

998

999

1000namespace {

1001

1002class MLIRTextFile {

1003public:

1004 MLIRTextFile(const lsp::URIForFile &uri, StringRef fileContents,

1006 std::vectorlsp::Diagnostic &diagnostics);

1007

1008

1009 int64_t getVersion() const { return version; }

1010

1011

1012

1013

1014

1015 void getLocationsOf(const lsp::URIForFile &uri, lsp::Position defPos,

1016 std::vectorlsp::Location &locations);

1017 void findReferencesOf(const lsp::URIForFile &uri, lsp::Position pos,

1018 std::vectorlsp::Location &references);

1019 std::optionallsp::Hover findHover(const lsp::URIForFile &uri,

1020 lsp::Position hoverPos);

1021 void findDocumentSymbols(std::vectorlsp::DocumentSymbol &symbols);

1022 lsp::CompletionList getCodeCompletion(const lsp::URIForFile &uri,

1023 lsp::Position completePos);

1024 void getCodeActions(const lsp::URIForFile &uri, const lsp::Range &pos,

1025 const lsp::CodeActionContext &context,

1026 std::vectorlsp::CodeAction &actions);

1027 llvm::Expectedlsp::MLIRConvertBytecodeResult convertToBytecode();

1028

1029private:

1030

1031

1032

1033 MLIRTextFileChunk &getChunkFor(lsp::Position &pos);

1034

1035

1036 MLIRContext context;

1037

1038

1039 std::string contents;

1040

1041

1042 int64_t version;

1043

1044

1045 int64_t totalNumLines = 0;

1046

1047

1048

1049 std::vector<std::unique_ptr> chunks;

1050};

1051}

1052

1053MLIRTextFile::MLIRTextFile(const lsp::URIForFile &uri, StringRef fileContents,

1055 std::vectorlsp::Diagnostic &diagnostics)

1056 : context(registryFn(uri), MLIRContext::Threading::DISABLED),

1057 contents(fileContents.str()), version(version) {

1059

1060

1063 chunks.emplace_back(std::make_unique(

1064 context, 0, uri, subContents.front(), diagnostics));

1065

1066 uint64_t lineOffset = subContents.front().count('\n');

1067 for (StringRef docContents : llvm::drop_begin(subContents)) {

1068 unsigned currentNumDiags = diagnostics.size();

1069 auto chunk = std::make_unique(context, lineOffset, uri,

1070 docContents, diagnostics);

1071 lineOffset += docContents.count('\n');

1072

1073

1074

1075 for (lsp::Diagnostic &diag :

1076 llvm::drop_begin(diagnostics, currentNumDiags)) {

1077 chunk->adjustLocForChunkOffset(diag.range);

1078

1079 if (diag.relatedInformation)

1080 continue;

1081 for (auto &it : *diag.relatedInformation)

1082 if (it.location.uri == uri)

1083 chunk->adjustLocForChunkOffset(it.location.range);

1084 }

1085 chunks.emplace_back(std::move(chunk));

1086 }

1087 totalNumLines = lineOffset;

1088}

1089

1090void MLIRTextFile::getLocationsOf(const lsp::URIForFile &uri,

1091 lsp::Position defPos,

1092 std::vectorlsp::Location &locations) {

1093 MLIRTextFileChunk &chunk = getChunkFor(defPos);

1094 chunk.document.getLocationsOf(uri, defPos, locations);

1095

1096

1097 if (chunk.lineOffset == 0)

1098 return;

1099 for (lsp::Location &loc : locations)

1100 if (loc.uri == uri)

1101 chunk.adjustLocForChunkOffset(loc.range);

1102}

1103

1104void MLIRTextFile::findReferencesOf(const lsp::URIForFile &uri,

1105 lsp::Position pos,

1106 std::vectorlsp::Location &references) {

1107 MLIRTextFileChunk &chunk = getChunkFor(pos);

1108 chunk.document.findReferencesOf(uri, pos, references);

1109

1110

1111 if (chunk.lineOffset == 0)

1112 return;

1113 for (lsp::Location &loc : references)

1114 if (loc.uri == uri)

1115 chunk.adjustLocForChunkOffset(loc.range);

1116}

1117

1118std::optionallsp::Hover MLIRTextFile::findHover(const lsp::URIForFile &uri,

1119 lsp::Position hoverPos) {

1120 MLIRTextFileChunk &chunk = getChunkFor(hoverPos);

1121 std::optionallsp::Hover hoverInfo = chunk.document.findHover(uri, hoverPos);

1122

1123

1124 if (chunk.lineOffset != 0 && hoverInfo && hoverInfo->range)

1125 chunk.adjustLocForChunkOffset(*hoverInfo->range);

1126 return hoverInfo;

1127}

1128

1129void MLIRTextFile::findDocumentSymbols(

1130 std::vectorlsp::DocumentSymbol &symbols) {

1131 if (chunks.size() == 1)

1132 return chunks.front()->document.findDocumentSymbols(symbols);

1133

1134

1135

1136 for (unsigned i = 0, e = chunks.size(); i < e; ++i) {

1137 MLIRTextFileChunk &chunk = *chunks[i];

1138 lsp::Position startPos(chunk.lineOffset);

1139 lsp::Position endPos((i == e - 1) ? totalNumLines - 1

1140 : chunks[i + 1]->lineOffset);

1141 lsp::DocumentSymbol symbol("<file-split-" + Twine(i) + ">",

1142 llvm::lsp::SymbolKind::Namespace,

1143 lsp::Range(startPos, endPos),

1144 lsp::Range(startPos));

1145 chunk.document.findDocumentSymbols(symbol.children);

1146

1147

1148 if (i != 0) {

1149 SmallVector<lsp::DocumentSymbol *> symbolsToFix;

1150 for (lsp::DocumentSymbol &childSymbol : symbol.children)

1151 symbolsToFix.push_back(&childSymbol);

1152

1153 while (!symbolsToFix.empty()) {

1154 lsp::DocumentSymbol *symbol = symbolsToFix.pop_back_val();

1155 chunk.adjustLocForChunkOffset(symbol->range);

1156 chunk.adjustLocForChunkOffset(symbol->selectionRange);

1157

1158 for (lsp::DocumentSymbol &childSymbol : symbol->children)

1159 symbolsToFix.push_back(&childSymbol);

1160 }

1161 }

1162

1163

1164 symbols.emplace_back(std::move(symbol));

1165 }

1166}

1167

1168lsp::CompletionList MLIRTextFile::getCodeCompletion(const lsp::URIForFile &uri,

1169 lsp::Position completePos) {

1170 MLIRTextFileChunk &chunk = getChunkFor(completePos);

1171 lsp::CompletionList completionList = chunk.document.getCodeCompletion(

1173

1174

1175 for (llvm::lsp::CompletionItem &item : completionList.items) {

1176 if (item.textEdit)

1177 chunk.adjustLocForChunkOffset(item.textEdit->range);

1178 for (llvm::lsp::TextEdit &edit : item.additionalTextEdits)

1179 chunk.adjustLocForChunkOffset(edit.range);

1180 }

1181 return completionList;

1182}

1183

1184void MLIRTextFile::getCodeActions(const lsp::URIForFile &uri,

1185 const lsp::Range &pos,

1186 const lsp::CodeActionContext &context,

1187 std::vectorlsp::CodeAction &actions) {

1188

1189 for (auto &diag : context.diagnostics) {

1190 if (diag.source != "mlir")

1191 continue;

1192 lsp::Position diagPos = diag.range.start;

1193 MLIRTextFileChunk &chunk = getChunkFor(diagPos);

1194

1195

1196 lsp::CodeAction action;

1197 action.title = "Add expected-* diagnostic checks";

1198 action.kind = lsp::CodeAction::kQuickFix.str();

1199

1200 StringRef severity;

1201 switch (diag.severity) {

1202 case llvm::lsp::DiagnosticSeverity::Error:

1203 severity = "error";

1204 break;

1205 case llvm::lsp::DiagnosticSeverity::Warning:

1206 severity = "warning";

1207 break;

1208 default:

1209 continue;

1210 }

1211

1212

1213 std::vectorllvm::lsp::TextEdit edits;

1214 chunk.document.getCodeActionForDiagnostic(uri, diagPos, severity,

1215 diag.message, edits);

1216

1217

1218 if (diag.relatedInformation) {

1219 for (auto &noteDiag : *diag.relatedInformation) {

1220 if (noteDiag.location.uri != uri)

1221 continue;

1222 diagPos = noteDiag.location.range.start;

1223 diagPos.line -= chunk.lineOffset;

1224 chunk.document.getCodeActionForDiagnostic(uri, diagPos, "note",

1225 noteDiag.message, edits);

1226 }

1227 }

1228

1229 for (llvm::lsp::TextEdit &edit : edits)

1230 chunk.adjustLocForChunkOffset(edit.range);

1231

1232 action.edit.emplace();

1233 action.edit->changes[uri.uri().str()] = std::move(edits);

1234 action.diagnostics = {diag};

1235

1236 actions.emplace_back(std::move(action));

1237 }

1238}

1239

1240llvm::Expectedlsp::MLIRConvertBytecodeResult

1241MLIRTextFile::convertToBytecode() {

1242

1243 if (chunks.size() != 1) {

1244 return llvm::make_errorllvm::lsp::LSPError(

1245 "unexpected split file, please remove all `// -----`",

1246 llvm::lsp::ErrorCode::RequestFailed);

1247 }

1248 return chunks.front()->document.convertToBytecode();

1249}

1250

1251MLIRTextFileChunk &MLIRTextFile::getChunkFor(lsp::Position &pos) {

1252 if (chunks.size() == 1)

1253 return *chunks.front();

1254

1255

1256

1257 auto it = llvm::upper_bound(

1258 chunks, pos, [](const lsp::Position &pos, const auto &chunk) {

1259 return static_cast<uint64_t>(pos.line) < chunk->lineOffset;

1260 });

1261 MLIRTextFileChunk &chunk = it == chunks.end() ? *chunks.back() : **(--it);

1262 pos.line -= chunk.lineOffset;

1263 return chunk;

1264}

1265

1266

1267

1268

1269

1272

1273

1274

1276

1277

1278 llvm::StringMap<std::unique_ptr> files;

1279};

1280

1281

1282

1283

1284

1286 : impl(std::make_unique<Impl>(registryFn)) {}

1288

1290 const URIForFile &uri, StringRef contents, int64_t version,

1291 std::vectorllvm::lsp::Diagnostic &diagnostics) {

1292 impl->files[uri.file()] = std::make_unique(

1293 uri, contents, version, impl->registryFn, diagnostics);

1294}

1295

1297 auto it = impl->files.find(uri.file());

1298 if (it == impl->files.end())

1299 return std::nullopt;

1300

1301 int64_t version = it->second->getVersion();

1302 impl->files.erase(it);

1303 return version;

1304}

1305

1307 const URIForFile &uri, const Position &defPos,

1308 std::vectorllvm::lsp::Location &locations) {

1309 auto fileIt = impl->files.find(uri.file());

1310 if (fileIt != impl->files.end())

1311 fileIt->second->getLocationsOf(uri, defPos, locations);

1312}

1313

1315 const URIForFile &uri, const Position &pos,

1316 std::vectorllvm::lsp::Location &references) {

1317 auto fileIt = impl->files.find(uri.file());

1318 if (fileIt != impl->files.end())

1319 fileIt->second->findReferencesOf(uri, pos, references);

1320}

1321

1323 const Position &hoverPos) {

1324 auto fileIt = impl->files.find(uri.file());

1325 if (fileIt != impl->files.end())

1326 return fileIt->second->findHover(uri, hoverPos);

1327 return std::nullopt;

1328}

1329

1331 const URIForFile &uri, std::vector &symbols) {

1332 auto fileIt = impl->files.find(uri.file());

1333 if (fileIt != impl->files.end())

1334 fileIt->second->findDocumentSymbols(symbols);

1335}

1336

1337lsp::CompletionList

1339 const Position &completePos) {

1340 auto fileIt = impl->files.find(uri.file());

1341 if (fileIt != impl->files.end())

1342 return fileIt->second->getCodeCompletion(uri, completePos);

1343 return CompletionList();

1344}

1345

1347 const CodeActionContext &context,

1348 std::vector &actions) {

1349 auto fileIt = impl->files.find(uri.file());

1350 if (fileIt != impl->files.end())

1351 fileIt->second->getCodeActions(uri, pos, context, actions);

1352}

1353

1358

1359

1360 std::string errorMsg;

1362 &tempContext,

1364

1365

1367

1368

1369 ParserConfig parserConfig(&tempContext, true,

1370 &fallbackResourceMap);

1371

1372

1373 Block parsedBlock;

1374 if (failed(parseSourceFile(uri.file(), &parsedBlock, parserConfig))) {

1375 return llvm::make_errorllvm::lsp::LSPError(

1376 "failed to parse bytecode source file: " + errorMsg,

1377 llvm::lsp::ErrorCode::RequestFailed);

1378 }

1379

1380

1381

1382 if (!llvm::hasSingleElement(parsedBlock)) {

1383 return llvm::make_errorllvm::lsp::LSPError(

1384 "expected bytecode to contain a single top-level operation",

1385 llvm::lsp::ErrorCode::RequestFailed);

1386 }

1387

1388

1390 {

1391

1392

1394 topOp->remove();

1395

1397 nullptr, &fallbackResourceMap);

1398

1399 llvm::raw_string_ostream os(result.output);

1400 topOp->print(os, state);

1401 }

1402 return std::move(result);

1403}

1404

1407 auto fileIt = impl->files.find(uri.file());

1408 if (fileIt == impl->files.end()) {

1409 return llvm::make_errorllvm::lsp::LSPError(

1410 "language server does not contain an entry for this source file",

1411 llvm::lsp::ErrorCode::RequestFailed);

1412 }

1413 return fileIt->second->convertToBytecode();

1414}

static void collectLocationsFromLoc(Location loc, std::vector< lsp::Location > &locations, const lsp::URIForFile &uri)

Collect all of the locations from the given MLIR location that are not contained within the given URI...

Definition MLIRServer.cpp:91

static unsigned getBlockNumber(Block *block)

Given a block, return its position in its parent region.

Definition MLIRServer.cpp:176

static std::optional< unsigned > getResultNumberFromLoc(SMLoc loc)

Given a location pointing to a result, return the result number it refers to or std::nullopt if it re...

Definition MLIRServer.cpp:141

static std::optional< StringRef > getTextFromRange(SMRange range)

Given a source location range, return the text covered by the given range.

Definition MLIRServer.cpp:168

static bool isDefOrUse(const AsmParserState::SMDefinition &def, SMLoc loc, SMRange *overlappedRange=nullptr)

Returns true if the given location is contained by the definition or one of the uses of the given SMD...

Definition MLIRServer.cpp:119

static bool contains(SMRange range, SMLoc loc)

Returns true if the given range contains the given source location.

Definition MLIRServer.cpp:111

static lsp::Diagnostic getLspDiagnoticFromDiag(llvm::SourceMgr &sourceMgr, Diagnostic &diag, const lsp::URIForFile &uri)

Convert the given MLIR diagnostic to the LSP form.

Definition MLIRServer.cpp:199

static std::optional< lsp::Location > getLocationFromLoc(StringRef uriScheme, FileLineColLoc loc)

Returns a language server location from the given MLIR file location.

Definition MLIRServer.cpp:37

static void printDefBlockName(raw_ostream &os, Block *block, SMRange loc={})

Given a block and source location, print the source name of the block to the given output stream.

Definition MLIRServer.cpp:182

static SMRange convertTokenLocToRange(SMLoc loc)

Returns the range of a lexical token given a SMLoc corresponding to the start of an token location.

Definition MLIRServer.cpp:31

static std::string diag(const llvm::Value &value)

void completeDialectName()

iterator_range< AttributeDefIterator > getAttributeAliasDefs() const

Return a range of the AttributeAliasDefinitions held by the current parser state.

iterator_range< BlockDefIterator > getBlockDefs() const

Return a range of the BlockDefinitions held by the current parser state.

const OperationDefinition * getOpDef(Operation *op) const

Return the definition for the given operation, or nullptr if the given operation does not have a defi...

const BlockDefinition * getBlockDef(Block *block) const

Return the definition for the given block, or nullptr if the given block does not have a definition.

iterator_range< OperationDefIterator > getOpDefs() const

Return a range of the OperationDefinitions held by the current parser state.

iterator_range< TypeDefIterator > getTypeAliasDefs() const

Return a range of the TypeAliasDefinitions held by the current parser state.

This class provides management for the lifetime of the state used when printing the IR.

unsigned getArgNumber() const

Returns the number of this argument.

Block represents an ordered list of Operations.

BlockArgument getArgument(unsigned i)

bool hasNoSuccessors()

Returns true if this blocks has no successors.

iterator_range< pred_iterator > getPredecessors()

Region * getParent() const

Provide a 'getParent' method for ilist_node_with_parent methods.

SuccessorRange getSuccessors()

bool hasNoPredecessors()

Return true if this block has no predecessors.

Operation * getParentOp()

Returns the closest surrounding operation that contains this block.

This class contains all of the information necessary to report a diagnostic to the DiagnosticEngine.

A fallback map containing external resources not explicitly handled by another parser/printer.

An instance of this location represents a tuple of file, line number, and column number.

StringAttr getFilename() const

unsigned getColumn() const

WalkResult walk(function_ref< WalkResult(Location)> walkFn)

Walk all of the locations nested directly under, and including, the current.

This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...

MLIRContext is the top-level object for a collection of MLIR operations.

T * getOrLoadDialect()

Get (or create) a dialect for the given derived dialect type.

ArrayRef< RegisteredOperationName > getRegisteredOperations()

Return a sorted array containing the information about all registered operations.

const DialectRegistry & getDialectRegistry()

Return the dialect registry associated with this context.

std::vector< StringRef > getAvailableDialects()

Return information about all available dialects in the registry in this context.

void allowUnregisteredDialects(bool allow=true)

Enables creating operations in unregistered dialects.

Set of flags used to control the behavior of the various IR print methods (e.g.

StringRef getStringRef() const

Return the name of this operation. This always succeeds.

Dialect * getDialect()

Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...

bool hasTrait()

Returns true if the operation was registered with a particular trait, e.g.

OpResult getResult(unsigned idx)

Get the 'idx'th result of this operation.

unsigned getNumRegions()

Returns the number of regions held by this operation.

OperationName getName()

The name of an operation is the key identifier for it.

void print(raw_ostream &os, const OpPrintingFlags &flags={})

MutableArrayRef< Region > getRegions()

Returns the regions held by this operation.

result_range getResults()

This class acts as an owning reference to an op, and will automatically destroy the held op on destru...

This class represents a configuration for the MLIR assembly parser.

This diagnostic handler is a simple RAII class that registers and erases a diagnostic handler on a gi...

Type getType() const

Return the type of this value.

static WalkResult advance()

static WalkResult interrupt()

void addOrUpdateDocument(const URIForFile &uri, StringRef contents, int64_t version, std::vector< Diagnostic > &diagnostics)

Add or update the document, with the provided version, at the given URI.

Definition MLIRServer.cpp:1289

std::optional< int64_t > removeDocument(const URIForFile &uri)

Remove the document with the given uri.

Definition MLIRServer.cpp:1296

void findReferencesOf(const URIForFile &uri, const Position &pos, std::vector< Location > &references)

Find all references of the object pointed at by the given position.

Definition MLIRServer.cpp:1314

void getLocationsOf(const URIForFile &uri, const Position &defPos, std::vector< Location > &locations)

Return the locations of the object pointed at by the given position.

Definition MLIRServer.cpp:1306

std::optional< Hover > findHover(const URIForFile &uri, const Position &hoverPos)

Find a hover description for the given hover position, or std::nullopt if one couldn't be found.

Definition MLIRServer.cpp:1322

llvm::Expected< MLIRConvertBytecodeResult > convertFromBytecode(const URIForFile &uri)

Convert the given bytecode file to the textual format.

Definition MLIRServer.cpp:1355

llvm::Expected< MLIRConvertBytecodeResult > convertToBytecode(const URIForFile &uri)

Convert the given textual file to the bytecode format.

Definition MLIRServer.cpp:1406

CompletionList getCodeCompletion(const URIForFile &uri, const Position &completePos)

Get the code completion list for the position within the given file.

Definition MLIRServer.cpp:1338

void findDocumentSymbols(const URIForFile &uri, std::vector< DocumentSymbol > &symbols)

Find all of the document symbols within the given file.

Definition MLIRServer.cpp:1330

MLIRServer(DialectRegistryFn registry_fn)

Construct a new server with the given dialect registry function.

Definition MLIRServer.cpp:1285

void getCodeActions(const URIForFile &uri, const Range &pos, const CodeActionContext &context, std::vector< CodeAction > &actions)

Get the set of code actions within the file.

Definition MLIRServer.cpp:1346

llvm::function_ref< DialectRegistry &(const llvm::lsp::URIForFile &uri)> DialectRegistryFn

SMRange convertTokenLocToRange(SMLoc loc, StringRef identifierChars="")

Returns the range of a lexical token given a SMLoc corresponding to the start of an token location.

Include the generated interface declarations.

const char *const kDefaultSplitMarker

LogicalResult parseAsmSourceFile(const llvm::SourceMgr &sourceMgr, Block *block, const ParserConfig &config, AsmParserState *asmState=nullptr, AsmParserCodeCompleteContext *codeCompleteContext=nullptr)

This parses the file specified by the indicated SourceMgr and appends parsed operations to the given ...

const FrozenRewritePatternSet GreedyRewriteConfig config

llvm::SetVector< T, Vector, Set, N > SetVector

LogicalResult parseSourceFile(const llvm::SourceMgr &sourceMgr, Block *block, const ParserConfig &config, LocationAttr *sourceFileLoc=nullptr)

This parses the file specified by the indicated SourceMgr and appends parsed operations to the given ...

LogicalResult writeBytecodeToFile(Operation *op, raw_ostream &os, const BytecodeWriterConfig &config={})

Write the bytecode for the given operation to the provided output stream.

This class represents the result of converting between MLIR's bytecode and textual format.

Definition MLIRServer.cpp:1270

lsp::DialectRegistryFn registryFn

The registry factory for containing dialects that can be recognized in parsed .mlir files.

Definition MLIRServer.cpp:1275

llvm::StringMap< std::unique_ptr< MLIRTextFile > > files

The files held by the server, mapped by their URI file name.

Definition MLIRServer.cpp:1278

Impl(lsp::DialectRegistryFn registryFn)

Definition MLIRServer.cpp:1271

StringRef name

The name of the attribute alias.

Attribute value

The value of the alias.

This class represents the information for a block definition within the input file.

Block * block

The block representing this definition.

SMDefinition definition

The source location for the block, i.e.

Operation * op

The operation representing this definition.

This class represents a definition within the source manager, containing it's defining location and l...

SmallVector< SMRange > uses

The source location of all uses of the definition.

SMRange loc

The source location of the definition.

Type value

The value of the alias.

StringRef name

The name of the attribute alias.

Represents a range (offset, size, and stride) where each element of the triple may be dynamic or stat...