1//===- TemplatingUtils.h - Templater for text templates -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H
10#define MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H
11
12#include "llvm/ADT/SmallString.h"
13#include "llvm/ADT/StringMap.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/ErrorHandling.h"
16#include "llvm/Support/raw_ostream.h"
17#include <variant>
18
19namespace mlir::irdl::detail {
20
21/// A dictionary stores a mapping of template variable names to their assigned
22/// string values.
23using dictionary = llvm::StringMap<llvm::SmallString<8>>;
24
25/// Template Code as used by IRDL-to-Cpp.
26///
27/// For efficiency, produces a bytecode representation of an input template.
28/// - LiteralToken: A contiguous stream of characters to be printed
29/// - ReplacementToken: A template variable that will be replaced
30class Template {
31public:
32 Template(llvm::StringRef str) {
33 bool processingReplacementToken = false;
34 while (!str.empty()) {
35 auto [token, remainder] = str.split(Separator: "__");
36
37 if (processingReplacementToken) {
38 assert(!token.empty() && "replacement name cannot be empty");
39 bytecode.emplace_back(args: ReplacementToken{.keyName: token});
40 } else {
41 if (!token.empty())
42 bytecode.emplace_back(args: LiteralToken{.text: token});
43 }
44
45 processingReplacementToken = !processingReplacementToken;
46 str = remainder;
47 }
48 }
49
50 /// Render will apply a dictionary to the Template and send the rendered
51 /// result to the specified output stream.
52 void render(llvm::raw_ostream &out, const dictionary &replacements) const {
53 for (auto instruction : bytecode) {
54 if (auto *inst = std::get_if<LiteralToken>(ptr: &instruction)) {
55 out << inst->text;
56 continue;
57 }
58
59 if (auto *inst = std::get_if<ReplacementToken>(ptr: &instruction)) {
60 auto replacement = replacements.find(Key: inst->keyName);
61#ifndef NDEBUG
62 if (replacement == replacements.end()) {
63 llvm::errs() << "Missing template key: " << inst->keyName << "\n";
64 llvm_unreachable("Missing template key");
65 }
66#endif
67 out << replacement->second;
68 continue;
69 }
70
71 llvm_unreachable("non-exhaustive bytecode visit");
72 }
73 }
74
75private:
76 struct LiteralToken {
77 llvm::StringRef text;
78 };
79
80 struct ReplacementToken {
81 llvm::StringRef keyName;
82 };
83
84 std::vector<std::variant<LiteralToken, ReplacementToken>> bytecode;
85};
86
87} // namespace mlir::irdl::detail
88
89#endif // MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H
90

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of mlir/lib/Target/IRDLToCpp/TemplatingUtils.h