brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · be16a1f Raw
91 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H10#define MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H11 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#include <vector>19 20namespace mlir::irdl::detail {21 22/// A dictionary stores a mapping of template variable names to their assigned23/// string values.24using dictionary = llvm::StringMap<llvm::SmallString<8>>;25 26/// Template Code as used by IRDL-to-Cpp.27///28/// For efficiency, produces a bytecode representation of an input template.29///   - LiteralToken: A contiguous stream of characters to be printed30///   - ReplacementToken: A template variable that will be replaced31class Template {32public:33  Template(llvm::StringRef str) {34    bool processingReplacementToken = false;35    while (!str.empty()) {36      auto [token, remainder] = str.split("__");37 38      if (processingReplacementToken) {39        assert(!token.empty() && "replacement name cannot be empty");40        bytecode.emplace_back(ReplacementToken{token});41      } else {42        if (!token.empty())43          bytecode.emplace_back(LiteralToken{token});44      }45 46      processingReplacementToken = !processingReplacementToken;47      str = remainder;48    }49  }50 51  /// Render will apply a dictionary to the Template and send the rendered52  /// result to the specified output stream.53  void render(llvm::raw_ostream &out, const dictionary &replacements) const {54    for (auto instruction : bytecode) {55      if (auto *inst = std::get_if<LiteralToken>(&instruction)) {56        out << inst->text;57        continue;58      }59 60      if (auto *inst = std::get_if<ReplacementToken>(&instruction)) {61        auto replacement = replacements.find(inst->keyName);62#ifndef NDEBUG63        if (replacement == replacements.end()) {64          llvm::errs() << "Missing template key: " << inst->keyName << "\n";65          llvm_unreachable("Missing template key");66        }67#endif68        out << replacement->second;69        continue;70      }71 72      llvm_unreachable("non-exhaustive bytecode visit");73    }74  }75 76private:77  struct LiteralToken {78    llvm::StringRef text;79  };80 81  struct ReplacementToken {82    llvm::StringRef keyName;83  };84 85  std::vector<std::variant<LiteralToken, ReplacementToken>> bytecode;86};87 88} // namespace mlir::irdl::detail89 90#endif // MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H91