summaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/GlobalISel
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/GlobalISel')
-rw-r--r--llvm/utils/TableGen/GlobalISel/CMakeLists.txt7
-rw-r--r--llvm/utils/TableGen/GlobalISel/CodeExpander.cpp93
-rw-r--r--llvm/utils/TableGen/GlobalISel/CodeExpander.h55
-rw-r--r--llvm/utils/TableGen/GlobalISel/CodeExpansions.h43
4 files changed, 198 insertions, 0 deletions
diff --git a/llvm/utils/TableGen/GlobalISel/CMakeLists.txt b/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
new file mode 100644
index 000000000000..2f74d1087bcd
--- /dev/null
+++ b/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
@@ -0,0 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+ Support
+ )
+
+llvm_add_library(LLVMTableGenGlobalISel STATIC DISABLE_LLVM_LINK_LLVM_DYLIB
+ CodeExpander.cpp
+ )
diff --git a/llvm/utils/TableGen/GlobalISel/CodeExpander.cpp b/llvm/utils/TableGen/GlobalISel/CodeExpander.cpp
new file mode 100644
index 000000000000..d59a9b8e3b65
--- /dev/null
+++ b/llvm/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);
+ }
+}
diff --git a/llvm/utils/TableGen/GlobalISel/CodeExpander.h b/llvm/utils/TableGen/GlobalISel/CodeExpander.h
new file mode 100644
index 000000000000..bd6946de5925
--- /dev/null
+++ b/llvm/utils/TableGen/GlobalISel/CodeExpander.h
@@ -0,0 +1,55 @@
+//===- CodeExpander.h - 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_UTILS_TABLEGEN_CODEEXPANDER_H
+#define LLVM_UTILS_TABLEGEN_CODEEXPANDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+class CodeExpansions;
+class raw_ostream;
+
+/// Emit the given code with all '${foo}' placeholders expanded to their
+/// replacements.
+///
+/// It's an error to use an undefined expansion and expansion-like output that
+/// needs to be emitted verbatim can be escaped as '\${foo}'
+///
+/// The emitted code can be given a custom indent to enable both indentation by
+/// an arbitrary amount of whitespace and emission of the code as a comment.
+class CodeExpander {
+ StringRef Code;
+ const CodeExpansions &Expansions;
+ const ArrayRef<SMLoc> &Loc;
+ bool ShowExpansions;
+ StringRef Indent;
+
+public:
+ CodeExpander(StringRef Code, const CodeExpansions &Expansions,
+ const ArrayRef<SMLoc> &Loc, bool ShowExpansions,
+ StringRef Indent = " ")
+ : Code(Code), Expansions(Expansions), Loc(Loc),
+ ShowExpansions(ShowExpansions), Indent(Indent) {}
+
+ void emit(raw_ostream &OS) const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const CodeExpander &Expander) {
+ Expander.emit(OS);
+ return OS;
+}
+} // end namespace llvm
+
+#endif // ifndef LLVM_UTILS_TABLEGEN_CODEEXPANDER_H
diff --git a/llvm/utils/TableGen/GlobalISel/CodeExpansions.h b/llvm/utils/TableGen/GlobalISel/CodeExpansions.h
new file mode 100644
index 000000000000..bb890ec8f57e
--- /dev/null
+++ b/llvm/utils/TableGen/GlobalISel/CodeExpansions.h
@@ -0,0 +1,43 @@
+//===- CodeExpansions.h - Record expansions for CodeExpander --------------===//
+//
+// 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 Record the expansions to use in a CodeExpander.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringMap.h"
+
+#ifndef LLVM_UTILS_TABLEGEN_CODEEXPANSIONS_H
+#define LLVM_UTILS_TABLEGEN_CODEEXPANSIONS_H
+namespace llvm {
+class CodeExpansions {
+public:
+ using const_iterator = StringMap<std::string>::const_iterator;
+
+protected:
+ StringMap<std::string> Expansions;
+
+public:
+ void declare(StringRef Name, StringRef Expansion) {
+ bool Inserted = Expansions.try_emplace(Name, Expansion).second;
+ assert(Inserted && "Declared variable twice");
+ (void)Inserted;
+ }
+
+ std::string lookup(StringRef Variable) const {
+ return Expansions.lookup(Variable);
+ }
+
+ const_iterator begin() const { return Expansions.begin(); }
+ const_iterator end() const { return Expansions.end(); }
+ const_iterator find(StringRef Variable) const {
+ return Expansions.find(Variable);
+ }
+};
+} // end namespace llvm
+#endif // ifndef LLVM_UTILS_TABLEGEN_CODEEXPANSIONS_H