aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/GlobalISel/CodeExpander.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/GlobalISel/CodeExpander.cpp')
-rw-r--r--utils/TableGen/GlobalISel/CodeExpander.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/utils/TableGen/GlobalISel/CodeExpander.cpp b/utils/TableGen/GlobalISel/CodeExpander.cpp
new file mode 100644
index 000000000000..d59a9b8e3b65
--- /dev/null
+++ b/utils/TableGen/GlobalISel/CodeExpander.cpp
@@ -0,0 +1,93 @@
+//===- CodeExpander.cpp - Expand variables in a string --------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Expand the variables in a string.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeExpander.h"
+#include "CodeExpansions.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Error.h"
+
+using namespace llvm;
+
+void CodeExpander::emit(raw_ostream &OS) const {
+ StringRef Current = Code;
+
+ while (!Current.empty()) {
+ size_t Pos = Current.find_first_of("$\n\\");
+ if (Pos == StringRef::npos) {
+ OS << Current;
+ Current = "";
+ continue;
+ }
+
+ OS << Current.substr(0, Pos);
+ Current = Current.substr(Pos);
+
+ if (Current.startswith("\n")) {
+ OS << "\n" << Indent;
+ Current = Current.drop_front(1);
+ continue;
+ }
+
+ if (Current.startswith("\\$") || Current.startswith("\\\\")) {
+ OS << Current[1];
+ Current = Current.drop_front(2);
+ continue;
+ }
+
+ if (Current.startswith("\\")) {
+ Current = Current.drop_front(1);
+ continue;
+ }
+
+ if (Current.startswith("${")) {
+ StringRef StartVar = Current;
+ Current = Current.drop_front(2);
+ StringRef Var;
+ std::tie(Var, Current) = Current.split("}");
+
+ // Warn if we split because no terminator was found.
+ StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size());
+ if (EndVar.empty()) {
+ size_t LocOffset = StartVar.data() - Code.data();
+ PrintWarning(
+ Loc.size() > 0 && Loc[0].isValid()
+ ? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
+ : SMLoc(),
+ "Unterminated expansion");
+ }
+
+ auto ValueI = Expansions.find(Var);
+ if (ValueI == Expansions.end()) {
+ size_t LocOffset = StartVar.data() - Code.data();
+ PrintError(Loc.size() > 0 && Loc[0].isValid()
+ ? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
+ : SMLoc(),
+ "Attempting to expand an undeclared variable " + Var);
+ }
+ if (ShowExpansions)
+ OS << "/*$" << Var << "{*/";
+ OS << Expansions.lookup(Var);
+ if (ShowExpansions)
+ OS << "/*}*/";
+ continue;
+ }
+
+ size_t LocOffset = Current.data() - Code.data();
+ PrintWarning(Loc.size() > 0 && Loc[0].isValid()
+ ? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
+ : SMLoc(),
+ "Assuming missing escape character");
+ OS << "$";
+ Current = Current.drop_front(1);
+ }
+}