aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/utils/TableGen/ClangOpcodesEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/utils/TableGen/ClangOpcodesEmitter.cpp')
-rw-r--r--contrib/llvm-project/clang/utils/TableGen/ClangOpcodesEmitter.cpp198
1 files changed, 110 insertions, 88 deletions
diff --git a/contrib/llvm-project/clang/utils/TableGen/ClangOpcodesEmitter.cpp b/contrib/llvm-project/clang/utils/TableGen/ClangOpcodesEmitter.cpp
index ffeedcdf0ee2..db88c990d5f9 100644
--- a/contrib/llvm-project/clang/utils/TableGen/ClangOpcodesEmitter.cpp
+++ b/contrib/llvm-project/clang/utils/TableGen/ClangOpcodesEmitter.cpp
@@ -21,7 +21,7 @@ using namespace llvm;
namespace {
class ClangOpcodesEmitter {
RecordKeeper &Records;
- Record Root;
+ const Record Root;
unsigned NumTypes;
public:
@@ -34,33 +34,32 @@ public:
private:
/// Emits the opcode name for the opcode enum.
/// The name is obtained by concatenating the name with the list of types.
- void EmitEnum(raw_ostream &OS, StringRef N, Record *R);
+ void EmitEnum(raw_ostream &OS, StringRef N, const Record *R);
/// Emits the switch case and the invocation in the interpreter.
- void EmitInterp(raw_ostream &OS, StringRef N, Record *R);
+ void EmitInterp(raw_ostream &OS, StringRef N, const Record *R);
/// Emits the disassembler.
- void EmitDisasm(raw_ostream &OS, StringRef N, Record *R);
+ void EmitDisasm(raw_ostream &OS, StringRef N, const Record *R);
/// Emits the byte code emitter method.
- void EmitEmitter(raw_ostream &OS, StringRef N, Record *R);
+ void EmitEmitter(raw_ostream &OS, StringRef N, const Record *R);
/// Emits the prototype.
- void EmitProto(raw_ostream &OS, StringRef N, Record *R);
+ void EmitProto(raw_ostream &OS, StringRef N, const Record *R);
/// Emits the prototype to dispatch from a type.
- void EmitGroup(raw_ostream &OS, StringRef N, Record *R);
+ void EmitGroup(raw_ostream &OS, StringRef N, const Record *R);
/// Emits the evaluator method.
- void EmitEval(raw_ostream &OS, StringRef N, Record *R);
+ void EmitEval(raw_ostream &OS, StringRef N, const Record *R);
- void PrintTypes(raw_ostream &OS, ArrayRef<Record *> Types);
+ void PrintTypes(raw_ostream &OS, ArrayRef<const Record *> Types);
};
-void Enumerate(const Record *R,
- StringRef N,
- std::function<void(ArrayRef<Record *>, Twine)> &&F) {
- llvm::SmallVector<Record *, 2> TypePath;
+void Enumerate(const Record *R, StringRef N,
+ std::function<void(ArrayRef<const Record *>, Twine)> &&F) {
+ llvm::SmallVector<const Record *, 2> TypePath;
auto *Types = R->getValueAsListInit("Types");
std::function<void(size_t, const Twine &)> Rec;
@@ -102,67 +101,80 @@ void ClangOpcodesEmitter::run(raw_ostream &OS) {
}
}
-void ClangOpcodesEmitter::EmitEnum(raw_ostream &OS, StringRef N, Record *R) {
+void ClangOpcodesEmitter::EmitEnum(raw_ostream &OS, StringRef N,
+ const Record *R) {
OS << "#ifdef GET_OPCODE_NAMES\n";
- Enumerate(R, N, [&OS](ArrayRef<Record *>, const Twine &ID) {
+ Enumerate(R, N, [&OS](ArrayRef<const Record *>, const Twine &ID) {
OS << "OP_" << ID << ",\n";
});
OS << "#endif\n";
}
-void ClangOpcodesEmitter::EmitInterp(raw_ostream &OS, StringRef N, Record *R) {
+void ClangOpcodesEmitter::EmitInterp(raw_ostream &OS, StringRef N,
+ const Record *R) {
OS << "#ifdef GET_INTERP\n";
- Enumerate(R, N, [this, R, &OS, &N](ArrayRef<Record *> TS, const Twine &ID) {
- bool CanReturn = R->getValueAsBit("CanReturn");
- bool ChangesPC = R->getValueAsBit("ChangesPC");
- auto Args = R->getValueAsListOfDefs("Args");
-
- OS << "case OP_" << ID << ": {\n";
-
- // Emit calls to read arguments.
- for (size_t I = 0, N = Args.size(); I < N; ++I) {
- OS << " auto V" << I;
- OS << " = ";
- OS << "PC.read<" << Args[I]->getValueAsString("Name") << ">();\n";
- }
-
- // Emit a call to the template method and pass arguments.
- OS << " if (!" << N;
- PrintTypes(OS, TS);
- OS << "(S";
- if (ChangesPC)
- OS << ", PC";
- else
- OS << ", OpPC";
- if (CanReturn)
- OS << ", Result";
- for (size_t I = 0, N = Args.size(); I < N; ++I)
- OS << ", V" << I;
- OS << "))\n";
- OS << " return false;\n";
-
- // Bail out if interpreter returned.
- if (CanReturn) {
- OS << " if (!S.Current || S.Current->isRoot())\n";
- OS << " return true;\n";
- }
-
- OS << " continue;\n";
- OS << "}\n";
- });
+ Enumerate(R, N,
+ [this, R, &OS, &N](ArrayRef<const Record *> TS, const Twine &ID) {
+ bool CanReturn = R->getValueAsBit("CanReturn");
+ bool ChangesPC = R->getValueAsBit("ChangesPC");
+ auto Args = R->getValueAsListOfDefs("Args");
+
+ OS << "case OP_" << ID << ": {\n";
+
+ if (CanReturn)
+ OS << " bool DoReturn = (S.Current == StartFrame);\n";
+
+ // Emit calls to read arguments.
+ for (size_t I = 0, N = Args.size(); I < N; ++I) {
+ OS << " auto V" << I;
+ OS << " = ";
+ OS << "ReadArg<" << Args[I]->getValueAsString("Name")
+ << ">(S, PC);\n";
+ }
+
+ // Emit a call to the template method and pass arguments.
+ OS << " if (!" << N;
+ PrintTypes(OS, TS);
+ OS << "(S";
+ if (ChangesPC)
+ OS << ", PC";
+ else
+ OS << ", OpPC";
+ if (CanReturn)
+ OS << ", Result";
+ for (size_t I = 0, N = Args.size(); I < N; ++I)
+ OS << ", V" << I;
+ OS << "))\n";
+ OS << " return false;\n";
+
+ // Bail out if interpreter returned.
+ if (CanReturn) {
+ OS << " if (!S.Current || S.Current->isRoot())\n";
+ OS << " return true;\n";
+
+ OS << " if (DoReturn)\n";
+ OS << " return true;\n";
+ }
+
+ OS << " continue;\n";
+ OS << "}\n";
+ });
OS << "#endif\n";
}
-void ClangOpcodesEmitter::EmitDisasm(raw_ostream &OS, StringRef N, Record *R) {
+void ClangOpcodesEmitter::EmitDisasm(raw_ostream &OS, StringRef N,
+ const Record *R) {
OS << "#ifdef GET_DISASM\n";
- Enumerate(R, N, [R, &OS](ArrayRef<Record *>, const Twine &ID) {
+ Enumerate(R, N, [R, &OS](ArrayRef<const Record *>, const Twine &ID) {
OS << "case OP_" << ID << ":\n";
OS << " PrintName(\"" << ID << "\");\n";
OS << " OS << \"\\t\"";
- for (auto *Arg : R->getValueAsListOfDefs("Args"))
- OS << " << PC.read<" << Arg->getValueAsString("Name") << ">() << \" \"";
+ for (auto *Arg : R->getValueAsListOfDefs("Args")) {
+ OS << " << ReadArg<" << Arg->getValueAsString("Name") << ">(P, PC)";
+ OS << " << \" \"";
+ }
OS << " << \"\\n\";\n";
OS << " continue;\n";
@@ -170,12 +182,13 @@ void ClangOpcodesEmitter::EmitDisasm(raw_ostream &OS, StringRef N, Record *R) {
OS << "#endif\n";
}
-void ClangOpcodesEmitter::EmitEmitter(raw_ostream &OS, StringRef N, Record *R) {
+void ClangOpcodesEmitter::EmitEmitter(raw_ostream &OS, StringRef N,
+ const Record *R) {
if (R->getValueAsBit("HasCustomLink"))
return;
OS << "#ifdef GET_LINK_IMPL\n";
- Enumerate(R, N, [R, &OS](ArrayRef<Record *>, const Twine &ID) {
+ Enumerate(R, N, [R, &OS](ArrayRef<const Record *>, const Twine &ID) {
auto Args = R->getValueAsListOfDefs("Args");
// Emit the list of arguments.
@@ -200,10 +213,11 @@ void ClangOpcodesEmitter::EmitEmitter(raw_ostream &OS, StringRef N, Record *R) {
OS << "#endif\n";
}
-void ClangOpcodesEmitter::EmitProto(raw_ostream &OS, StringRef N, Record *R) {
+void ClangOpcodesEmitter::EmitProto(raw_ostream &OS, StringRef N,
+ const Record *R) {
OS << "#if defined(GET_EVAL_PROTO) || defined(GET_LINK_PROTO)\n";
auto Args = R->getValueAsListOfDefs("Args");
- Enumerate(R, N, [&OS, &Args](ArrayRef<Record *> TS, const Twine &ID) {
+ Enumerate(R, N, [&OS, &Args](ArrayRef<const Record *> TS, const Twine &ID) {
OS << "bool emit" << ID << "(";
for (auto *Arg : Args)
OS << Arg->getValueAsString("Name") << ", ";
@@ -231,16 +245,19 @@ void ClangOpcodesEmitter::EmitProto(raw_ostream &OS, StringRef N, Record *R) {
OS << "#endif\n";
}
-void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N, Record *R) {
+void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N,
+ const Record *R) {
if (!R->getValueAsBit("HasGroup"))
return;
auto *Types = R->getValueAsListInit("Types");
auto Args = R->getValueAsListOfDefs("Args");
+ Twine EmitFuncName = "emit" + N;
+
// Emit the prototype of the group emitter in the header.
OS << "#if defined(GET_EVAL_PROTO) || defined(GET_LINK_PROTO)\n";
- OS << "bool emit" << N << "(";
+ OS << "bool " << EmitFuncName << "(";
for (size_t I = 0, N = Types->size(); I < N; ++I)
OS << "PrimType, ";
for (auto *Arg : Args)
@@ -256,7 +273,7 @@ void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N, Record *R) {
OS << "#else\n";
OS << "ByteCodeEmitter\n";
OS << "#endif\n";
- OS << "::emit" << N << "(";
+ OS << "::" << EmitFuncName << "(";
for (size_t I = 0, N = Types->size(); I < N; ++I)
OS << "PrimType T" << I << ", ";
for (size_t I = 0, N = Args.size(); I < N; ++I)
@@ -264,8 +281,9 @@ void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N, Record *R) {
OS << "const SourceInfo &I) {\n";
std::function<void(size_t, const Twine &)> Rec;
- llvm::SmallVector<Record *, 2> TS;
- Rec = [this, &Rec, &OS, Types, &Args, R, &TS, N](size_t I, const Twine &ID) {
+ llvm::SmallVector<const Record *, 2> TS;
+ Rec = [this, &Rec, &OS, Types, &Args, R, &TS, N,
+ EmitFuncName](size_t I, const Twine &ID) {
if (I >= Types->size()) {
// Print a call to the emitter method.
// Custom evaluator methods dispatch to template methods.
@@ -301,7 +319,8 @@ void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N, Record *R) {
}
// Emit a default case if not all types are present.
if (Cases.size() < NumTypes)
- OS << " default: llvm_unreachable(\"invalid type\");\n";
+ OS << " default: llvm_unreachable(\"invalid type: " << EmitFuncName
+ << "\");\n";
OS << " }\n";
OS << " llvm_unreachable(\"invalid enum value\");\n";
} else {
@@ -314,34 +333,37 @@ void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N, Record *R) {
OS << "#endif\n";
}
-void ClangOpcodesEmitter::EmitEval(raw_ostream &OS, StringRef N, Record *R) {
+void ClangOpcodesEmitter::EmitEval(raw_ostream &OS, StringRef N,
+ const Record *R) {
if (R->getValueAsBit("HasCustomEval"))
return;
OS << "#ifdef GET_EVAL_IMPL\n";
- Enumerate(R, N, [this, R, &N, &OS](ArrayRef<Record *> TS, const Twine &ID) {
- auto Args = R->getValueAsListOfDefs("Args");
-
- OS << "bool EvalEmitter::emit" << ID << "(";
- for (size_t I = 0, N = Args.size(); I < N; ++I)
- OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
- OS << "const SourceInfo &L) {\n";
- OS << " if (!isActive()) return true;\n";
- OS << " CurrentSource = L;\n";
-
- OS << " return " << N;
- PrintTypes(OS, TS);
- OS << "(S, OpPC";
- for (size_t I = 0, N = Args.size(); I < N; ++I)
- OS << ", A" << I;
- OS << ");\n";
- OS << "}\n";
- });
+ Enumerate(R, N,
+ [this, R, &N, &OS](ArrayRef<const Record *> TS, const Twine &ID) {
+ auto Args = R->getValueAsListOfDefs("Args");
+
+ OS << "bool EvalEmitter::emit" << ID << "(";
+ for (size_t I = 0, N = Args.size(); I < N; ++I)
+ OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
+ OS << "const SourceInfo &L) {\n";
+ OS << " if (!isActive()) return true;\n";
+ OS << " CurrentSource = L;\n";
+
+ OS << " return " << N;
+ PrintTypes(OS, TS);
+ OS << "(S, OpPC";
+ for (size_t I = 0, N = Args.size(); I < N; ++I)
+ OS << ", A" << I;
+ OS << ");\n";
+ OS << "}\n";
+ });
OS << "#endif\n";
}
-void ClangOpcodesEmitter::PrintTypes(raw_ostream &OS, ArrayRef<Record *> Types) {
+void ClangOpcodesEmitter::PrintTypes(raw_ostream &OS,
+ ArrayRef<const Record *> Types) {
if (Types.empty())
return;
OS << "<";