aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-10-01 16:41:13 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2011-10-01 16:41:13 +0000
commit7c788888872233748da10a8177a9a1eb176c1bc8 (patch)
tree2a813c66793364aeb39020c96c9510bb1c4f9cee /utils
parent2e6b97bbf86d0825a060e190189fae7f884c79c9 (diff)
Move TableGen's parser and entry point into a library
This is the first step towards splitting LLVM and Clang's tblgen executables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140951 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/ARMDecoderEmitter.cpp2
-rw-r--r--utils/TableGen/ARMDecoderEmitter.h3
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp4
-rw-r--r--utils/TableGen/AsmMatcherEmitter.h2
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp4
-rw-r--r--utils/TableGen/AsmWriterEmitter.h2
-rw-r--r--utils/TableGen/AsmWriterInst.cpp2
-rw-r--r--utils/TableGen/CMakeLists.txt8
-rw-r--r--utils/TableGen/CallingConvEmitter.cpp2
-rw-r--r--utils/TableGen/CallingConvEmitter.h2
-rw-r--r--utils/TableGen/ClangASTNodesEmitter.h4
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp2
-rw-r--r--utils/TableGen/ClangAttrEmitter.h2
-rw-r--r--utils/TableGen/ClangDiagnosticsEmitter.cpp2
-rw-r--r--utils/TableGen/ClangDiagnosticsEmitter.h2
-rw-r--r--utils/TableGen/ClangSACheckersEmitter.cpp2
-rw-r--r--utils/TableGen/ClangSACheckersEmitter.h2
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp2
-rw-r--r--utils/TableGen/CodeEmitterGen.h2
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp4
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp4
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp2
-rw-r--r--utils/TableGen/CodeGenRegisters.h2
-rw-r--r--utils/TableGen/CodeGenTarget.cpp2
-rw-r--r--utils/TableGen/CodeGenTarget.h2
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp2
-rw-r--r--utils/TableGen/DAGISelEmitter.h2
-rw-r--r--utils/TableGen/DAGISelMatcher.cpp2
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp2
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp2
-rw-r--r--utils/TableGen/DisassemblerEmitter.cpp4
-rw-r--r--utils/TableGen/DisassemblerEmitter.h2
-rw-r--r--utils/TableGen/EDEmitter.cpp2
-rw-r--r--utils/TableGen/EDEmitter.h2
-rw-r--r--utils/TableGen/Error.cpp39
-rw-r--r--utils/TableGen/Error.h43
-rw-r--r--utils/TableGen/FastISelEmitter.cpp4
-rw-r--r--utils/TableGen/FastISelEmitter.h2
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp2
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.h2
-rw-r--r--utils/TableGen/InstrEnumEmitter.cpp2
-rw-r--r--utils/TableGen/InstrEnumEmitter.h2
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp2
-rw-r--r--utils/TableGen/InstrInfoEmitter.h2
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp2
-rw-r--r--utils/TableGen/IntrinsicEmitter.h2
-rw-r--r--utils/TableGen/Makefile2
-rw-r--r--utils/TableGen/NeonEmitter.cpp2
-rw-r--r--utils/TableGen/NeonEmitter.h4
-rw-r--r--utils/TableGen/OptParserEmitter.cpp2
-rw-r--r--utils/TableGen/OptParserEmitter.h2
-rw-r--r--utils/TableGen/PseudoLoweringEmitter.cpp4
-rw-r--r--utils/TableGen/PseudoLoweringEmitter.h2
-rw-r--r--utils/TableGen/Record.cpp2009
-rw-r--r--utils/TableGen/Record.h1656
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp2
-rw-r--r--utils/TableGen/RegisterInfoEmitter.h2
-rw-r--r--utils/TableGen/SetTheory.cpp4
-rw-r--r--utils/TableGen/SubtargetEmitter.cpp2
-rw-r--r--utils/TableGen/SubtargetEmitter.h2
-rw-r--r--utils/TableGen/TGLexer.cpp435
-rw-r--r--utils/TableGen/TGLexer.h125
-rw-r--r--utils/TableGen/TGParser.cpp2163
-rw-r--r--utils/TableGen/TGParser.h122
-rw-r--r--utils/TableGen/TableGen.cpp205
-rw-r--r--utils/TableGen/TableGenBackend.cpp25
-rw-r--r--utils/TableGen/TableGenBackend.h43
-rw-r--r--utils/TableGen/X86DisassemblerTables.cpp2
-rw-r--r--utils/TableGen/X86RecognizableInstr.h2
69 files changed, 129 insertions, 6879 deletions
diff --git a/utils/TableGen/ARMDecoderEmitter.cpp b/utils/TableGen/ARMDecoderEmitter.cpp
index c4bac10cfb..145b96df98 100644
--- a/utils/TableGen/ARMDecoderEmitter.cpp
+++ b/utils/TableGen/ARMDecoderEmitter.cpp
@@ -18,10 +18,10 @@
#include "ARMDecoderEmitter.h"
#include "CodeGenTarget.h"
-#include "Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Record.h"
#include <vector>
#include <map>
diff --git a/utils/TableGen/ARMDecoderEmitter.h b/utils/TableGen/ARMDecoderEmitter.h
index 1faeb91fae..486f899354 100644
--- a/utils/TableGen/ARMDecoderEmitter.h
+++ b/utils/TableGen/ARMDecoderEmitter.h
@@ -15,9 +15,8 @@
#ifndef ARMDECODEREMITTER_H
#define ARMDECODEREMITTER_H
-#include "TableGenBackend.h"
-
#include "llvm/Support/DataTypes.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 6d5d2de201..e43f8311a8 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -98,8 +98,6 @@
#include "AsmMatcherEmitter.h"
#include "CodeGenTarget.h"
-#include "Error.h"
-#include "Record.h"
#include "StringMatcher.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerUnion.h"
@@ -109,6 +107,8 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include <map>
#include <set>
using namespace llvm;
diff --git a/utils/TableGen/AsmMatcherEmitter.h b/utils/TableGen/AsmMatcherEmitter.h
index c13adf3dc5..e04ac103a4 100644
--- a/utils/TableGen/AsmMatcherEmitter.h
+++ b/utils/TableGen/AsmMatcherEmitter.h
@@ -15,7 +15,7 @@
#ifndef ASMMATCHER_EMITTER_H
#define ASMMATCHER_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
namespace llvm {
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 0f011de710..bb91cd0415 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -14,13 +14,13 @@
#include "AsmWriterEmitter.h"
#include "AsmWriterInst.h"
-#include "Error.h"
#include "CodeGenTarget.h"
-#include "Record.h"
#include "StringToOffsetTable.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include <algorithm>
using namespace llvm;
diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h
index 84c925b66e..731e31cc74 100644
--- a/utils/TableGen/AsmWriterEmitter.h
+++ b/utils/TableGen/AsmWriterEmitter.h
@@ -15,7 +15,7 @@
#ifndef ASMWRITER_EMITTER_H
#define ASMWRITER_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <map>
#include <vector>
#include <cassert>
diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp
index fdf447f2aa..350a2ccfcc 100644
--- a/utils/TableGen/AsmWriterInst.cpp
+++ b/utils/TableGen/AsmWriterInst.cpp
@@ -13,8 +13,8 @@
#include "AsmWriterInst.h"
#include "CodeGenTarget.h"
-#include "Record.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/TableGen/Record.h"
using namespace llvm;
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt
index 0202f53c42..9e9a3a1d0d 100644
--- a/utils/TableGen/CMakeLists.txt
+++ b/utils/TableGen/CMakeLists.txt
@@ -25,7 +25,6 @@ add_llvm_utility(tblgen
DAGISelMatcher.cpp
DisassemblerEmitter.cpp
EDEmitter.cpp
- Error.cpp
FastISelEmitter.cpp
FixedLenDecoderEmitter.cpp
InstrEnumEmitter.cpp
@@ -34,21 +33,16 @@ add_llvm_utility(tblgen
NeonEmitter.cpp
OptParserEmitter.cpp
PseudoLoweringEmitter.cpp
- Record.cpp
RegisterInfoEmitter.cpp
SetTheory.cpp
StringMatcher.cpp
SubtargetEmitter.cpp
- TGLexer.cpp
- TGParser.cpp
TGValueTypes.cpp
TableGen.cpp
- TableGenBackend.cpp
X86DisassemblerTables.cpp
X86RecognizableInstr.cpp
)
-
-target_link_libraries(tblgen LLVMSupport)
+target_link_libraries(tblgen LLVMSupport LLVMTableGen)
if( MINGW )
target_link_libraries(tblgen imagehlp psapi)
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp
index c51afd82a3..fcdaa082fb 100644
--- a/utils/TableGen/CallingConvEmitter.cpp
+++ b/utils/TableGen/CallingConvEmitter.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "CallingConvEmitter.h"
-#include "Record.h"
#include "CodeGenTarget.h"
+#include "llvm/TableGen/Record.h"
using namespace llvm;
void CallingConvEmitter::run(raw_ostream &O) {
diff --git a/utils/TableGen/CallingConvEmitter.h b/utils/TableGen/CallingConvEmitter.h
index 431c33bcc0..7bddd6c93e 100644
--- a/utils/TableGen/CallingConvEmitter.h
+++ b/utils/TableGen/CallingConvEmitter.h
@@ -15,7 +15,7 @@
#ifndef CALLINGCONV_EMITTER_H
#define CALLINGCONV_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
namespace llvm {
diff --git a/utils/TableGen/ClangASTNodesEmitter.h b/utils/TableGen/ClangASTNodesEmitter.h
index 712333bd2d..edd9316544 100644
--- a/utils/TableGen/ClangASTNodesEmitter.h
+++ b/utils/TableGen/ClangASTNodesEmitter.h
@@ -14,8 +14,8 @@
#ifndef CLANGAST_EMITTER_H
#define CLANGAST_EMITTER_H
-#include "TableGenBackend.h"
-#include "Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include "llvm/TableGen/Record.h"
#include <string>
#include <cctype>
#include <map>
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 68cd87dcdc..5f25b8fa56 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "ClangAttrEmitter.h"
-#include "Record.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/TableGen/Record.h"
#include <algorithm>
#include <cctype>
diff --git a/utils/TableGen/ClangAttrEmitter.h b/utils/TableGen/ClangAttrEmitter.h
index d6c00d6e23..5acca560f0 100644
--- a/utils/TableGen/ClangAttrEmitter.h
+++ b/utils/TableGen/ClangAttrEmitter.h
@@ -14,7 +14,7 @@
#ifndef CLANGATTR_EMITTER_H
#define CLANGATTR_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index 130f3e1e76..da2fb70b4a 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ClangDiagnosticsEmitter.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/DenseSet.h"
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.h b/utils/TableGen/ClangDiagnosticsEmitter.h
index 1e4c8b70c2..73d3c4dc0e 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.h
+++ b/utils/TableGen/ClangDiagnosticsEmitter.h
@@ -14,7 +14,7 @@
#ifndef CLANGDIAGS_EMITTER_H
#define CLANGDIAGS_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp
index 97739c6b3f..423b68a648 100644
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ClangSACheckersEmitter.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/DenseSet.h"
#include <map>
#include <string>
diff --git a/utils/TableGen/ClangSACheckersEmitter.h b/utils/TableGen/ClangSACheckersEmitter.h
index 6bd1635473..5a0e148111 100644
--- a/utils/TableGen/ClangSACheckersEmitter.h
+++ b/utils/TableGen/ClangSACheckersEmitter.h
@@ -14,7 +14,7 @@
#ifndef CLANGSACHECKERS_EMITTER_H
#define CLANGSACHECKERS_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index 81551a7cfe..c5a152665b 100644
--- a/utils/TableGen/CodeEmitterGen.cpp
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -15,7 +15,7 @@
#include "CodeEmitterGen.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
diff --git a/utils/TableGen/CodeEmitterGen.h b/utils/TableGen/CodeEmitterGen.h
index a874d970fe..7f6ee2a1b4 100644
--- a/utils/TableGen/CodeEmitterGen.h
+++ b/utils/TableGen/CodeEmitterGen.h
@@ -14,7 +14,7 @@
#ifndef CODEMITTERGEN_H
#define CODEMITTERGEN_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <vector>
#include <string>
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index ef6634ea56..4954f33986 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "CodeGenDAGPatterns.h"
-#include "Error.h"
-#include "Record.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index 4b252774f0..53d499f395 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -13,8 +13,8 @@
#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
-#include "Error.h"
-#include "Record.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/STLExtras.h"
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 6e98d0ca91..a5bb5c2e63 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -14,7 +14,7 @@
#include "CodeGenRegisters.h"
#include "CodeGenTarget.h"
-#include "Error.h"
+#include "llvm/TableGen/Error.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index c3af5593c1..f5759b557d 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -15,8 +15,8 @@
#ifndef CODEGEN_REGISTERS_H
#define CODEGEN_REGISTERS_H
-#include "Record.h"
#include "SetTheory.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index e8d376d943..4a7bad7e6d 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -16,7 +16,7 @@
#include "CodeGenTarget.h"
#include "CodeGenIntrinsics.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CommandLine.h"
diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h
index bfd086346c..730216c331 100644
--- a/utils/TableGen/CodeGenTarget.h
+++ b/utils/TableGen/CodeGenTarget.h
@@ -19,7 +19,7 @@
#include "CodeGenRegisters.h"
#include "CodeGenInstruction.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index d66ae96cbc..7db9003499 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -13,7 +13,7 @@
#include "DAGISelEmitter.h"
#include "DAGISelMatcher.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/Support/Debug.h"
using namespace llvm;
diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h
index 35ab550343..9c9fe4273f 100644
--- a/utils/TableGen/DAGISelEmitter.h
+++ b/utils/TableGen/DAGISelEmitter.h
@@ -14,7 +14,7 @@
#ifndef DAGISEL_EMITTER_H
#define DAGISEL_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include "CodeGenDAGPatterns.h"
namespace llvm {
diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp
index b12e1015c3..1367e8dd6e 100644
--- a/utils/TableGen/DAGISelMatcher.cpp
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -10,7 +10,7 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index acb0135422..3b65b2a6de 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -13,7 +13,7 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 85a4266a70..49ad956f88 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -10,7 +10,7 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
#include "CodeGenRegisters.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp
index 24db080b26..ff314e9c4f 100644
--- a/utils/TableGen/DisassemblerEmitter.cpp
+++ b/utils/TableGen/DisassemblerEmitter.cpp
@@ -9,12 +9,12 @@
#include "DisassemblerEmitter.h"
#include "CodeGenTarget.h"
-#include "Error.h"
-#include "Record.h"
#include "X86DisassemblerTables.h"
#include "X86RecognizableInstr.h"
#include "ARMDecoderEmitter.h"
#include "FixedLenDecoderEmitter.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
using namespace llvm;
using namespace llvm::X86Disassembler;
diff --git a/utils/TableGen/DisassemblerEmitter.h b/utils/TableGen/DisassemblerEmitter.h
index 7229d81649..63ee55264a 100644
--- a/utils/TableGen/DisassemblerEmitter.h
+++ b/utils/TableGen/DisassemblerEmitter.h
@@ -10,7 +10,7 @@
#ifndef DISASSEMBLEREMITTER_H
#define DISASSEMBLEREMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index e866487d25..85f7e1f26c 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -17,8 +17,8 @@
#include "AsmWriterInst.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/MC/EDInstInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
diff --git a/utils/TableGen/EDEmitter.h b/utils/TableGen/EDEmitter.h
index e30373fed2..f268375547 100644
--- a/utils/TableGen/EDEmitter.h
+++ b/utils/TableGen/EDEmitter.h
@@ -16,7 +16,7 @@
#ifndef SEMANTIC_INFO_EMITTER_H
#define SEMANTIC_INFO_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/Error.cpp b/utils/TableGen/Error.cpp
deleted file mode 100644
index 3f6cda8977..0000000000
--- a/utils/TableGen/Error.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-//===- Error.cpp - tblgen error handling helper routines --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains error handling helper routines to pretty-print diagnostic
-// messages from tblgen.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Error.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-
-SourceMgr SrcMgr;
-
-void PrintError(SMLoc ErrorLoc, const Twine &Msg) {
- SrcMgr.PrintMessage(ErrorLoc, Msg, "error");
-}
-
-void PrintError(const char *Loc, const Twine &Msg) {
- SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
-}
-
-void PrintError(const Twine &Msg) {
- errs() << "error:" << Msg << "\n";
-}
-
-void PrintError(const TGError &Error) {
- PrintError(Error.getLoc(), Error.getMessage());
-}
-
-} // end namespace llvm
diff --git a/utils/TableGen/Error.h b/utils/TableGen/Error.h
deleted file mode 100644
index b3a0146194..0000000000
--- a/utils/TableGen/Error.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===- Error.h - tblgen error handling helper routines ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains error handling helper routines to pretty-print diagnostic
-// messages from tblgen.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ERROR_H
-#define ERROR_H
-
-#include "llvm/Support/SourceMgr.h"
-
-namespace llvm {
-
-class TGError {
- SMLoc Loc;
- std::string Message;
-public:
- TGError(SMLoc loc, const std::string &message) : Loc(loc), Message(message) {}
-
- SMLoc getLoc() const { return Loc; }
- const std::string &getMessage() const { return Message; }
-};
-
-void PrintError(SMLoc ErrorLoc, const Twine &Msg);
-void PrintError(const char *Loc, const Twine &Msg);
-void PrintError(const Twine &Msg);
-void PrintError(const TGError &Error);
-
-
-extern SourceMgr SrcMgr;
-
-
-} // end namespace "llvm"
-
-#endif
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp
index 66fc9a68ba..9fdc2e33a5 100644
--- a/utils/TableGen/FastISelEmitter.cpp
+++ b/utils/TableGen/FastISelEmitter.cpp
@@ -18,8 +18,8 @@
//===----------------------------------------------------------------------===//
#include "FastISelEmitter.h"
-#include "Error.h"
-#include "Record.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/Debug.h"
diff --git a/utils/TableGen/FastISelEmitter.h b/utils/TableGen/FastISelEmitter.h
index ce4e77e6f8..4f75ac1fd9 100644
--- a/utils/TableGen/FastISelEmitter.h
+++ b/utils/TableGen/FastISelEmitter.h
@@ -14,8 +14,8 @@
#ifndef FASTISEL_EMITTER_H
#define FASTISEL_EMITTER_H
-#include "TableGenBackend.h"
#include "CodeGenDAGPatterns.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
index a3255a06e9..02b966a214 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -16,7 +16,7 @@
#include "FixedLenDecoderEmitter.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/utils/TableGen/FixedLenDecoderEmitter.h b/utils/TableGen/FixedLenDecoderEmitter.h
index 7460f83c69..2df5448aa8 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.h
+++ b/utils/TableGen/FixedLenDecoderEmitter.h
@@ -16,8 +16,8 @@
#define FixedLenDECODEREMITTER_H
#include "CodeGenTarget.h"
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
diff --git a/utils/TableGen/InstrEnumEmitter.cpp b/utils/TableGen/InstrEnumEmitter.cpp
index aa596892f5..5981afde0e 100644
--- a/utils/TableGen/InstrEnumEmitter.cpp
+++ b/utils/TableGen/InstrEnumEmitter.cpp
@@ -14,7 +14,7 @@
#include "InstrEnumEmitter.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include <cstdio>
using namespace llvm;
diff --git a/utils/TableGen/InstrEnumEmitter.h b/utils/TableGen/InstrEnumEmitter.h
index 89f8b659d7..c29a30938d 100644
--- a/utils/TableGen/InstrEnumEmitter.h
+++ b/utils/TableGen/InstrEnumEmitter.h
@@ -15,7 +15,7 @@
#ifndef INSTRENUM_EMITTER_H
#define INSTRENUM_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index 35fe728f9e..8341724a73 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -14,7 +14,7 @@
#include "InstrInfoEmitter.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
using namespace llvm;
diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h
index 165ce423ab..1461e2c5f7 100644
--- a/utils/TableGen/InstrInfoEmitter.h
+++ b/utils/TableGen/InstrInfoEmitter.h
@@ -15,8 +15,8 @@
#ifndef INSTRINFO_EMITTER_H
#define INSTRINFO_EMITTER_H
-#include "TableGenBackend.h"
#include "CodeGenDAGPatterns.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <vector>
#include <map>
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index e5e7cea120..782b89ede2 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -13,8 +13,8 @@
#include "CodeGenTarget.h"
#include "IntrinsicEmitter.h"
-#include "Record.h"
#include "StringMatcher.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
using namespace llvm;
diff --git a/utils/TableGen/IntrinsicEmitter.h b/utils/TableGen/IntrinsicEmitter.h
index b1efecb92e..eb6379cc74 100644
--- a/utils/TableGen/IntrinsicEmitter.h
+++ b/utils/TableGen/IntrinsicEmitter.h
@@ -15,7 +15,7 @@
#define INTRINSIC_EMITTER_H
#include "CodeGenIntrinsics.h"
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
class IntrinsicEmitter : public TableGenBackend {
diff --git a/utils/TableGen/Makefile b/utils/TableGen/Makefile
index c01b6602fa..17e94eacc3 100644
--- a/utils/TableGen/Makefile
+++ b/utils/TableGen/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TOOLNAME = tblgen
-USEDLIBS = LLVMSupport.a
+USEDLIBS = LLVMTableGen.a LLVMSupport.a
REQUIRES_EH := 1
REQUIRES_RTTI := 1
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 1e96da7f64..0b5665fdc2 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -24,7 +24,7 @@
//===----------------------------------------------------------------------===//
#include "NeonEmitter.h"
-#include "Error.h"
+#include "llvm/TableGen/Error.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
diff --git a/utils/TableGen/NeonEmitter.h b/utils/TableGen/NeonEmitter.h
index 12e4e86799..708ad3c06a 100644
--- a/utils/TableGen/NeonEmitter.h
+++ b/utils/TableGen/NeonEmitter.h
@@ -16,8 +16,8 @@
#ifndef NEON_EMITTER_H
#define NEON_EMITTER_H
-#include "Record.h"
-#include "TableGenBackend.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp
index 431026c669..dea22d3886 100644
--- a/utils/TableGen/OptParserEmitter.cpp
+++ b/utils/TableGen/OptParserEmitter.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "OptParserEmitter.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/STLExtras.h"
using namespace llvm;
diff --git a/utils/TableGen/OptParserEmitter.h b/utils/TableGen/OptParserEmitter.h
index 241a3f2b4a..ca667caf43 100644
--- a/utils/TableGen/OptParserEmitter.h
+++ b/utils/TableGen/OptParserEmitter.h
@@ -10,7 +10,7 @@
#ifndef UTILS_TABLEGEN_OPTPARSEREMITTER_H
#define UTILS_TABLEGEN_OPTPARSEREMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
namespace llvm {
/// OptParserEmitter - This tablegen backend takes an input .td file
diff --git a/utils/TableGen/PseudoLoweringEmitter.cpp b/utils/TableGen/PseudoLoweringEmitter.cpp
index db33c1f7f6..c685527a14 100644
--- a/utils/TableGen/PseudoLoweringEmitter.cpp
+++ b/utils/TableGen/PseudoLoweringEmitter.cpp
@@ -8,10 +8,10 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "pseudo-lowering"
-#include "Error.h"
#include "CodeGenInstruction.h"
#include "PseudoLoweringEmitter.h"
-#include "Record.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/utils/TableGen/PseudoLoweringEmitter.h b/utils/TableGen/PseudoLoweringEmitter.h
index 2749280e6a..325bc8be14 100644
--- a/utils/TableGen/PseudoLoweringEmitter.h
+++ b/utils/TableGen/PseudoLoweringEmitter.h
@@ -12,7 +12,7 @@
#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
deleted file mode 100644
index 3d42a5233c..0000000000
--- a/utils/TableGen/Record.cpp
+++ /dev/null
@@ -1,2009 +0,0 @@
-//===- Record.cpp - Record implementation ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implement the tablegen record classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Record.h"
-#include "Error.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
-
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-// std::string wrapper for DenseMap purposes
-//===----------------------------------------------------------------------===//
-
-/// TableGenStringKey - This is a wrapper for std::string suitable for
-/// using as a key to a DenseMap. Because there isn't a particularly
-/// good way to indicate tombstone or empty keys for strings, we want
-/// to wrap std::string to indicate that this is a "special" string
-/// not expected to take on certain values (those of the tombstone and
-/// empty keys). This makes things a little safer as it clarifies
-/// that DenseMap is really not appropriate for general strings.
-
-class TableGenStringKey {
-public:
- TableGenStringKey(const std::string &str) : data(str) {}
- TableGenStringKey(const char *str) : data(str) {}
-
- const std::string &str() const { return data; }
-
-private:
- std::string data;
-};
-
-/// Specialize DenseMapInfo for TableGenStringKey.
-namespace llvm {
-
-template<> struct DenseMapInfo<TableGenStringKey> {
- static inline TableGenStringKey getEmptyKey() {
- TableGenStringKey Empty("<<<EMPTY KEY>>>");
- return Empty;
- }
- static inline TableGenStringKey getTombstoneKey() {
- TableGenStringKey Tombstone("<<<TOMBSTONE KEY>>>");
- return Tombstone;
- }
- static unsigned getHashValue(const TableGenStringKey& Val) {
- return HashString(Val.str());
- }
- static bool isEqual(const TableGenStringKey& LHS,
- const TableGenStringKey& RHS) {
- return LHS.str() == RHS.str();
- }
-};
-
-}
-
-//===----------------------------------------------------------------------===//
-// Type implementations
-//===----------------------------------------------------------------------===//
-
-BitRecTy BitRecTy::Shared;
-IntRecTy IntRecTy::Shared;
-StringRecTy StringRecTy::Shared;
-CodeRecTy CodeRecTy::Shared;
-DagRecTy DagRecTy::Shared;
-
-void RecTy::dump() const { print(errs()); }
-
-ListRecTy *RecTy::getListTy() {
- if (!ListTy)
- ListTy = new ListRecTy(this);
- return ListTy;
-}
-
-Init *BitRecTy::convertValue(BitsInit *BI) {
- if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
- return BI->getBit(0);
-}
-
-bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
- return RHS->getNumBits() == 1;
-}
-
-Init *BitRecTy::convertValue(IntInit *II) {
- int64_t Val = II->getValue();
- if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
-
- return BitInit::get(Val != 0);
-}
-
-Init *BitRecTy::convertValue(TypedInit *VI) {
- if (dynamic_cast<BitRecTy*>(VI->getType()))
- return VI; // Accept variable if it is already of bit type!
- return 0;
-}
-
-BitsRecTy *BitsRecTy::get(unsigned Sz) {
- static std::vector<BitsRecTy*> Shared;
- if (Sz >= Shared.size())
- Shared.resize(Sz + 1);
- BitsRecTy *&Ty = Shared[Sz];
- if (!Ty)
- Ty = new BitsRecTy(Sz);
- return Ty;
-}
-
-std::string BitsRecTy::getAsString() const {
- return "bits<" + utostr(Size) + ">";
-}
-
-Init *BitsRecTy::convertValue(UnsetInit *UI) {
- SmallVector<Init *, 16> NewBits(Size);
-
- for (unsigned i = 0; i != Size; ++i)
- NewBits[i] = UnsetInit::get();
-
- return BitsInit::get(NewBits);
-}
-
-Init *BitsRecTy::convertValue(BitInit *UI) {
- if (Size != 1) return 0; // Can only convert single bit.
- return BitsInit::get(UI);
-}
-
-/// canFitInBitfield - Return true if the number of bits is large enough to hold
-/// the integer value.
-static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
- // For example, with NumBits == 4, we permit Values from [-7 .. 15].
- return (NumBits >= sizeof(Value) * 8) ||
- (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
-}
-
-/// convertValue from Int initializer to bits type: Split the integer up into the
-/// appropriate bits.
-///
-Init *BitsRecTy::convertValue(IntInit *II) {
- int64_t Value = II->getValue();
- // Make sure this bitfield is large enough to hold the integer value.
- if (!canFitInBitfield(Value, Size))
- return 0;
-
- SmallVector<Init *, 16> NewBits(Size);
-
- for (unsigned i = 0; i != Size; ++i)
- NewBits[i] = BitInit::get(Value & (1LL << i));
-
- return BitsInit::get(NewBits);
-}
-
-Init *BitsRecTy::convertValue(BitsInit *BI) {
- // If the number of bits is right, return it. Otherwise we need to expand or
- // truncate.
- if (BI->getNumBits() == Size) return BI;
- return 0;
-}
-
-Init *BitsRecTy::convertValue(TypedInit *VI) {
- if (BitsRecTy *BRT = dynamic_cast<BitsRecTy*>(VI->getType()))
- if (BRT->Size == Size) {
- SmallVector<Init *, 16> NewBits(Size);
-
- for (unsigned i = 0; i != Size; ++i)
- NewBits[i] = VarBitInit::get(VI, i);
- return BitsInit::get(NewBits);
- }
-
- if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType()))
- return BitsInit::get(VI);
-
- if (TernOpInit *Tern = dynamic_cast<TernOpInit*>(VI)) {
- if (Tern->getOpcode() == TernOpInit::IF) {
- Init *LHS = Tern->getLHS();
- Init *MHS = Tern->getMHS();
- Init *RHS = Tern->getRHS();
-
- IntInit *MHSi = dynamic_cast<IntInit*>(MHS);
- IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
-
- if (MHSi && RHSi) {
- int64_t MHSVal = MHSi->getValue();
- int64_t RHSVal = RHSi->getValue();
-
- if (canFitInBitfield(MHSVal, Size) && canFitInBitfield(RHSVal, Size)) {
- SmallVector<Init *, 16> NewBits(Size);
-
- for (unsigned i = 0; i != Size; ++i)
- NewBits[i] =
- TernOpInit::get(TernOpInit::IF, LHS,
- IntInit::get((MHSVal & (1LL << i)) ? 1 : 0),
- IntInit::get((RHSVal & (1LL << i)) ? 1 : 0),
- VI->getType());
-
- return BitsInit::get(NewBits);
- }
- } else {
- BitsInit *MHSbs = dynamic_cast<BitsInit*>(MHS);
- BitsInit *RHSbs = dynamic_cast<BitsInit*>(RHS);
-
- if (MHSbs && RHSbs) {
- SmallVector<Init *, 16> NewBits(Size);
-
- for (unsigned i = 0; i != Size; ++i)
- NewBits[i] = TernOpInit::get(TernOpInit::IF, LHS,
- MHSbs->getBit(i),
- RHSbs->getBit(i),
- VI->getType());
-
- return BitsInit::get(NewBits);
- }
- }
- }
- }
-
- return 0;
-}
-
-Init *IntRecTy::convertValue(BitInit *BI) {
- return IntInit::get(BI->getValue());
-}
-
-Init *IntRecTy::convertValue(BitsInit *BI) {
- int64_t Result = 0;
- for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
- if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
- Result |= Bit->getValue() << i;
- } else {
- return 0;
- }
- return IntInit::get(Result);
-}
-
-Init *IntRecTy::convertValue(TypedInit *TI) {
- if (TI->getType()->typeIsConvertibleTo(this))
- return TI; // Accept variable if already of the right type!
- return 0;
-}
-
-Init *StringRecTy::convertValue(UnOpInit *BO) {
- if (BO->getOpcode() == UnOpInit::CAST) {
- Init *L = BO->getOperand()->convertInitializerTo(this);
- if (L == 0) return 0;
- if (L != BO->getOperand())
- return UnOpInit::get(UnOpInit::CAST, L, new StringRecTy);
- return BO;
- }
-
- return convertValue((TypedInit*)BO);
-}
-
-Init *StringRecTy::convertValue(BinOpInit *BO) {
- if (BO->getOpcode() == BinOpInit::STRCONCAT) {
- Init *L = BO->getLHS()->convertInitializerTo(this);
- Init *R = BO->getRHS()->convertInitializerTo(this);
- if (L == 0 || R == 0) return 0;
- if (L != BO->getLHS() || R != BO->getRHS())
- return BinOpInit::get(BinOpInit::STRCONCAT, L, R, new StringRecTy);
- return BO;
- }
-
- return convertValue((TypedInit*)BO);
-}
-
-
-Init *StringRecTy::convertValue(TypedInit *TI) {
- if (dynamic_cast<StringRecTy*>(TI->getType()))
- return TI; // Accept variable if already of the right type!
- return 0;
-}
-
-std::string ListRecTy::getAsString() const {
- return "list<" + Ty->getAsString() + ">";
-}
-
-Init *ListRecTy::convertValue(ListInit *LI) {
- std::vector<Init*> Elements;
-
- // Verify that all of the elements of the list are subclasses of the
- // appropriate class!
- for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
- if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
- Elements.push_back(CI);
- else
- return 0;
-
- ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
- if (LType == 0) {
- return 0;
- }
-
- return ListInit::get(Elements, this);
-}
-
-Init *ListRecTy::convertValue(TypedInit *TI) {
- // Ensure that TI is compatible with our class.
- if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
- if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
- return TI;
- return 0;
-}
-
-Init *CodeRecTy::convertValue(TypedInit *TI) {
- if (TI->getType()->typeIsConvertibleTo(this))
- return TI;
- return 0;
-}
-
-Init *DagRecTy::convertValue(TypedInit *TI) {
- if (TI->getType()->typeIsConvertibleTo(this))
- return TI;
- return 0;
-}
-
-Init *DagRecTy::convertValue(UnOpInit *BO) {
- if (BO->getOpcode() == UnOpInit::CAST) {
- Init *L = BO->getOperand()->convertInitializerTo(this);
- if (L == 0) return 0;
- if (L != BO->getOperand())
- return UnOpInit::get(UnOpInit::CAST, L, new DagRecTy);
- return BO;
- }
- return 0;
-}
-
-Init *DagRecTy::convertValue(BinOpInit *BO) {
- if (BO->getOpcode() == BinOpInit::CONCAT) {
- Init *L = BO->getLHS()->convertInitializerTo(this);
- Init *R = BO->getRHS()->convertInitializerTo(this);
- if (L == 0 || R == 0) return 0;
- if (L != BO->getLHS() || R != BO->getRHS())
- return BinOpInit::get(BinOpInit::CONCAT, L, R, new DagRecTy);
- return BO;
- }
- return 0;
-}
-
-RecordRecTy *RecordRecTy::get(Record *R) {
- return &dynamic_cast<RecordRecTy&>(*R->getDefInit()->getType());
-}
-
-std::string RecordRecTy::getAsString() const {
- return Rec->getName();
-}
-
-Init *RecordRecTy::convertValue(DefInit *DI) {
- // Ensure that DI is a subclass of Rec.
- if (!DI->getDef()->isSubClassOf(Rec))
- return 0;
- return DI;
-}
-
-Init *RecordRecTy::convertValue(TypedInit *TI) {
- // Ensure that TI is compatible with Rec.
- if (RecordRecTy *RRT = dynamic_cast<RecordRecTy*>(TI->getType()))
- if (RRT->getRecord()->isSubClassOf(getRecord()) ||
- RRT->getRecord() == getRecord())
- return TI;
- return 0;
-}
-
-bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
- if (Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec))
- return true;
-
- const std::vector<Record*> &SC = Rec->getSuperClasses();
- for (unsigned i = 0, e = SC.size(); i != e; ++i)
- if (RHS->getRecord()->isSubClassOf(SC[i]))
- return true;
-
- return false;
-}
-
-
-/// resolveTypes - Find a common type that T1 and T2 convert to.
-/// Return 0 if no such type exists.
-///
-RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
- if (!T1->typeIsConvertibleTo(T2)) {
- if (!T2->typeIsConvertibleTo(T1)) {
- // If one is a Record type, check superclasses
- RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
- if (RecTy1) {
- // See if T2 inherits from a type T1 also inherits from
- const std::vector<Record *> &T1SuperClasses =
- RecTy1->getRecord()->getSuperClasses();
- for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
- iend = T1SuperClasses.end();
- i != iend;
- ++i) {
- RecordRecTy *SuperRecTy1 = RecordRecTy::get(*i);
- RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
- if (NewType1 != 0) {
- if (NewType1 != SuperRecTy1) {
- delete SuperRecTy1;
- }
- return NewType1;
- }
- }
- }
- RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
- if (RecTy2) {
- // See if T1 inherits from a type T2 also inherits from
- const std::vector<Record *> &T2SuperClasses =
- RecTy2->getRecord()->getSuperClasses();
- for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
- iend = T2SuperClasses.end();
- i != iend;
- ++i) {
- RecordRecTy *SuperRecTy2 = RecordRecTy::get(*i);
- RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
- if (NewType2 != 0) {
- if (NewType2 != SuperRecTy2) {
- delete SuperRecTy2;
- }
- return NewType2;
- }
- }
- }
- return 0;
- }
- return T2;
- }
- return T1;
-}
-
-
-//===----------------------------------------------------------------------===//
-// Initializer implementations
-//===----------------------------------------------------------------------===//
-
-void Init::dump() const { return print(errs()); }
-
-UnsetInit *UnsetInit::get() {
- static UnsetInit TheInit;
- return &TheInit;
-}
-
-BitInit *BitInit::get(bool V) {
- static BitInit True(true);
- static BitInit False(false);
-
- return V ? &True : &False;
-}
-
-static void
-ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) {
- ID.AddInteger(Range.size());
-
- for (ArrayRef<Init *>::iterator i = Range.begin(),
- iend = Range.end();
- i != iend;
- ++i)
- ID.AddPointer(*i);
-}
-
-BitsInit *BitsInit::get(ArrayRef<Init *> Range) {
- typedef FoldingSet<BitsInit> Pool;
- static Pool ThePool;
-
- FoldingSetNodeID ID;
- ProfileBitsInit(ID, Range);
-
- void *IP = 0;
- if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
- return I;
-
- BitsInit *I = new BitsInit(Range);
- ThePool.InsertNode(I, IP);
-
- return I;
-}
-
-void BitsInit::Profile(FoldingSetNodeID &ID) const {
- ProfileBitsInit(ID, Bits);
-}
-
-Init *
-BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
- SmallVector<Init *, 16> NewBits(Bits.size());
-
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= getNumBits())
- return 0;
- NewBits[i] = getBit(Bits[i]);
- }
- return BitsInit::get(NewBits);
-}
-
-std::string BitsInit::getAsString() const {
- std::string Result = "{ ";
- for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
- if (i) Result += ", ";
- if (Init *Bit = getBit(e-i-1))
- Result += Bit->getAsString();
- else
- Result += "*";
- }
- return Result + " }";
-}
-
-// resolveReferences - If there are any field references that refer to fields
-// that have been filled in, we can propagate the values now.
-//
-Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const {
- bool Changed = false;
- SmallVector<Init *, 16> NewBits(getNumBits());
-
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- Init *B;
- Init *CurBit = getBit(i);
-
- do {
- B = CurBit;
- CurBit = CurBit->resolveReferences(R, RV);
- Changed |= B != CurBit;
- } while (B != CurBit);
- NewBits[i] = CurBit;
- }
-
- if (Changed)
- return BitsInit::get(NewBits);
-
- return const_cast<BitsInit *>(this);
-}
-
-IntInit *IntInit::get(int64_t V) {
- typedef DenseMap<int64_t, IntInit *> Pool;
- static Pool ThePool;
-
- IntInit *&I = ThePool[V];
- if (!I) I = new IntInit(V);
- return I;
-}
-
-std::string IntInit::getAsString() const {
- return itostr(Value);
-}
-
-Init *
-IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
- SmallVector<Init *, 16> NewBits(Bits.size());
-
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= 64)
- return 0;
-
- NewBits[i] = BitInit::get(Value & (INT64_C(1) << Bits[i]));
- }
- return BitsInit::get(NewBits);
-}
-
-StringInit *StringInit::get(const std::string &V) {
- typedef StringMap<StringInit *> Pool;
- static Pool ThePool;
-
- StringInit *&I = ThePool[V];
- if (!I) I = new StringInit(V);
- return I;
-}
-
-CodeInit *CodeInit::get(const std::string &V) {
- typedef StringMap<CodeInit *> Pool;
- static Pool ThePool;
-
- CodeInit *&I = ThePool[V];
- if (!I) I = new CodeInit(V);
- return I;
-}
-
-static void ProfileListInit(FoldingSetNodeID &ID,
- ArrayRef<Init *> Range,
- RecTy *EltTy) {
- ID.AddInteger(Range.size());
- ID.AddPointer(EltTy);
-
- for (ArrayRef<Init *>::iterator i = Range.begin(),
- iend = Range.end();
- i != iend;
- ++i)
- ID.AddPointer(*i);
-}
-
-ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
- typedef FoldingSet<ListInit> Pool;
- static Pool ThePool;
-
- // Just use the FoldingSetNodeID to compute a hash. Use a DenseMap
- // for actual storage.
- FoldingSetNodeID ID;
- ProfileListInit(ID, Range, EltTy);
-
- void *IP = 0;
- if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
- return I;
-
- ListInit *I = new ListInit(Range, EltTy);
- ThePool.InsertNode(I, IP);
- return I;
-}
-
-void ListInit::Profile(FoldingSetNodeID &ID) const {
- ListRecTy *ListType = dynamic_cast<ListRecTy *>(getType());
- assert(ListType && "Bad type for ListInit!");
- RecTy *EltTy = ListType->getElementType();
-
- ProfileListInit(ID, Values, EltTy);
-}
-
-Init *
-ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
- std::vector<Init*> Vals;
- for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
- if (Elements[i] >= getSize())
- return 0;
- Vals.push_back(getElement(Elements[i]));
- }
- return ListInit::get(Vals, getType());
-}
-
-Record *ListInit::getElementAsRecord(unsigned i) const {
- assert(i < Values.size() && "List element index out of range!");
- DefInit *DI = dynamic_cast<DefInit*>(Values[i]);
- if (DI == 0) throw "Expected record in list!";
- return DI->getDef();
-}
-
-Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) const {
- std::vector<Init*> Resolved;
- Resolved.reserve(getSize());
- bool Changed = false;
-
- for (unsigned i = 0, e = getSize(); i != e; ++i) {
- Init *E;
- Init *CurElt = getElement(i);
-
- do {
- E = CurElt;
- CurElt = CurElt->resolveReferences(R, RV);
- Changed |= E != CurElt;
- } while (E != CurElt);
- Resolved.push_back(E);
- }
-
- if (Changed)
- return ListInit::get(Resolved, getType());
- return const_cast<ListInit *>(this);
-}
-
-Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
- unsigned Elt) const {
- if (Elt >= getSize())
- return 0; // Out of range reference.
- Init *E = getElement(Elt);
- // If the element is set to some value, or if we are resolving a reference
- // to a specific variable and that variable is explicitly unset, then
- // replace the VarListElementInit with it.
- if (IRV || !dynamic_cast<UnsetInit*>(E))
- return E;
- return 0;
-}
-
-std::string ListInit::getAsString() const {
- std::string Result = "[";
- for (unsigned i = 0, e = Values.size(); i != e; ++i) {
- if (i) Result += ", ";
- Result += Values[i]->getAsString();
- }
- return Result + "]";
-}
-
-Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV,
- unsigned Bit) const {
- Init *Folded = Fold(&R, 0);
-
- if (Folded != this) {
- TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
- if (Typed) {
- return Typed->resolveBitReference(R, IRV, Bit);
- }
- }
-
- return 0;
-}
-
-Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
- unsigned Elt) const {
- Init *Folded = Fold(&R, 0);
-
- if (Folded != this) {
- TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
- if (Typed) {
- return Typed->resolveListElementReference(R, IRV, Elt);
- }
- }
-
- return 0;
-}
-
-UnOpInit *UnOpInit::get(UnaryOp opc, Init *lhs, RecTy *Type) {
- typedef std::pair<std::pair<unsigned, Init *>, RecTy *> Key;
-
- typedef DenseMap<Key, UnOpInit *> Pool;
- static Pool ThePool;
-
- Key TheKey(std::make_pair(std::make_pair(opc, lhs), Type));
-
- UnOpInit *&I = ThePool[TheKey];
- if (!I) I = new UnOpInit(opc, lhs, Type);
- return I;
-}
-
-Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
- switch (getOpcode()) {
- default: assert(0 && "Unknown unop");
- case CAST: {
- if (getType()->getAsString() == "string") {
- StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
- if (LHSs) {
- return LHSs;
- }
-
- DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
- if (LHSd) {
- return StringInit::get(LHSd->getDef()->getName());
- }
- } else {
- StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
- if (LHSs) {
- std::string Name = LHSs->getValue();
-
- // From TGParser::ParseIDValue
- if (CurRec) {
- if (const RecordVal *RV = CurRec->getValue(Name)) {
- if (RV->getType() != getType())
- throw "type mismatch in cast";
- return VarInit::get(Name, RV->getType());
- }
-
- std::string TemplateArgName = CurRec->getName()+":"+Name;
- if (CurRec->isTemplateArg(TemplateArgName)) {
- const RecordVal *RV = CurRec->getValue(TemplateArgName);
- assert(RV && "Template arg doesn't exist??");
-
- if (RV->getType() != getType())
- throw "type mismatch in cast";
-
- return VarInit::get(TemplateArgName, RV->getType());
- }
- }
-
- if (CurMultiClass) {
- std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
- if (CurMultiClass->Rec.isTemplateArg(MCName)) {
- const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
- assert(RV && "Template arg doesn't exist??");
-
- if (RV->getType() != getType())
- throw "type mismatch in cast";
-
- return VarInit::get(MCName, RV->getType());
- }
- }
-
- if (Record *D = (CurRec->getRecords()).getDef(Name))
- return DefInit::get(D);
-
- throw TGError(CurRec->getLoc(), "Undefined reference:'" + Name + "'\n");
- }
- }
- break;
- }
- case HEAD: {
- ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
- if (LHSl) {
- if (LHSl->getSize() == 0) {
- assert(0 && "Empty list in car");
- return 0;
- }
- return LHSl->getElement(0);
- }
- break;
- }
- case TAIL: {
- ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
- if (LHSl) {
- if (LHSl->getSize() == 0) {
- assert(0 && "Empty list in cdr");
- return 0;
- }
- // Note the +1. We can't just pass the result of getValues()
- // directly.
- ArrayRef<Init *>::iterator begin = LHSl->getValues().begin()+1;
- ArrayRef<Init *>::iterator end = LHSl->getValues().end();
- ListInit *Result =
- ListInit::get(ArrayRef<Init *>(begin, end - begin),
- LHSl->getType());
- return Result;
- }
- break;
- }
- case EMPTY: {
- ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
- if (LHSl) {
- if (LHSl->getSize() == 0) {
- return IntInit::get(1);
- } else {
- return IntInit::get(0);
- }
- }
- StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
- if (LHSs) {
- if (LHSs->getValue().empty()) {
- return IntInit::get(1);
- } else {
- return IntInit::get(0);
- }
- }
-
- break;
- }
- }
- return const_cast<UnOpInit *>(this);
-}
-
-Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) const {
- Init *lhs = LHS->resolveReferences(R, RV);
-
- if (LHS != lhs)
- return (UnOpInit::get(getOpcode(), lhs, getType()))->Fold(&R, 0);
- return Fold(&R, 0);
-}
-
-std::string UnOpInit::getAsString() const {
- std::string Result;
- switch (Opc) {
- case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
- case HEAD: Result = "!head"; break;
- case TAIL: Result = "!tail"; break;
- case EMPTY: Result = "!empty"; break;
- }
- return Result + "(" + LHS->getAsString() + ")";
-}
-
-BinOpInit *BinOpInit::get(BinaryOp opc, Init *lhs,
- Init *rhs, RecTy *Type) {
- typedef std::pair<
- std::pair<std::pair<unsigned, Init *>, Init *>,
- RecTy *
- > Key;
-
- typedef DenseMap<Key, BinOpInit *> Pool;
- static Pool ThePool;
-
- Key TheKey(std::make_pair(std::make_pair(std::make_pair(opc, lhs), rhs),
- Type));
-
- BinOpInit *&I = ThePool[TheKey];
- if (!I) I = new BinOpInit(opc, lhs, rhs, Type);
- return I;
-}
-
-Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
- switch (getOpcode()) {
- default: assert(0 && "Unknown binop");
- case CONCAT: {
- DagInit *LHSs = dynamic_cast<DagInit*>(LHS);
- DagInit *RHSs = dynamic_cast<DagInit*>(RHS);
- if (LHSs && RHSs) {
- DefInit *LOp = dynamic_cast<DefInit*>(LHSs->getOperator());
- DefInit *ROp = dynamic_cast<DefInit*>(RHSs->getOperator());
- if (LOp == 0 || ROp == 0 || LOp->getDef() != ROp->getDef())
- throw "Concated Dag operators do not match!";
- std::vector<Init*> Args;
- std::vector<std::string> ArgNames;
- for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
- Args.push_back(LHSs->getArg(i));
- ArgNames.push_back(LHSs->getArgName(i));
- }
- for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
- Args.push_back(RHSs->getArg(i));
- ArgNames.push_back(RHSs->getArgName(i));
- }
- return DagInit::get(LHSs->getOperator(), "", Args, ArgNames);
- }
- break;
- }
- case STRCONCAT: {
- StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
- StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
- if (LHSs && RHSs)
- return StringInit::get(LHSs->getValue() + RHSs->getValue());
- break;
- }
- case EQ: {
- // try to fold eq comparison for 'bit' and 'int', otherwise fallback
- // to string objects.
- IntInit* L =
- dynamic_cast<IntInit*>(LHS->convertInitializerTo(IntRecTy::get()));
- IntInit* R =
- dynamic_cast<IntInit*>(RHS->convertInitializerTo(IntRecTy::get()));
-
- if (L && R)
- return IntInit::get(L->getValue() == R->getValue());
-
- StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
- StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
-
- // Make sure we've resolved
- if (LHSs && RHSs)
- return IntInit::get(LHSs->getValue() == RHSs->getValue());
-
- break;
- }
- case SHL:
- case SRA:
- case SRL: {
- IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
- IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
- if (LHSi && RHSi) {
- int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
- int64_t Result;
- switch (getOpcode()) {
- default: assert(0 && "Bad opcode!");
- case SHL: Result = LHSv << RHSv; break;
- case SRA: Result = LHSv >> RHSv; break;
- case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
- }
- return IntInit::get(Result);
- }
- break;
- }
- }
- return const_cast<BinOpInit *>(this);
-}
-
-Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) const {
- Init *lhs = LHS->resolveReferences(R, RV);
- Init *rhs = RHS->resolveReferences(R, RV);
-
- if (LHS != lhs || RHS != rhs)
- return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
- return Fold(&R, 0);
-}
-
-std::string BinOpInit::getAsString() const {
- std::string Result;
- switch (Opc) {
- case CONCAT: Result = "!con"; break;
- case SHL: Result = "!shl"; break;
- case SRA: Result = "!sra"; break;
- case SRL: Result = "!srl"; break;
- case EQ: Result = "!eq"; break;
- case STRCONCAT: Result = "!strconcat"; break;
- }
- return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
-}
-
-TernOpInit *TernOpInit::get(TernaryOp opc, Init *lhs,
- Init *mhs, Init *rhs,
- RecTy *Type) {
- typedef std::pair<
- std::pair<
- std::pair<std::pair<unsigned, RecTy *>, Init *>,
- Init *
- >,
- Init *
- > Key;
-
- typedef DenseMap<Key, TernOpInit *> Pool;
- static Pool ThePool;
-
- Key TheKey(std::make_pair(std::make_pair(std::make_pair(std::make_pair(opc,
- Type),
- lhs),
- mhs),
- rhs));
-
- TernOpInit *&I = ThePool[TheKey];
- if (!I) I = new TernOpInit(opc, lhs, mhs, rhs, Type);
- return I;
-}
-
-static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
- Record *CurRec, MultiClass *CurMultiClass);
-
-static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
- RecTy *Type, Record *CurRec,
- MultiClass *CurMultiClass) {
- std::vector<Init *> NewOperands;
-
- TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
-
- // If this is a dag, recurse
- if (TArg && TArg->getType()->getAsString() == "dag") {
- Init *Result = ForeachHelper(LHS, Arg, RHSo, Type,
- CurRec, CurMultiClass);
- if (Result != 0) {
- return Result;
- } else {
- return 0;
- }
- }
-
- for (int i = 0; i < RHSo->getNumOperands(); ++i) {
- OpInit *RHSoo = dynamic_cast<OpInit*>(RHSo->getOperand(i));
-
- if (RHSoo) {
- Init *Result = EvaluateOperation(RHSoo, LHS, Arg,
- Type, CurRec, CurMultiClass);
- if (Result != 0) {
- NewOperands.push_back(Result);
- } else {
- NewOperands.push_back(Arg);
- }
- } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
- NewOperands.push_back(Arg);
- } else {
- NewOperands.push_back(RHSo->getOperand(i));
- }
- }
-
- // Now run the operator and use its result as the new leaf
- const OpInit *NewOp = RHSo->clone(NewOperands);
- Init *NewVal = NewOp->Fold(CurRec, CurMultiClass);
- if (NewVal != NewOp)
- return NewVal;
-
- return 0;
-}
-
-static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
- Record *CurRec, MultiClass *CurMultiClass) {
- DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
- ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
-
- DagRecTy *DagType = dynamic_cast<DagRecTy*>(Type);
- ListRecTy *ListType = dynamic_cast<ListRecTy*>(Type);
-
- OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
-
- if (!RHSo) {
- throw TGError(CurRec->getLoc(), "!foreach requires an operator\n");
- }
-
- TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
-
- if (!LHSt) {
- throw TGError(CurRec->getLoc(), "!foreach requires typed variable\n");
- }
-
- if ((MHSd && DagType) || (MHSl && ListType)) {
- if (MHSd) {
- Init *Val = MHSd->getOperator();
- Init *Result = EvaluateOperation(RHSo, LHS, Val,
- Type, CurRec, CurMultiClass);
- if (Result != 0) {
- Val = Result;
- }
-
- std::vector<std::pair<Init *, std::string> > args;
- for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
- Init *Arg;
- std::string ArgName;
- Arg = MHSd->getArg(i);
- ArgName = MHSd->getArgName(i);
-
- // Process args
- Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type,
- CurRec, CurMultiClass);
- if (Result != 0) {
- Arg = Result;
- }
-
- // TODO: Process arg names
- args.push_back(std::make_pair(Arg, ArgName));
- }
-
- return DagInit::get(Val, "", args);
- }
- if (MHSl) {
- std::vector<Init *> NewOperands;
- std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
-
- for (std::vector<Init *>::iterator li = NewList.begin(),
- liend = NewList.end();
- li != liend;
- ++li) {
- Init *Item = *li;
- NewOperands.clear();
- for(int i = 0; i < RHSo->getNumOperands(); ++i) {
- // First, replace the foreach variable with the list item
- if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
- NewOperands.push_back(Item);
- } else {
- NewOperands.push_back(RHSo->getOperand(i));
- }
- }
-
- // Now run the operator and use its result as the new list item
- const OpInit *NewOp = RHSo->clone(NewOperands);
- Init *NewItem = NewOp->Fold(CurRec, CurMultiClass);
- if (NewItem != NewOp)
- *li = NewItem;
- }
- return ListInit::get(NewList, MHSl->getType());
- }
- }
- return 0;
-}
-
-Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
- switch (getOpcode()) {
- default: assert(0 && "Unknown binop");
- case SUBST: {
- DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
- VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
- StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
-
- DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
- VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
- StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
-
- DefInit *RHSd = dynamic_cast<DefInit*>(RHS);
- VarInit *RHSv = dynamic_cast<VarInit*>(RHS);
- StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
-
- if ((LHSd && MHSd && RHSd)
- || (LHSv && MHSv && RHSv)
- || (LHSs && MHSs && RHSs)) {
- if (RHSd) {
- Record *Val = RHSd->getDef();
- if (LHSd->getAsString() == RHSd->getAsString()) {
- Val = MHSd->getDef();
- }
- return DefInit::get(Val);
- }
- if (RHSv) {
- std::string Val = RHSv->getName();
- if (LHSv->getAsString() == RHSv->getAsString()) {
- Val = MHSv->getName();
- }
- return VarInit::get(Val, getType());
- }
- if (RHSs) {
- std::string Val = RHSs->getValue();
-
- std::string::size_type found;
- std::string::size_type idx = 0;
- do {
- found = Val.find(LHSs->getValue(), idx);
- if (found != std::string::npos) {
- Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
- }
- idx = found + MHSs->getValue().size();
- } while (found != std::string::npos);
-
- return StringInit::get(Val);
- }
- }
- break;
- }
-
- case FOREACH: {
- Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
- CurRec, CurMultiClass);
- if (Result != 0) {
- return Result;
- }
- break;
- }
-
- case IF: {
- IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
- if (Init *I = LHS->convertInitializerTo(IntRecTy::get()))
- LHSi = dynamic_cast<IntInit*>(I);
- if (LHSi) {
- if (LHSi->getValue()) {
- return MHS;
- } else {
- return RHS;
- }
- }
- break;
- }
- }
-
- return const_cast<TernOpInit *>(this);
-}
-
-Init *TernOpInit::resolveReferences(Record &R,
- const RecordVal *RV) const {
- Init *lhs = LHS->resolveReferences(R, RV);
-
- if (Opc == IF && lhs != LHS) {
- IntInit *Value = dynamic_cast<IntInit*>(lhs);
- if (Init *I = lhs->convertInitializerTo(IntRecTy::get()))
- Value = dynamic_cast<IntInit*>(I);
- if (Value != 0) {
- // Short-circuit
- if (Value->getValue()) {
- Init *mhs = MHS->resolveReferences(R, RV);
- return (TernOpInit::get(getOpcode(), lhs, mhs,
- RHS, getType()))->Fold(&R, 0);
- } else {
- Init *rhs = RHS->resolveReferences(R, RV);
- return (TernOpInit::get(getOpcode(), lhs, MHS,
- rhs, getType()))->Fold(&R, 0);
- }
- }
- }
-
- Init *mhs = MHS->resolveReferences(R, RV);
- Init *rhs = RHS->resolveReferences(R, RV);
-
- if (LHS != lhs || MHS != mhs || RHS != rhs)
- return (TernOpInit::get(getOpcode(), lhs, mhs, rhs,
- getType()))->Fold(&R, 0);
- return Fold(&R, 0);
-}
-
-std::string TernOpInit::getAsString() const {
- std::string Result;
- switch (Opc) {
- case SUBST: Result = "!subst"; break;
- case FOREACH: Result = "!foreach"; break;
- case IF: Result = "!if"; break;
- }
- return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
- + RHS->getAsString() + ")";
-}
-
-RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
- RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
- if (RecordType) {
- RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
- if (Field) {
- return Field->getType();
- }
- }
- return 0;
-}
-
-Init *
-TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
- BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
- if (T == 0) return 0; // Cannot subscript a non-bits variable.
- unsigned NumBits = T->getNumBits();
-
- SmallVector<Init *, 16> NewBits(Bits.size());
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= NumBits)
- return 0;
-
- NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), Bits[i]);
- }
- return BitsInit::get(NewBits);
-}
-
-Init *
-TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
- ListRecTy *T = dynamic_cast<ListRecTy*>(getType());
- if (T == 0) return 0; // Cannot subscript a non-list variable.
-
- if (Elements.size() == 1)
- return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]);
-
- std::vector<Init*> ListInits;
- ListInits.reserve(Elements.size());
- for (unsigned i = 0, e = Elements.size(); i != e; ++i)
- ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this),
- Elements[i]));
- return ListInit::get(ListInits, T);
-}
-
-
-VarInit *VarInit::get(const std::string &VN, RecTy *T) {
- typedef std::pair<RecTy *, TableGenStringKey> Key;
- typedef DenseMap<Key, VarInit *> Pool;
- static Pool ThePool;
-
- Key TheKey(std::make_pair(T, VN));
-
- VarInit *&I = ThePool[TheKey];
- if (!I) I = new VarInit(VN, T);
- return I;
-}
-
-Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
- unsigned Bit) const {
- if (R.isTemplateArg(getName())) return 0;
- if (IRV && IRV->getName() != getName()) return 0;
-
- RecordVal *RV = R.getValue(getName());
- assert(RV && "Reference to a non-existent variable?");
- assert(dynamic_cast<BitsInit*>(RV->getValue()));
- BitsInit *BI = (BitsInit*)RV->getValue();
-
- assert(Bit < BI->getNumBits() && "Bit reference out of range!");
- Init *B = BI->getBit(Bit);
-
- // If the bit is set to some value, or if we are resolving a reference to a
- // specific variable and that variable is explicitly unset, then replace the
- // VarBitInit with it.
- if (IRV || !dynamic_cast<UnsetInit*>(B))
- return B;
- return 0;
-}
-
-Init *VarInit::resolveListElementReference(Record &R,
- const RecordVal *IRV,
- unsigned Elt) const {
- if (R.isTemplateArg(getName())) return 0;
- if (IRV && IRV->getName() != getName()) return 0;
-
- RecordVal *RV = R.getValue(getName());
- assert(RV && "Reference to a non-existent variable?");
- ListInit *LI = dynamic_cast<ListInit*>(RV->getValue());
- if (!LI) {
- VarInit *VI = dynamic_cast<VarInit*>(RV->getValue());
- assert(VI && "Invalid list element!");
- return VarListElementInit::get(VI, Elt);
- }
-
- if (Elt >= LI->getSize())
- return 0; // Out of range reference.
- Init *E = LI->getElement(Elt);
- // If the element is set to some value, or if we are resolving a reference
- // to a specific variable and that variable is explicitly unset, then
- // replace the VarListElementInit with it.
- if (IRV || !dynamic_cast<UnsetInit*>(E))
- return E;
- return 0;
-}
-
-
-RecTy *VarInit::getFieldType(const std::string &FieldName) const {
- if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
- if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
- return RV->getType();
- return 0;
-}
-
-Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const {
- if (dynamic_cast<RecordRecTy*>(getType()))
- if (const RecordVal *Val = R.getValue(VarName)) {
- if (RV != Val && (RV || dynamic_cast<UnsetInit*>(Val->getValue())))
- return 0;
- Init *TheInit = Val->getValue();
- assert(TheInit != this && "Infinite loop detected!");
- if (Init *I = TheInit->getFieldInit(R, RV, FieldName))
- return I;
- else
- return 0;
- }
- return 0;
-}
-
-/// resolveReferences - This method is used by classes that refer to other
-/// variables which may not be defined at the time the expression is formed.
-/// If a value is set for the variable later, this method will be called on
-/// users of the value to allow the value to propagate out.
-///
-Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) const {
- if (RecordVal *Val = R.getValue(VarName))
- if (RV == Val || (RV == 0 && !dynamic_cast<UnsetInit*>(Val->getValue())))
- return Val->getValue();
- return const_cast<VarInit *>(this);
-}
-
-VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) {
- typedef std::pair<TypedInit *, unsigned> Key;
- typedef DenseMap<Key, VarBitInit *> Pool;
-
- static Pool ThePool;
-
- Key TheKey(std::make_pair(T, B));
-
- VarBitInit *&I = ThePool[TheKey];
- if (!I) I = new VarBitInit(T, B);
- return I;
-}
-
-std::string VarBitInit::getAsString() const {
- return TI->getAsString() + "{" + utostr(Bit) + "}";
-}
-
-Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) const {
- if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum()))
- return I;
- return const_cast<VarBitInit *>(this);
-}
-
-VarListElementInit *VarListElementInit::get(TypedInit *T,
- unsigned E) {
- typedef std::pair<TypedInit *, unsigned> Key;
- typedef DenseMap<Key, VarListElementInit *> Pool;
-
- static Pool ThePool;
-
- Key TheKey(std::make_pair(T, E));
-
- VarListElementInit *&I = ThePool[TheKey];
- if (!I) I = new VarListElementInit(T, E);
- return I;
-}
-
-std::string VarListElementInit::getAsString() const {
- return TI->getAsString() + "[" + utostr(Element) + "]";
-}
-
-Init *
-VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) const {
- if (Init *I = getVariable()->resolveListElementReference(R, RV,
- getElementNum()))
- return I;
- return const_cast<VarListElementInit *>(this);
-}
-
-Init *VarListElementInit::resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const {
- // FIXME: This should be implemented, to support references like:
- // bit B = AA[0]{1};
- return 0;
-}
-
-Init *VarListElementInit:: resolveListElementReference(Record &R,
- const RecordVal *RV,
- unsigned Elt) const {
- Init *Result = TI->resolveListElementReference(R, RV, Element);
-
- if (Result) {
- TypedInit *TInit = dynamic_cast<TypedInit *>(Result);
- if (TInit) {
- return TInit->resolveListElementReference(R, RV, Elt);
- }
- return Result;
- }
-
- return 0;
-}
-
-DefInit *DefInit::get(Record *R) {
- return R->getDefInit();
-}
-
-RecTy *DefInit::getFieldType(const std::string &FieldName) const {
- if (const RecordVal *RV = Def->getValue(FieldName))
- return RV->getType();
- return 0;
-}
-
-Init *DefInit::getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const {
- return Def->getValue(FieldName)->getValue();
-}
-
-
-std::string DefInit::getAsString() const {
- return Def->getName();
-}
-
-FieldInit *FieldInit::get(Init *R, const std::string &FN) {
- typedef std::pair<Init *, TableGenStringKey> Key;
- typedef DenseMap<Key, FieldInit *> Pool;
- static Pool ThePool;
-
- Key TheKey(std::make_pair(R, FN));
-
- FieldInit *&I = ThePool[TheKey];
- if (!I) I = new FieldInit(R, FN);
- return I;
-}
-
-Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const {
- if (Init *BitsVal = Rec->getFieldInit(R, RV, FieldName))
- if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
- assert(Bit < BI->getNumBits() && "Bit reference out of range!");
- Init *B = BI->getBit(Bit);
-
- if (dynamic_cast<BitInit*>(B)) // If the bit is set.
- return B; // Replace the VarBitInit with it.
- }
- return 0;
-}
-
-Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const {
- if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName))
- if (ListInit *LI = dynamic_cast<ListInit*>(ListVal)) {
- if (Elt >= LI->getSize()) return 0;
- Init *E = LI->getElement(Elt);
-
- // If the element is set to some value, or if we are resolving a
- // reference to a specific variable and that variable is explicitly
- // unset, then replace the VarListElementInit with it.
- if (RV || !dynamic_cast<UnsetInit*>(E))
- return E;
- }
- return 0;
-}
-
-Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const {
- Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec;
-
- Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName);
- if (BitsVal) {
- Init *BVR = BitsVal->resolveReferences(R, RV);
- return BVR->isComplete() ? BVR : const_cast<FieldInit *>(this);
- }
-
- if (NewRec != Rec) {
- return FieldInit::get(NewRec, FieldName);
- }
- return const_cast<FieldInit *>(this);
-}
-
-void ProfileDagInit(FoldingSetNodeID &ID,
- Init *V,
- const std::string &VN,
- ArrayRef<Init *> ArgRange,
- ArrayRef<std::string> NameRange) {
- ID.AddPointer(V);
- ID.AddString(VN);
-
- ArrayRef<Init *>::iterator Arg = ArgRange.begin();
- ArrayRef<std::string>::iterator Name = NameRange.begin();
- while (Arg != ArgRange.end()) {
- assert(Name != NameRange.end() && "Arg name underflow!");
- ID.AddPointer(*Arg++);
- ID.AddString(*Name++);
- }
- assert(Name == NameRange.end() && "Arg name overflow!");
-}
-
-DagInit *
-DagInit::get(Init *V, const std::string &VN,
- ArrayRef<Init *> ArgRange,
- ArrayRef<std::string> NameRange) {
- typedef FoldingSet<DagInit> Pool;
- static Pool ThePool;
-
- FoldingSetNodeID ID;
- ProfileDagInit(ID, V, VN, ArgRange, NameRange);
-
- void *IP = 0;
- if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
- return I;
-
- DagInit *I = new DagInit(V, VN, ArgRange, NameRange);
- ThePool.InsertNode(I, IP);
-
- return I;
-}
-
-DagInit *
-DagInit::get(Init *V, const std::string &VN,
- const std::vector<std::pair<Init*, std::string> > &args) {
- typedef std::pair<Init*, std::string> PairType;
-
- std::vector<Init *> Args;
- std::vector<std::string> Names;
-
- for (std::vector<PairType>::const_iterator i = args.begin(),
- iend = args.end();
- i != iend;
- ++i) {
- Args.push_back(i->first);
- Names.push_back(i->second);
- }
-
- return DagInit::get(V, VN, Args, Names);
-}
-
-void DagInit::Profile(FoldingSetNodeID &ID) const {
- ProfileDagInit(ID, Val, ValName, Args, ArgNames);
-}
-
-Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const {
- std::vector<Init*> NewArgs;
- for (unsigned i = 0, e = Args.size(); i != e; ++i)
- NewArgs.push_back(Args[i]->resolveReferences(R, RV));
-
- Init *Op = Val->resolveReferences(R, RV);
-
- if (Args != NewArgs || Op != Val)
- return DagInit::get(Op, ValName, NewArgs, ArgNames);
-
- return const_cast<DagInit *>(this);
-}
-
-
-std::string DagInit::getAsString() const {
- std::string Result = "(" + Val->getAsString();
- if (!ValName.empty())
- Result += ":" + ValName;
- if (Args.size()) {
- Result += " " + Args[0]->getAsString();
- if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0];
- for (unsigned i = 1, e = Args.size(); i != e; ++i) {
- Result += ", " + Args[i]->getAsString();
- if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i];
- }
- }
- return Result + ")";
-}
-
-
-//===----------------------------------------------------------------------===//
-// Other implementations
-//===----------------------------------------------------------------------===//
-
-RecordVal::RecordVal(Init *N, RecTy *T, unsigned P)
- : Name(N), Ty(T), Prefix(P) {
- Value = Ty->convertValue(UnsetInit::get());
- assert(Value && "Cannot create unset value for current type!");
-}
-
-RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
- : Name(StringInit::get(N)), Ty(T), Prefix(P) {
- Value = Ty->convertValue(UnsetInit::get());
- assert(Value && "Cannot create unset value for current type!");
-}
-
-const std::string &RecordVal::getName() const {
- StringInit *NameString = dynamic_cast<StringInit *>(Name);
- assert(NameString && "RecordVal name is not a string!");
- return NameString->getValue();
-}
-
-void RecordVal::dump() const { errs() << *this; }
-
-void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
- if (getPrefix()) OS << "field ";
- OS << *getType() << " " << getName();
-
- if (getValue())
- OS << " = " << *getValue();
-
- if (PrintSem) OS << ";\n";
-}
-
-unsigned Record::LastID = 0;
-
-void Record::checkName() {
- // Ensure the record name has string type.
- const TypedInit *TypedName = dynamic_cast<const TypedInit *>(Name);
- assert(TypedName && "Record name is not typed!");
- RecTy *Type = TypedName->getType();
- if (dynamic_cast<StringRecTy *>(Type) == 0) {
- llvm_unreachable("Record name is not a string!");
- }
-}
-
-DefInit *Record::getDefInit() {
- if (!TheInit)
- TheInit = new DefInit(this, new RecordRecTy(this));
- return TheInit;
-}
-
-const std::string &Record::getName() const {
- const StringInit *NameString =
- dynamic_cast<const StringInit *>(Name);
- assert(NameString && "Record name is not a string!");
- return NameString->getValue();
-}
-
-void Record::setName(Init *NewName) {
- if (TrackedRecords.getDef(Name->getAsUnquotedString()) == this) {
- TrackedRecords.removeDef(Name->getAsUnquotedString());
- Name = NewName;
- TrackedRecords.addDef(this);
- } else {
- TrackedRecords.removeClass(Name->getAsUnquotedString());
- Name = NewName;
- TrackedRecords.addClass(this);
- }
- checkName();
- // Since the Init for the name was changed, see if we can resolve
- // any of it using members of the Record.
- Init *ComputedName = Name->resolveReferences(*this, 0);
- if (ComputedName != Name) {
- setName(ComputedName);
- }
- // DO NOT resolve record values to the name at this point because
- // there might be default values for arguments of this def. Those
- // arguments might not have been resolved yet so we don't want to
- // prematurely assume values for those arguments were not passed to
- // this def.
- //
- // Nonetheless, it may be that some of this Record's values
- // reference the record name. Indeed, the reason for having the
- // record name be an Init is to provide this flexibility. The extra
- // resolve steps after completely instantiating defs takes care of
- // this. See TGParser::ParseDef and TGParser::ParseDefm.
-}
-
-void Record::setName(const std::string &Name) {
- setName(StringInit::get(Name));
-}
-
-/// resolveReferencesTo - If anything in this record refers to RV, replace the
-/// reference to RV with the RHS of RV. If RV is null, we resolve all possible
-/// references.
-void Record::resolveReferencesTo(const RecordVal *RV) {
- for (unsigned i = 0, e = Values.size(); i != e; ++i) {
- if (Init *V = Values[i].getValue())
- Values[i].setValue(V->resolveReferences(*this, RV));
- }
-}
-
-void Record::dump() const { errs() << *this; }
-
-raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
- OS << R.getName();
-
- const std::vector<std::string> &TArgs = R.getTemplateArgs();
- if (!TArgs.empty()) {
- OS << "<";
- for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
- if (i) OS << ", ";
- const RecordVal *RV = R.getValue(TArgs[i]);
- assert(RV && "Template argument record not found??");
- RV->print(OS, false);
- }
- OS << ">";
- }
-
- OS << " {";
- const std::vector<Record*> &SC = R.getSuperClasses();
- if (!SC.empty()) {
- OS << "\t//";
- for (unsigned i = 0, e = SC.size(); i != e; ++i)
- OS << " " << SC[i]->getName();
- }
- OS << "\n";
-
- const std::vector<RecordVal> &Vals = R.getValues();
- for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
- OS << Vals[i];
- for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
- OS << Vals[i];
-
- return OS << "}\n";
-}
-
-/// getValueInit - Return the initializer for a value with the specified name,
-/// or throw an exception if the field does not exist.
-///
-Init *Record::getValueInit(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
- return R->getValue();
-}
-
-
-/// getValueAsString - This method looks up the specified field and returns its
-/// value as a string, throwing an exception if the field does not exist or if
-/// the value is not a string.
-///
-std::string Record::getValueAsString(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (StringInit *SI = dynamic_cast<StringInit*>(R->getValue()))
- return SI->getValue();
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a string initializer!";
-}
-
-/// getValueAsBitsInit - This method looks up the specified field and returns
-/// its value as a BitsInit, throwing an exception if the field does not exist
-/// or if the value is not the right type.
-///
-BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (BitsInit *BI = dynamic_cast<BitsInit*>(R->getValue()))
- return BI;
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a BitsInit initializer!";
-}
-
-/// getValueAsListInit - This method looks up the specified field and returns
-/// its value as a ListInit, throwing an exception if the field does not exist
-/// or if the value is not the right type.
-///
-ListInit *Record::getValueAsListInit(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (ListInit *LI = dynamic_cast<ListInit*>(R->getValue()))
- return LI;
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a list initializer!";
-}
-
-/// getValueAsListOfDefs - This method looks up the specified field and returns
-/// its value as a vector of records, throwing an exception if the field does
-/// not exist or if the value is not the right type.
-///
-std::vector<Record*>
-Record::getValueAsListOfDefs(StringRef FieldName) const {
- ListInit *List = getValueAsListInit(FieldName);
- std::vector<Record*> Defs;
- for (unsigned i = 0; i < List->getSize(); i++) {
- if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i))) {
- Defs.push_back(DI->getDef());
- } else {
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' list is not entirely DefInit!";
- }
- }
- return Defs;
-}
-
-/// getValueAsInt - This method looks up the specified field and returns its
-/// value as an int64_t, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-int64_t Record::getValueAsInt(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (IntInit *II = dynamic_cast<IntInit*>(R->getValue()))
- return II->getValue();
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have an int initializer!";
-}
-
-/// getValueAsListOfInts - This method looks up the specified field and returns
-/// its value as a vector of integers, throwing an exception if the field does
-/// not exist or if the value is not the right type.
-///
-std::vector<int64_t>
-Record::getValueAsListOfInts(StringRef FieldName) const {
- ListInit *List = getValueAsListInit(FieldName);
- std::vector<int64_t> Ints;
- for (unsigned i = 0; i < List->getSize(); i++) {
- if (IntInit *II = dynamic_cast<IntInit*>(List->getElement(i))) {
- Ints.push_back(II->getValue());
- } else {
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a list of ints initializer!";
- }
- }
- return Ints;
-}
-
-/// getValueAsListOfStrings - This method looks up the specified field and
-/// returns its value as a vector of strings, throwing an exception if the
-/// field does not exist or if the value is not the right type.
-///
-std::vector<std::string>
-Record::getValueAsListOfStrings(StringRef FieldName) const {
- ListInit *List = getValueAsListInit(FieldName);
- std::vector<std::string> Strings;
- for (unsigned i = 0; i < List->getSize(); i++) {
- if (StringInit *II = dynamic_cast<StringInit*>(List->getElement(i))) {
- Strings.push_back(II->getValue());
- } else {
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a list of strings initializer!";
- }
- }
- return Strings;
-}
-
-/// getValueAsDef - This method looks up the specified field and returns its
-/// value as a Record, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-Record *Record::getValueAsDef(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (DefInit *DI = dynamic_cast<DefInit*>(R->getValue()))
- return DI->getDef();
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a def initializer!";
-}
-
-/// getValueAsBit - This method looks up the specified field and returns its
-/// value as a bit, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-bool Record::getValueAsBit(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (BitInit *BI = dynamic_cast<BitInit*>(R->getValue()))
- return BI->getValue();
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a bit initializer!";
-}
-
-/// getValueAsDag - This method looks up the specified field and returns its
-/// value as an Dag, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-DagInit *Record::getValueAsDag(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (DagInit *DI = dynamic_cast<DagInit*>(R->getValue()))
- return DI;
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a dag initializer!";
-}
-
-std::string Record::getValueAsCode(StringRef FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record `" + getName() + "' does not have a field named `" +
- FieldName.str() + "'!\n";
-
- if (CodeInit *CI = dynamic_cast<CodeInit*>(R->getValue()))
- return CI->getValue();
- throw "Record `" + getName() + "', field `" + FieldName.str() +
- "' does not have a code initializer!";
-}
-
-
-void MultiClass::dump() const {
- errs() << "Record:\n";
- Rec.dump();
-
- errs() << "Defs:\n";
- for (RecordVector::const_iterator r = DefPrototypes.begin(),
- rend = DefPrototypes.end();
- r != rend;
- ++r) {
- (*r)->dump();
- }
-}
-
-
-void RecordKeeper::dump() const { errs() << *this; }
-
-raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
- OS << "------------- Classes -----------------\n";
- const std::map<std::string, Record*> &Classes = RK.getClasses();
- for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
- E = Classes.end(); I != E; ++I)
- OS << "class " << *I->second;
-
- OS << "------------- Defs -----------------\n";
- const std::map<std::string, Record*> &Defs = RK.getDefs();
- for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
- E = Defs.end(); I != E; ++I)
- OS << "def " << *I->second;
- return OS;
-}
-
-
-/// getAllDerivedDefinitions - This method returns all concrete definitions
-/// that derive from the specified class name. If a class with the specified
-/// name does not exist, an error is printed and true is returned.
-std::vector<Record*>
-RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
- Record *Class = getClass(ClassName);
- if (!Class)
- throw "ERROR: Couldn't find the `" + ClassName + "' class!\n";
-
- std::vector<Record*> Defs;
- for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(),
- E = getDefs().end(); I != E; ++I)
- if (I->second->isSubClassOf(Class))
- Defs.push_back(I->second);
-
- return Defs;
-}
-
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
deleted file mode 100644
index 84313e66d5..0000000000
--- a/utils/TableGen/Record.h
+++ /dev/null
@@ -1,1656 +0,0 @@
-
-//===- Record.h - Classes to represent Table Records ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the main TableGen data structures, including the TableGen
-// types, values, and high-level data structures.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef RECORD_H
-#define RECORD_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/raw_ostream.h"
-#include <map>
-
-namespace llvm {
-class raw_ostream;
-
-// RecTy subclasses.
-class BitRecTy;
-class BitsRecTy;
-class IntRecTy;
-class StringRecTy;
-class ListRecTy;
-class CodeRecTy;
-class DagRecTy;
-class RecordRecTy;
-
-// Init subclasses.
-class Init;
-class UnsetInit;
-class BitInit;
-class BitsInit;
-class IntInit;
-class StringInit;
-class CodeInit;
-class ListInit;
-class UnOpInit;
-class BinOpInit;
-class TernOpInit;
-class DefInit;
-class DagInit;
-class TypedInit;
-class VarInit;
-class FieldInit;
-class VarBitInit;
-class VarListElementInit;
-
-// Other classes.
-class Record;
-class RecordVal;
-struct MultiClass;
-class RecordKeeper;
-
-//===----------------------------------------------------------------------===//
-// Type Classes
-//===----------------------------------------------------------------------===//
-
-class RecTy {
- ListRecTy *ListTy;
-public:
- RecTy() : ListTy(0) {}
- virtual ~RecTy() {}
-
- virtual std::string getAsString() const = 0;
- void print(raw_ostream &OS) const { OS << getAsString(); }
- void dump() const;
-
- /// typeIsConvertibleTo - Return true if all values of 'this' type can be
- /// converted to the specified type.
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
-
- /// getListTy - Returns the type representing list<this>.
- ListRecTy *getListTy();
-
-public: // These methods should only be called from subclasses of Init
- virtual Init *convertValue( UnsetInit *UI) { return 0; }
- virtual Init *convertValue( BitInit *BI) { return 0; }
- virtual Init *convertValue( BitsInit *BI) { return 0; }
- virtual Init *convertValue( IntInit *II) { return 0; }
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( UnOpInit *UI) {
- return convertValue((TypedInit*)UI);
- }
- virtual Init *convertValue( BinOpInit *UI) {
- return convertValue((TypedInit*)UI);
- }
- virtual Init *convertValue( TernOpInit *UI) {
- return convertValue((TypedInit*)UI);
- }
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( TypedInit *TI) { return 0; }
- virtual Init *convertValue( VarInit *VI) {
- return convertValue((TypedInit*)VI);
- }
- virtual Init *convertValue( FieldInit *FI) {
- return convertValue((TypedInit*)FI);
- }
-
-public: // These methods should only be called by subclasses of RecTy.
- // baseClassOf - These virtual methods should be overloaded to return true iff
- // all values of type 'RHS' can be converted to the 'this' type.
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
- Ty.print(OS);
- return OS;
-}
-
-
-/// BitRecTy - 'bit' - Represent a single bit
-///
-class BitRecTy : public RecTy {
- static BitRecTy Shared;
- BitRecTy() {}
-public:
- static BitRecTy *get() { return &Shared; }
-
- virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
- virtual Init *convertValue( BitInit *BI) { return (Init*)BI; }
- virtual Init *convertValue( BitsInit *BI);
- virtual Init *convertValue( IntInit *II);
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TypedInit *TI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const { return "bit"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const;
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-
-};
-
-
-// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
-/// BitsRecTy - 'bits&lt;n&gt;' - Represent a fixed number of bits
-///
-class BitsRecTy : public RecTy {
- unsigned Size;
- explicit BitsRecTy(unsigned Sz) : Size(Sz) {}
-public:
- static BitsRecTy *get(unsigned Sz);
-
- unsigned getNumBits() const { return Size; }
-
- virtual Init *convertValue( UnsetInit *UI);
- virtual Init *convertValue( BitInit *UI);
- virtual Init *convertValue( BitsInit *BI);
- virtual Init *convertValue( IntInit *II);
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TypedInit *TI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const;
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const {
- return RHS->Size == Size;
- }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-
-};
-
-
-/// IntRecTy - 'int' - Represent an integer value of no particular size
-///
-class IntRecTy : public RecTy {
- static IntRecTy Shared;
- IntRecTy() {}
-public:
- static IntRecTy *get() { return &Shared; }
-
- virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
- virtual Init *convertValue( BitInit *BI);
- virtual Init *convertValue( BitsInit *BI);
- virtual Init *convertValue( IntInit *II) { return (Init*)II; }
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TypedInit *TI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const { return "int"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
-
- virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-
-};
-
-/// StringRecTy - 'string' - Represent an string value
-///
-class StringRecTy : public RecTy {
- static StringRecTy Shared;
- StringRecTy() {}
-public:
- static StringRecTy *get() { return &Shared; }
-
- virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
- virtual Init *convertValue( BitInit *BI) { return 0; }
- virtual Init *convertValue( BitsInit *BI) { return 0; }
- virtual Init *convertValue( IntInit *II) { return 0; }
- virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( UnOpInit *BO);
- virtual Init *convertValue( BinOpInit *BO);
- virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
-
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( TypedInit *TI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const { return "string"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
-
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-};
-
-// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
-// the specified type.
-/// ListRecTy - 'list&lt;Ty&gt;' - Represent a list of values, all of which must
-/// be of the specified type.
-///
-class ListRecTy : public RecTy {
- RecTy *Ty;
- explicit ListRecTy(RecTy *T) : Ty(T) {}
- friend ListRecTy *RecTy::getListTy();
-public:
- static ListRecTy *get(RecTy *T) { return T->getListTy(); }
- RecTy *getElementType() const { return Ty; }
-
- virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
- virtual Init *convertValue( BitInit *BI) { return 0; }
- virtual Init *convertValue( BitsInit *BI) { return 0; }
- virtual Init *convertValue( IntInit *II) { return 0; }
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI);
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TypedInit *TI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const;
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
-
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const {
- return RHS->getElementType()->typeIsConvertibleTo(Ty);
- }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-};
-
-/// CodeRecTy - 'code' - Represent an code fragment, function or method.
-///
-class CodeRecTy : public RecTy {
- static CodeRecTy Shared;
- CodeRecTy() {}
-public:
- static CodeRecTy *get() { return &Shared; }
-
- virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
- virtual Init *convertValue( BitInit *BI) { return 0; }
- virtual Init *convertValue( BitsInit *BI) { return 0; }
- virtual Init *convertValue( IntInit *II) { return 0; }
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( CodeInit *CI) { return (Init*)CI; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TypedInit *TI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const { return "code"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-};
-
-/// DagRecTy - 'dag' - Represent a dag fragment
-///
-class DagRecTy : public RecTy {
- static DagRecTy Shared;
- DagRecTy() {}
-public:
- static DagRecTy *get() { return &Shared; }
-
- virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
- virtual Init *convertValue( BitInit *BI) { return 0; }
- virtual Init *convertValue( BitsInit *BI) { return 0; }
- virtual Init *convertValue( IntInit *II) { return 0; }
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( UnOpInit *BO);
- virtual Init *convertValue( BinOpInit *BO);
- virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
- virtual Init *convertValue( DagInit *CI) { return (Init*)CI; }
- virtual Init *convertValue( TypedInit *TI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const { return "dag"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
-
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-};
-
-
-/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
-/// (R32 X = EAX).
-///
-class RecordRecTy : public RecTy {
- Record *Rec;
- explicit RecordRecTy(Record *R) : Rec(R) {}
- friend class Record;
-public:
- static RecordRecTy *get(Record *R);
-
- Record *getRecord() const { return Rec; }
-
- virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
- virtual Init *convertValue( BitInit *BI) { return 0; }
- virtual Init *convertValue( BitsInit *BI) { return 0; }
- virtual Init *convertValue( IntInit *II) { return 0; }
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
- virtual Init *convertValue( DefInit *DI);
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( TypedInit *VI);
- virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
- virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
-
- std::string getAsString() const;
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const;
-};
-
-/// resolveTypes - Find a common type that T1 and T2 convert to.
-/// Return 0 if no such type exists.
-///
-RecTy *resolveTypes(RecTy *T1, RecTy *T2);
-
-//===----------------------------------------------------------------------===//
-// Initializer Classes
-//===----------------------------------------------------------------------===//
-
-class Init {
- Init(const Init &); // Do not define.
- Init &operator=(const Init &); // Do not define.
-
-protected:
- Init(void) {}
-
-public:
- virtual ~Init() {}
-
- /// isComplete - This virtual method should be overridden by values that may
- /// not be completely specified yet.
- virtual bool isComplete() const { return true; }
-
- /// print - Print out this value.
- void print(raw_ostream &OS) const { OS << getAsString(); }
-
- /// getAsString - Convert this value to a string form.
- virtual std::string getAsString() const = 0;
- /// getAsUnquotedString - Convert this value to a string form,
- /// without adding quote markers. This primaruly affects
- /// StringInits where we will not surround the string value with
- /// quotes.
- virtual std::string getAsUnquotedString() const { return getAsString(); }
-
- /// dump - Debugging method that may be called through a debugger, just
- /// invokes print on stderr.
- void dump() const;
-
- /// convertInitializerTo - This virtual function is a simple call-back
- /// function that should be overridden to call the appropriate
- /// RecTy::convertValue method.
- ///
- virtual Init *convertInitializerTo(RecTy *Ty) const = 0;
-
- /// convertInitializerBitRange - This method is used to implement the bitrange
- /// selection operator. Given an initializer, it selects the specified bits
- /// out, returning them as a new init of bits type. If it is not legal to use
- /// the bit subscript operator on this initializer, return null.
- ///
- virtual Init *
- convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
- return 0;
- }
-
- /// convertInitListSlice - This method is used to implement the list slice
- /// selection operator. Given an initializer, it selects the specified list
- /// elements, returning them as a new init of list type. If it is not legal
- /// to take a slice of this, return null.
- ///
- virtual Init *
- convertInitListSlice(const std::vector<unsigned> &Elements) const {
- return 0;
- }
-
- /// getFieldType - This method is used to implement the FieldInit class.
- /// Implementors of this method should return the type of the named field if
- /// they are of record type.
- ///
- virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
-
- /// getFieldInit - This method complements getFieldType to return the
- /// initializer for the specified field. If getFieldType returns non-null
- /// this method should return non-null, otherwise it returns null.
- ///
- virtual Init *getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const {
- return 0;
- }
-
- /// resolveReferences - This method is used by classes that refer to other
- /// variables which may not be defined at the time the expression is formed.
- /// If a value is set for the variable later, this method will be called on
- /// users of the value to allow the value to propagate out.
- ///
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const {
- return const_cast<Init *>(this);
- }
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
- I.print(OS); return OS;
-}
-
-/// TypedInit - This is the common super-class of types that have a specific,
-/// explicit, type.
-///
-class TypedInit : public Init {
- RecTy *Ty;
-
- TypedInit(const TypedInit &Other); // Do not define.
- TypedInit &operator=(const TypedInit &Other); // Do not define.
-
-protected:
- explicit TypedInit(RecTy *T) : Ty(T) {}
-
-public:
- RecTy *getType() const { return Ty; }
-
- virtual Init *
- convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
- virtual Init *
- convertInitListSlice(const std::vector<unsigned> &Elements) const;
-
- /// getFieldType - This method is used to implement the FieldInit class.
- /// Implementors of this method should return the type of the named field if
- /// they are of record type.
- ///
- virtual RecTy *getFieldType(const std::string &FieldName) const;
-
- /// resolveBitReference - This method is used to implement
- /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
- /// simply return the resolved value, otherwise we return null.
- ///
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const = 0;
-
- /// resolveListElementReference - This method is used to implement
- /// VarListElementInit::resolveReferences. If the list element is resolvable
- /// now, we return the resolved value, otherwise we return null.
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const = 0;
-};
-
-
-/// UnsetInit - ? - Represents an uninitialized value
-///
-class UnsetInit : public Init {
- UnsetInit() : Init() {}
- UnsetInit(const UnsetInit &); // Do not define.
- UnsetInit &operator=(const UnsetInit &Other); // Do not define.
-
-public:
- static UnsetInit *get();
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<UnsetInit *>(this));
- }
-
- virtual bool isComplete() const { return false; }
- virtual std::string getAsString() const { return "?"; }
-};
-
-
-/// BitInit - true/false - Represent a concrete initializer for a bit.
-///
-class BitInit : public Init {
- bool Value;
-
- explicit BitInit(bool V) : Value(V) {}
- BitInit(const BitInit &Other); // Do not define.
- BitInit &operator=(BitInit &Other); // Do not define.
-
-public:
- static BitInit *get(bool V);
-
- bool getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<BitInit *>(this));
- }
-
- virtual std::string getAsString() const { return Value ? "1" : "0"; }
-};
-
-/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
-/// It contains a vector of bits, whose size is determined by the type.
-///
-class BitsInit : public Init, public FoldingSetNode {
- std::vector<Init*> Bits;
-
- BitsInit(ArrayRef<Init *> Range) : Bits(Range.begin(), Range.end()) {}
-
- BitsInit(const BitsInit &Other); // Do not define.
- BitsInit &operator=(const BitsInit &Other); // Do not define.
-
-public:
- static BitsInit *get(ArrayRef<Init *> Range);
-
- void Profile(FoldingSetNodeID &ID) const;
-
- unsigned getNumBits() const { return Bits.size(); }
-
- Init *getBit(unsigned Bit) const {
- assert(Bit < Bits.size() && "Bit index out of range!");
- return Bits[Bit];
- }
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<BitsInit *>(this));
- }
- virtual Init *
- convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
-
- virtual bool isComplete() const {
- for (unsigned i = 0; i != getNumBits(); ++i)
- if (!getBit(i)->isComplete()) return false;
- return true;
- }
- bool allInComplete() const {
- for (unsigned i = 0; i != getNumBits(); ++i)
- if (getBit(i)->isComplete()) return false;
- return true;
- }
- virtual std::string getAsString() const;
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-};
-
-
-/// IntInit - 7 - Represent an initalization by a literal integer value.
-///
-class IntInit : public TypedInit {
- int64_t Value;
-
- explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {}
-
- IntInit(const IntInit &Other); // Do not define.
- IntInit &operator=(const IntInit &Other); // Do note define.
-
-public:
- static IntInit *get(int64_t V);
-
- int64_t getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<IntInit *>(this));
- }
- virtual Init *
- convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
-
- virtual std::string getAsString() const;
-
- /// resolveBitReference - This method is used to implement
- /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
- /// simply return the resolved value, otherwise we return null.
- ///
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const {
- assert(0 && "Illegal bit reference off int");
- return 0;
- }
-
- /// resolveListElementReference - This method is used to implement
- /// VarListElementInit::resolveReferences. If the list element is resolvable
- /// now, we return the resolved value, otherwise we return null.
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const {
- assert(0 && "Illegal element reference off int");
- return 0;
- }
-};
-
-
-/// StringInit - "foo" - Represent an initialization by a string value.
-///
-class StringInit : public TypedInit {
- std::string Value;
-
- explicit StringInit(const std::string &V)
- : TypedInit(StringRecTy::get()), Value(V) {}
-
- StringInit(const StringInit &Other); // Do not define.
- StringInit &operator=(const StringInit &Other); // Do not define.
-
-public:
- static StringInit *get(const std::string &V);
-
- const std::string &getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<StringInit *>(this));
- }
-
- virtual std::string getAsString() const { return "\"" + Value + "\""; }
- virtual std::string getAsUnquotedString() const { return Value; }
-
- /// resolveBitReference - This method is used to implement
- /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
- /// simply return the resolved value, otherwise we return null.
- ///
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const {
- assert(0 && "Illegal bit reference off string");
- return 0;
- }
-
- /// resolveListElementReference - This method is used to implement
- /// VarListElementInit::resolveReferences. If the list element is resolvable
- /// now, we return the resolved value, otherwise we return null.
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const {
- assert(0 && "Illegal element reference off string");
- return 0;
- }
-};
-
-/// CodeInit - "[{...}]" - Represent a code fragment.
-///
-class CodeInit : public Init {
- std::string Value;
-
- explicit CodeInit(const std::string &V) : Value(V) {}
-
- CodeInit(const CodeInit &Other); // Do not define.
- CodeInit &operator=(const CodeInit &Other); // Do not define.
-
-public:
- static CodeInit *get(const std::string &V);
-
- const std::string &getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<CodeInit *>(this));
- }
-
- virtual std::string getAsString() const { return "[{" + Value + "}]"; }
-};
-
-/// ListInit - [AL, AH, CL] - Represent a list of defs
-///
-class ListInit : public TypedInit, public FoldingSetNode {
- std::vector<Init*> Values;
-public:
- typedef std::vector<Init*>::const_iterator const_iterator;
-
-private:
- explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy)
- : TypedInit(ListRecTy::get(EltTy)), Values(Range.begin(), Range.end()) {}
-
- ListInit(const ListInit &Other); // Do not define.
- ListInit &operator=(const ListInit &Other); // Do not define.
-
-public:
- static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy);
-
- void Profile(FoldingSetNodeID &ID) const;
-
- unsigned getSize() const { return Values.size(); }
- Init *getElement(unsigned i) const {
- assert(i < Values.size() && "List element index out of range!");
- return Values[i];
- }
-
- Record *getElementAsRecord(unsigned i) const;
-
- Init *convertInitListSlice(const std::vector<unsigned> &Elements) const;
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<ListInit *>(this));
- }
-
- /// resolveReferences - This method is used by classes that refer to other
- /// variables which may not be defined at the time they expression is formed.
- /// If a value is set for the variable later, this method will be called on
- /// users of the value to allow the value to propagate out.
- ///
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-
- virtual std::string getAsString() const;
-
- ArrayRef<Init*> getValues() const { return Values; }
-
- inline const_iterator begin() const { return Values.begin(); }
- inline const_iterator end () const { return Values.end(); }
-
- inline size_t size () const { return Values.size(); }
- inline bool empty() const { return Values.empty(); }
-
- /// resolveBitReference - This method is used to implement
- /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
- /// simply return the resolved value, otherwise we return null.
- ///
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const {
- assert(0 && "Illegal bit reference off list");
- return 0;
- }
-
- /// resolveListElementReference - This method is used to implement
- /// VarListElementInit::resolveReferences. If the list element is resolvable
- /// now, we return the resolved value, otherwise we return null.
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const;
-};
-
-
-/// OpInit - Base class for operators
-///
-class OpInit : public TypedInit {
- OpInit(const OpInit &Other); // Do not define.
- OpInit &operator=(OpInit &Other); // Do not define.
-
-protected:
- explicit OpInit(RecTy *Type) : TypedInit(Type) {}
-
-public:
- // Clone - Clone this operator, replacing arguments with the new list
- virtual OpInit *clone(std::vector<Init *> &Operands) const = 0;
-
- virtual int getNumOperands() const = 0;
- virtual Init *getOperand(int i) const = 0;
-
- // Fold - If possible, fold this to a simpler init. Return this if not
- // possible to fold.
- virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<OpInit *>(this));
- }
-
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const;
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const;
-};
-
-
-/// UnOpInit - !op (X) - Transform an init.
-///
-class UnOpInit : public OpInit {
-public:
- enum UnaryOp { CAST, HEAD, TAIL, EMPTY };
-private:
- UnaryOp Opc;
- Init *LHS;
-
- UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
- : OpInit(Type), Opc(opc), LHS(lhs) {}
-
- UnOpInit(const UnOpInit &Other); // Do not define.
- UnOpInit &operator=(const UnOpInit &Other); // Do not define.
-
-public:
- static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type);
-
- // Clone - Clone this operator, replacing arguments with the new list
- virtual OpInit *clone(std::vector<Init *> &Operands) const {
- assert(Operands.size() == 1 &&
- "Wrong number of operands for unary operation");
- return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
- }
-
- int getNumOperands() const { return 1; }
- Init *getOperand(int i) const {
- assert(i == 0 && "Invalid operand id for unary operator");
- return getOperand();
- }
-
- UnaryOp getOpcode() const { return Opc; }
- Init *getOperand() const { return LHS; }
-
- // Fold - If possible, fold this to a simpler init. Return this if not
- // possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-
- virtual std::string getAsString() const;
-};
-
-/// BinOpInit - !op (X, Y) - Combine two inits.
-///
-class BinOpInit : public OpInit {
-public:
- enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
-private:
- BinaryOp Opc;
- Init *LHS, *RHS;
-
- BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
- OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {}
-
- BinOpInit(const BinOpInit &Other); // Do not define.
- BinOpInit &operator=(const BinOpInit &Other); // Do not define.
-
-public:
- static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
- RecTy *Type);
-
- // Clone - Clone this operator, replacing arguments with the new list
- virtual OpInit *clone(std::vector<Init *> &Operands) const {
- assert(Operands.size() == 2 &&
- "Wrong number of operands for binary operation");
- return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
- }
-
- int getNumOperands() const { return 2; }
- Init *getOperand(int i) const {
- assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
- if (i == 0) {
- return getLHS();
- } else {
- return getRHS();
- }
- }
-
- BinaryOp getOpcode() const { return Opc; }
- Init *getLHS() const { return LHS; }
- Init *getRHS() const { return RHS; }
-
- // Fold - If possible, fold this to a simpler init. Return this if not
- // possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-
- virtual std::string getAsString() const;
-};
-
-/// TernOpInit - !op (X, Y, Z) - Combine two inits.
-///
-class TernOpInit : public OpInit {
-public:
- enum TernaryOp { SUBST, FOREACH, IF };
-private:
- TernaryOp Opc;
- Init *LHS, *MHS, *RHS;
-
- TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
- RecTy *Type) :
- OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
-
- TernOpInit(const TernOpInit &Other); // Do not define.
- TernOpInit &operator=(const TernOpInit &Other); // Do not define.
-
-public:
- static TernOpInit *get(TernaryOp opc, Init *lhs,
- Init *mhs, Init *rhs,
- RecTy *Type);
-
- // Clone - Clone this operator, replacing arguments with the new list
- virtual OpInit *clone(std::vector<Init *> &Operands) const {
- assert(Operands.size() == 3 &&
- "Wrong number of operands for ternary operation");
- return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
- getType());
- }
-
- int getNumOperands() const { return 3; }
- Init *getOperand(int i) const {
- assert((i == 0 || i == 1 || i == 2) &&
- "Invalid operand id for ternary operator");
- if (i == 0) {
- return getLHS();
- } else if (i == 1) {
- return getMHS();
- } else {
- return getRHS();
- }
- }
-
- TernaryOp getOpcode() const { return Opc; }
- Init *getLHS() const { return LHS; }
- Init *getMHS() const { return MHS; }
- Init *getRHS() const { return RHS; }
-
- // Fold - If possible, fold this to a simpler init. Return this if not
- // possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
-
- virtual bool isComplete() const { return false; }
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-
- virtual std::string getAsString() const;
-};
-
-
-/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
-///
-class VarInit : public TypedInit {
- std::string VarName;
-
- explicit VarInit(const std::string &VN, RecTy *T)
- : TypedInit(T), VarName(VN) {}
-
- VarInit(const VarInit &Other); // Do not define.
- VarInit &operator=(const VarInit &Other); // Do not define.
-
-public:
- static VarInit *get(const std::string &VN, RecTy *T);
- static VarInit *get(Init *VN, RecTy *T);
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<VarInit *>(this));
- }
-
- const std::string &getName() const { return VarName; }
-
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const;
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const;
-
- virtual RecTy *getFieldType(const std::string &FieldName) const;
- virtual Init *getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const;
-
- /// resolveReferences - This method is used by classes that refer to other
- /// variables which may not be defined at the time they expression is formed.
- /// If a value is set for the variable later, this method will be called on
- /// users of the value to allow the value to propagate out.
- ///
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-
- virtual std::string getAsString() const { return VarName; }
-};
-
-
-/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
-///
-class VarBitInit : public Init {
- TypedInit *TI;
- unsigned Bit;
-
- VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) {
- assert(T->getType() && dynamic_cast<BitsRecTy*>(T->getType()) &&
- ((BitsRecTy*)T->getType())->getNumBits() > B &&
- "Illegal VarBitInit expression!");
- }
-
- VarBitInit(const VarBitInit &Other); // Do not define.
- VarBitInit &operator=(const VarBitInit &Other); // Do not define.
-
-public:
- static VarBitInit *get(TypedInit *T, unsigned B);
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<VarBitInit *>(this));
- }
-
- TypedInit *getVariable() const { return TI; }
- unsigned getBitNum() const { return Bit; }
-
- virtual std::string getAsString() const;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-};
-
-/// VarListElementInit - List[4] - Represent access to one element of a var or
-/// field.
-class VarListElementInit : public TypedInit {
- TypedInit *TI;
- unsigned Element;
-
- VarListElementInit(TypedInit *T, unsigned E)
- : TypedInit(dynamic_cast<ListRecTy*>(T->getType())->getElementType()),
- TI(T), Element(E) {
- assert(T->getType() && dynamic_cast<ListRecTy*>(T->getType()) &&
- "Illegal VarBitInit expression!");
- }
-
- VarListElementInit(const VarListElementInit &Other); // Do not define.
- VarListElementInit &operator=(const VarListElementInit &Other); // Do
- // not
- // define.
-
-public:
- static VarListElementInit *get(TypedInit *T, unsigned E);
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<VarListElementInit *>(this));
- }
-
- TypedInit *getVariable() const { return TI; }
- unsigned getElementNum() const { return Element; }
-
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const;
-
- /// resolveListElementReference - This method is used to implement
- /// VarListElementInit::resolveReferences. If the list element is resolvable
- /// now, we return the resolved value, otherwise we return null.
- virtual Init *resolveListElementReference(Record &R,
- const RecordVal *RV,
- unsigned Elt) const;
-
- virtual std::string getAsString() const;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-};
-
-/// DefInit - AL - Represent a reference to a 'def' in the description
-///
-class DefInit : public TypedInit {
- Record *Def;
-
- DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {}
- friend class Record;
-
- DefInit(const DefInit &Other); // Do not define.
- DefInit &operator=(const DefInit &Other); // Do not define.
-
-public:
- static DefInit *get(Record*);
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<DefInit *>(this));
- }
-
- Record *getDef() const { return Def; }
-
- //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-
- virtual RecTy *getFieldType(const std::string &FieldName) const;
- virtual Init *getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const;
-
- virtual std::string getAsString() const;
-
- /// resolveBitReference - This method is used to implement
- /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
- /// simply return the resolved value, otherwise we return null.
- ///
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const {
- assert(0 && "Illegal bit reference off def");
- return 0;
- }
-
- /// resolveListElementReference - This method is used to implement
- /// VarListElementInit::resolveReferences. If the list element is resolvable
- /// now, we return the resolved value, otherwise we return null.
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const {
- assert(0 && "Illegal element reference off def");
- return 0;
- }
-};
-
-
-/// FieldInit - X.Y - Represent a reference to a subfield of a variable
-///
-class FieldInit : public TypedInit {
- Init *Rec; // Record we are referring to
- std::string FieldName; // Field we are accessing
-
- FieldInit(Init *R, const std::string &FN)
- : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) {
- assert(getType() && "FieldInit with non-record type!");
- }
-
- FieldInit(const FieldInit &Other); // Do not define.
- FieldInit &operator=(const FieldInit &Other); // Do not define.
-
-public:
- static FieldInit *get(Init *R, const std::string &FN);
- static FieldInit *get(Init *R, const Init *FN);
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<FieldInit *>(this));
- }
-
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const;
- virtual Init *resolveListElementReference(Record &R,
- const RecordVal *RV,
- unsigned Elt) const;
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-
- virtual std::string getAsString() const {
- return Rec->getAsString() + "." + FieldName;
- }
-};
-
-/// DagInit - (v a, b) - Represent a DAG tree value. DAG inits are required
-/// to have at least one value then a (possibly empty) list of arguments. Each
-/// argument can have a name associated with it.
-///
-class DagInit : public TypedInit, public FoldingSetNode {
- Init *Val;
- std::string ValName;
- std::vector<Init*> Args;
- std::vector<std::string> ArgNames;
-
- DagInit(Init *V, const std::string &VN,
- ArrayRef<Init *> ArgRange,
- ArrayRef<std::string> NameRange)
- : TypedInit(DagRecTy::get()), Val(V), ValName(VN),
- Args(ArgRange.begin(), ArgRange.end()),
- ArgNames(NameRange.begin(), NameRange.end()) {}
-
- DagInit(const DagInit &Other); // Do not define.
- DagInit &operator=(const DagInit &Other); // Do not define.
-
-public:
- static DagInit *get(Init *V, const std::string &VN,
- ArrayRef<Init *> ArgRange,
- ArrayRef<std::string> NameRange);
- static DagInit *get(Init *V, const std::string &VN,
- const std::vector<
- std::pair<Init*, std::string> > &args);
-
- void Profile(FoldingSetNodeID &ID) const;
-
- virtual Init *convertInitializerTo(RecTy *Ty) const {
- return Ty->convertValue(const_cast<DagInit *>(this));
- }
-
- Init *getOperator() const { return Val; }
-
- const std::string &getName() const { return ValName; }
-
- unsigned getNumArgs() const { return Args.size(); }
- Init *getArg(unsigned Num) const {
- assert(Num < Args.size() && "Arg number out of range!");
- return Args[Num];
- }
- const std::string &getArgName(unsigned Num) const {
- assert(Num < ArgNames.size() && "Arg number out of range!");
- return ArgNames[Num];
- }
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
-
- virtual std::string getAsString() const;
-
- typedef std::vector<Init*>::const_iterator const_arg_iterator;
- typedef std::vector<std::string>::const_iterator const_name_iterator;
-
- inline const_arg_iterator arg_begin() const { return Args.begin(); }
- inline const_arg_iterator arg_end () const { return Args.end(); }
-
- inline size_t arg_size () const { return Args.size(); }
- inline bool arg_empty() const { return Args.empty(); }
-
- inline const_name_iterator name_begin() const { return ArgNames.begin(); }
- inline const_name_iterator name_end () const { return ArgNames.end(); }
-
- inline size_t name_size () const { return ArgNames.size(); }
- inline bool name_empty() const { return ArgNames.empty(); }
-
- virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
- unsigned Bit) const {
- assert(0 && "Illegal bit reference off dag");
- return 0;
- }
-
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const {
- assert(0 && "Illegal element reference off dag");
- return 0;
- }
-};
-
-//===----------------------------------------------------------------------===//
-// High-Level Classes
-//===----------------------------------------------------------------------===//
-
-class RecordVal {
- Init *Name;
- RecTy *Ty;
- unsigned Prefix;
- Init *Value;
-public:
- RecordVal(Init *N, RecTy *T, unsigned P);
- RecordVal(const std::string &N, RecTy *T, unsigned P);
-
- const std::string &getName() const;
-
- unsigned getPrefix() const { return Prefix; }
- RecTy *getType() const { return Ty; }
- Init *getValue() const { return Value; }
-
- bool setValue(Init *V) {
- if (V) {
- Value = V->convertInitializerTo(Ty);
- return Value == 0;
- }
- Value = 0;
- return false;
- }
-
- void dump() const;
- void print(raw_ostream &OS, bool PrintSem = true) const;
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) {
- RV.print(OS << " ");
- return OS;
-}
-
-class Record {
- static unsigned LastID;
-
- // Unique record ID.
- unsigned ID;
- Init *Name;
- SMLoc Loc;
- std::vector<std::string> TemplateArgs;
- std::vector<RecordVal> Values;
- std::vector<Record*> SuperClasses;
-
- // Tracks Record instances. Not owned by Record.
- RecordKeeper &TrackedRecords;
-
- DefInit *TheInit;
-
- void checkName();
-
-public:
-
- // Constructs a record.
- explicit Record(const std::string &N, SMLoc loc, RecordKeeper &records) :
- ID(LastID++), Name(StringInit::get(N)), Loc(loc), TrackedRecords(records), TheInit(0) {}
- ~Record() {}
-
-
- static unsigned getNewUID() { return LastID++; }
-
-
- unsigned getID() const { return ID; }
-
- const std::string &getName() const;
- void setName(Init *Name); // Also updates RecordKeeper.
- void setName(const std::string &Name); // Also updates RecordKeeper.
-
- SMLoc getLoc() const { return Loc; }
-
- /// get the corresponding DefInit.
- DefInit *getDefInit();
-
- const std::vector<std::string> &getTemplateArgs() const {
- return TemplateArgs;
- }
- const std::vector<RecordVal> &getValues() const { return Values; }
- const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
-
- bool isTemplateArg(StringRef Name) const {
- for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
- if (TemplateArgs[i] == Name) return true;
- return false;
- }
-
- const RecordVal *getValue(StringRef Name) const {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getName() == Name) return &Values[i];
- return 0;
- }
- RecordVal *getValue(StringRef Name) {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getName() == Name) return &Values[i];
- return 0;
- }
-
- void addTemplateArg(StringRef Name) {
- assert(!isTemplateArg(Name) && "Template arg already defined!");
- TemplateArgs.push_back(Name);
- }
-
- void addValue(const RecordVal &RV) {
- assert(getValue(RV.getName()) == 0 && "Value already added!");
- Values.push_back(RV);
- }
-
- void removeValue(StringRef Name) {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getName() == Name) {
- Values.erase(Values.begin()+i);
- return;
- }
- assert(0 && "Cannot remove an entry that does not exist!");
- }
-
- bool isSubClassOf(const Record *R) const {
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- if (SuperClasses[i] == R)
- return true;
- return false;
- }
-
- bool isSubClassOf(StringRef Name) const {
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- if (SuperClasses[i]->getName() == Name)
- return true;
- return false;
- }
-
- void addSuperClass(Record *R) {
- assert(!isSubClassOf(R) && "Already subclassing record!");
- SuperClasses.push_back(R);
- }
-
- /// resolveReferences - If there are any field references that refer to fields
- /// that have been filled in, we can propagate the values now.
- ///
- void resolveReferences() { resolveReferencesTo(0); }
-
- /// resolveReferencesTo - If anything in this record refers to RV, replace the
- /// reference to RV with the RHS of RV. If RV is null, we resolve all
- /// possible references.
- void resolveReferencesTo(const RecordVal *RV);
-
- RecordKeeper &getRecords() const {
- return TrackedRecords;
- }
-
- void dump() const;
-
- //===--------------------------------------------------------------------===//
- // High-level methods useful to tablegen back-ends
- //
-
- /// getValueInit - Return the initializer for a value with the specified name,
- /// or throw an exception if the field does not exist.
- ///
- Init *getValueInit(StringRef FieldName) const;
-
- /// getValueAsString - This method looks up the specified field and returns
- /// its value as a string, throwing an exception if the field does not exist
- /// or if the value is not a string.
- ///
- std::string getValueAsString(StringRef FieldName) const;
-
- /// getValueAsBitsInit - This method looks up the specified field and returns
- /// its value as a BitsInit, throwing an exception if the field does not exist
- /// or if the value is not the right type.
- ///
- BitsInit *getValueAsBitsInit(StringRef FieldName) const;
-
- /// getValueAsListInit - This method looks up the specified field and returns
- /// its value as a ListInit, throwing an exception if the field does not exist
- /// or if the value is not the right type.
- ///
- ListInit *getValueAsListInit(StringRef FieldName) const;
-
- /// getValueAsListOfDefs - This method looks up the specified field and
- /// returns its value as a vector of records, throwing an exception if the
- /// field does not exist or if the value is not the right type.
- ///
- std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
-
- /// getValueAsListOfInts - This method looks up the specified field and
- /// returns its value as a vector of integers, throwing an exception if the
- /// field does not exist or if the value is not the right type.
- ///
- std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
-
- /// getValueAsListOfStrings - This method looks up the specified field and
- /// returns its value as a vector of strings, throwing an exception if the
- /// field does not exist or if the value is not the right type.
- ///
- std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const;
-
- /// getValueAsDef - This method looks up the specified field and returns its
- /// value as a Record, throwing an exception if the field does not exist or if
- /// the value is not the right type.
- ///
- Record *getValueAsDef(StringRef FieldName) const;
-
- /// getValueAsBit - This method looks up the specified field and returns its
- /// value as a bit, throwing an exception if the field does not exist or if
- /// the value is not the right type.
- ///
- bool getValueAsBit(StringRef FieldName) const;
-
- /// getValueAsInt - This method looks up the specified field and returns its
- /// value as an int64_t, throwing an exception if the field does not exist or
- /// if the value is not the right type.
- ///
- int64_t getValueAsInt(StringRef FieldName) const;
-
- /// getValueAsDag - This method looks up the specified field and returns its
- /// value as an Dag, throwing an exception if the field does not exist or if
- /// the value is not the right type.
- ///
- DagInit *getValueAsDag(StringRef FieldName) const;
-
- /// getValueAsCode - This method looks up the specified field and returns
- /// its value as the string data in a CodeInit, throwing an exception if the
- /// field does not exist or if the value is not a code object.
- ///
- std::string getValueAsCode(StringRef FieldName) const;
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const Record &R);
-
-struct MultiClass {
- Record Rec; // Placeholder for template args and Name.
- typedef std::vector<Record*> RecordVector;
- RecordVector DefPrototypes;
-
- void dump() const;
-
- MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
- Rec(Name, Loc, Records) {}
-};
-
-class RecordKeeper {
- std::map<std::string, Record*> Classes, Defs;
-public:
- ~RecordKeeper() {
- for (std::map<std::string, Record*>::iterator I = Classes.begin(),
- E = Classes.end(); I != E; ++I)
- delete I->second;
- for (std::map<std::string, Record*>::iterator I = Defs.begin(),
- E = Defs.end(); I != E; ++I)
- delete I->second;
- }
-
- const std::map<std::string, Record*> &getClasses() const { return Classes; }
- const std::map<std::string, Record*> &getDefs() const { return Defs; }
-
- Record *getClass(const std::string &Name) const {
- std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
- return I == Classes.end() ? 0 : I->second;
- }
- Record *getDef(const std::string &Name) const {
- std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
- return I == Defs.end() ? 0 : I->second;
- }
- void addClass(Record *R) {
- assert(getClass(R->getName()) == 0 && "Class already exists!");
- Classes.insert(std::make_pair(R->getName(), R));
- }
- void addDef(Record *R) {
- assert(getDef(R->getName()) == 0 && "Def already exists!");
- Defs.insert(std::make_pair(R->getName(), R));
- }
-
- /// removeClass - Remove, but do not delete, the specified record.
- ///
- void removeClass(const std::string &Name) {
- assert(Classes.count(Name) && "Class does not exist!");
- Classes.erase(Name);
- }
- /// removeDef - Remove, but do not delete, the specified record.
- ///
- void removeDef(const std::string &Name) {
- assert(Defs.count(Name) && "Def does not exist!");
- Defs.erase(Name);
- }
-
- //===--------------------------------------------------------------------===//
- // High-level helper methods, useful for tablegen backends...
-
- /// getAllDerivedDefinitions - This method returns all concrete definitions
- /// that derive from the specified class name. If a class with the specified
- /// name does not exist, an exception is thrown.
- std::vector<Record*>
- getAllDerivedDefinitions(const std::string &ClassName) const;
-
- void dump() const;
-};
-
-/// LessRecord - Sorting predicate to sort record pointers by name.
-///
-struct LessRecord {
- bool operator()(const Record *Rec1, const Record *Rec2) const {
- return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
- }
-};
-
-/// LessRecordFieldName - Sorting predicate to sort record pointers by their
-/// name field.
-///
-struct LessRecordFieldName {
- bool operator()(const Record *Rec1, const Record *Rec2) const {
- return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
- }
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
-
-} // End llvm namespace
-
-#endif
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index e5185020b7..19b45f8667 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -16,7 +16,7 @@
#include "RegisterInfoEmitter.h"
#include "CodeGenTarget.h"
#include "CodeGenRegisters.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h
index 4ad9cfa97f..0fd4d079eb 100644
--- a/utils/TableGen/RegisterInfoEmitter.h
+++ b/utils/TableGen/RegisterInfoEmitter.h
@@ -16,7 +16,7 @@
#ifndef REGISTER_INFO_EMITTER_H
#define REGISTER_INFO_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <vector>
namespace llvm {
diff --git a/utils/TableGen/SetTheory.cpp b/utils/TableGen/SetTheory.cpp
index 21ac09cb66..bef73f33ef 100644
--- a/utils/TableGen/SetTheory.cpp
+++ b/utils/TableGen/SetTheory.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "SetTheory.h"
-#include "Error.h"
-#include "Record.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/Support/Format.h"
using namespace llvm;
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
index 978e91a1d6..103a4032b0 100644
--- a/utils/TableGen/SubtargetEmitter.cpp
+++ b/utils/TableGen/SubtargetEmitter.cpp
@@ -13,7 +13,7 @@
#include "SubtargetEmitter.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h
index b239f3dda7..ff01274bd1 100644
--- a/utils/TableGen/SubtargetEmitter.h
+++ b/utils/TableGen/SubtargetEmitter.h
@@ -14,7 +14,7 @@
#ifndef SUBTARGET_EMITTER_H
#define SUBTARGET_EMITTER_H
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/MC/MCInstrItineraries.h"
#include <vector>
#include <map>
diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp
deleted file mode 100644
index b4b90ff64e..0000000000
--- a/utils/TableGen/TGLexer.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-//===- TGLexer.cpp - Lexer for TableGen -----------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implement the Lexer for TableGen.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TGLexer.h"
-#include "Error.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Config/config.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Twine.h"
-#include <cctype>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <cerrno>
-using namespace llvm;
-
-TGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) {
- CurBuffer = 0;
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = CurBuf->getBufferStart();
- TokStart = 0;
-}
-
-SMLoc TGLexer::getLoc() const {
- return SMLoc::getFromPointer(TokStart);
-}
-
-/// ReturnError - Set the error to the specified string at the specified
-/// location. This is defined to always return tgtok::Error.
-tgtok::TokKind TGLexer::ReturnError(const char *Loc, const Twine &Msg) {
- PrintError(Loc, Msg);
- return tgtok::Error;
-}
-
-int TGLexer::getNextChar() {
- char CurChar = *CurPtr++;
- switch (CurChar) {
- default:
- return (unsigned char)CurChar;
- case 0: {
- // A nul character in the stream is either the end of the current buffer or
- // a random nul in the file. Disambiguate that here.
- if (CurPtr-1 != CurBuf->getBufferEnd())
- return 0; // Just whitespace.
-
- // If this is the end of an included file, pop the parent file off the
- // include stack.
- SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
- if (ParentIncludeLoc != SMLoc()) {
- CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = ParentIncludeLoc.getPointer();
- return getNextChar();
- }
-
- // Otherwise, return end of file.
- --CurPtr; // Another call to lex will return EOF again.
- return EOF;
- }
- case '\n':
- case '\r':
- // Handle the newline character by ignoring it and incrementing the line
- // count. However, be careful about 'dos style' files with \n\r in them.
- // Only treat a \n\r or \r\n as a single line.
- if ((*CurPtr == '\n' || (*CurPtr == '\r')) &&
- *CurPtr != CurChar)
- ++CurPtr; // Eat the two char newline sequence.
- return '\n';
- }
-}
-
-tgtok::TokKind TGLexer::LexToken() {
- TokStart = CurPtr;
- // This always consumes at least one character.
- int CurChar = getNextChar();
-
- switch (CurChar) {
- default:
- // Handle letters: [a-zA-Z_#]
- if (isalpha(CurChar) || CurChar == '_' || CurChar == '#')
- return LexIdentifier();
-
- // Unknown character, emit an error.
- return ReturnError(TokStart, "Unexpected character");
- case EOF: return tgtok::Eof;
- case ':': return tgtok::colon;
- case ';': return tgtok::semi;
- case '.': return tgtok::period;
- case ',': return tgtok::comma;
- case '<': return tgtok::less;
- case '>': return tgtok::greater;
- case ']': return tgtok::r_square;
- case '{': return tgtok::l_brace;
- case '}': return tgtok::r_brace;
- case '(': return tgtok::l_paren;
- case ')': return tgtok::r_paren;
- case '=': return tgtok::equal;
- case '?': return tgtok::question;
-
- case 0:
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- // Ignore whitespace.
- return LexToken();
- case '/':
- // If this is the start of a // comment, skip until the end of the line or
- // the end of the buffer.
- if (*CurPtr == '/')
- SkipBCPLComment();
- else if (*CurPtr == '*') {
- if (SkipCComment())
- return tgtok::Error;
- } else // Otherwise, this is an error.
- return ReturnError(TokStart, "Unexpected character");
- return LexToken();
- case '-': case '+':
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': case '8': case '9':
- return LexNumber();
- case '"': return LexString();
- case '$': return LexVarName();
- case '[': return LexBracket();
- case '!': return LexExclaim();
- }
-}
-
-/// LexString - Lex "[^"]*"
-tgtok::TokKind TGLexer::LexString() {
- const char *StrStart = CurPtr;
-
- CurStrVal = "";
-
- while (*CurPtr != '"') {
- // If we hit the end of the buffer, report an error.
- if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd())
- return ReturnError(StrStart, "End of file in string literal");
-
- if (*CurPtr == '\n' || *CurPtr == '\r')
- return ReturnError(StrStart, "End of line in string literal");
-
- if (*CurPtr != '\\') {
- CurStrVal += *CurPtr++;
- continue;
- }
-
- ++CurPtr;
-
- switch (*CurPtr) {
- case '\\': case '\'': case '"':
- // These turn into their literal character.
- CurStrVal += *CurPtr++;
- break;
- case 't':
- CurStrVal += '\t';
- ++CurPtr;
- break;
- case 'n':
- CurStrVal += '\n';
- ++CurPtr;
- break;
-
- case '\n':
- case '\r':
- return ReturnError(CurPtr, "escaped newlines not supported in tblgen");
-
- // If we hit the end of the buffer, report an error.
- case '\0':
- if (CurPtr == CurBuf->getBufferEnd())
- return ReturnError(StrStart, "End of file in string literal");
- // FALL THROUGH
- default:
- return ReturnError(CurPtr, "invalid escape in string literal");
- }
- }
-
- ++CurPtr;
- return tgtok::StrVal;
-}
-
-tgtok::TokKind TGLexer::LexVarName() {
- if (!isalpha(CurPtr[0]) && CurPtr[0] != '_')
- return ReturnError(TokStart, "Invalid variable name");
-
- // Otherwise, we're ok, consume the rest of the characters.
- const char *VarNameStart = CurPtr++;
-
- while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
- ++CurPtr;
-
- CurStrVal.assign(VarNameStart, CurPtr);
- return tgtok::VarName;
-}
-
-
-tgtok::TokKind TGLexer::LexIdentifier() {
- // The first letter is [a-zA-Z_#].
- const char *IdentStart = TokStart;
-
- // Match the rest of the identifier regex: [0-9a-zA-Z_#]*
- while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_' ||
- *CurPtr == '#')
- ++CurPtr;
-
-
- // Check to see if this identifier is a keyword.
- unsigned Len = CurPtr-IdentStart;
-
- if (Len == 3 && !memcmp(IdentStart, "int", 3)) return tgtok::Int;
- if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return tgtok::Bit;
- if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return tgtok::Bits;
- if (Len == 6 && !memcmp(IdentStart, "string", 6)) return tgtok::String;
- if (Len == 4 && !memcmp(IdentStart, "list", 4)) return tgtok::List;
- if (Len == 4 && !memcmp(IdentStart, "code", 4)) return tgtok::Code;
- if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return tgtok::Dag;
-
- if (Len == 5 && !memcmp(IdentStart, "class", 5)) return tgtok::Class;
- if (Len == 3 && !memcmp(IdentStart, "def", 3)) return tgtok::Def;
- if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return tgtok::Defm;
- if (Len == 10 && !memcmp(IdentStart, "multiclass", 10))
- return tgtok::MultiClass;
- if (Len == 5 && !memcmp(IdentStart, "field", 5)) return tgtok::Field;
- if (Len == 3 && !memcmp(IdentStart, "let", 3)) return tgtok::Let;
- if (Len == 2 && !memcmp(IdentStart, "in", 2)) return tgtok::In;
-
- if (Len == 7 && !memcmp(IdentStart, "include", 7)) {
- if (LexInclude()) return tgtok::Error;
- return Lex();
- }
-
- CurStrVal.assign(IdentStart, CurPtr);
- return tgtok::Id;
-}
-
-/// LexInclude - We just read the "include" token. Get the string token that
-/// comes next and enter the include.
-bool TGLexer::LexInclude() {
- // The token after the include must be a string.
- tgtok::TokKind Tok = LexToken();
- if (Tok == tgtok::Error) return true;
- if (Tok != tgtok::StrVal) {
- PrintError(getLoc(), "Expected filename after include");
- return true;
- }
-
- // Get the string.
- std::string Filename = CurStrVal;
- std::string IncludedFile;
-
-
- CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr),
- IncludedFile);
- if (CurBuffer == -1) {
- PrintError(getLoc(), "Could not find include file '" + Filename + "'");
- return true;
- }
-
- Dependencies.push_back(IncludedFile);
- // Save the line number and lex buffer of the includer.
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = CurBuf->getBufferStart();
- return false;
-}
-
-void TGLexer::SkipBCPLComment() {
- ++CurPtr; // skip the second slash.
- while (1) {
- switch (*CurPtr) {
- case '\n':
- case '\r':
- return; // Newline is end of comment.
- case 0:
- // If this is the end of the buffer, end the comment.
- if (CurPtr == CurBuf->getBufferEnd())
- return;
- break;
- }
- // Otherwise, skip the character.
- ++CurPtr;
- }
-}
-
-/// SkipCComment - This skips C-style /**/ comments. The only difference from C
-/// is that we allow nesting.
-bool TGLexer::SkipCComment() {
- ++CurPtr; // skip the star.
- unsigned CommentDepth = 1;
-
- while (1) {
- int CurChar = getNextChar();
- switch (CurChar) {
- case EOF:
- PrintError(TokStart, "Unterminated comment!");
- return true;
- case '*':
- // End of the comment?
- if (CurPtr[0] != '/') break;
-
- ++CurPtr; // End the */.
- if (--CommentDepth == 0)
- return false;
- break;
- case '/':
- // Start of a nested comment?
- if (CurPtr[0] != '*') break;
- ++CurPtr;
- ++CommentDepth;
- break;
- }
- }
-}
-
-/// LexNumber - Lex:
-/// [-+]?[0-9]+
-/// 0x[0-9a-fA-F]+
-/// 0b[01]+
-tgtok::TokKind TGLexer::LexNumber() {
- if (CurPtr[-1] == '0') {
- if (CurPtr[0] == 'x') {
- ++CurPtr;
- const char *NumStart = CurPtr;
- while (isxdigit(CurPtr[0]))
- ++CurPtr;
-
- // Requires at least one hex digit.
- if (CurPtr == NumStart)
- return ReturnError(TokStart, "Invalid hexadecimal number");
-
- errno = 0;
- CurIntVal = strtoll(NumStart, 0, 16);
- if (errno == EINVAL)
- return ReturnError(TokStart, "Invalid hexadecimal number");
- if (errno == ERANGE) {
- errno = 0;
- CurIntVal = (int64_t)strtoull(NumStart, 0, 16);
- if (errno == EINVAL)
- return ReturnError(TokStart, "Invalid hexadecimal number");
- if (errno == ERANGE)
- return ReturnError(TokStart, "Hexadecimal number out of range");
- }
- return tgtok::IntVal;
- } else if (CurPtr[0] == 'b') {
- ++CurPtr;
- const char *NumStart = CurPtr;
- while (CurPtr[0] == '0' || CurPtr[0] == '1')
- ++CurPtr;
-
- // Requires at least one binary digit.
- if (CurPtr == NumStart)
- return ReturnError(CurPtr-2, "Invalid binary number");
- CurIntVal = strtoll(NumStart, 0, 2);
- return tgtok::IntVal;
- }
- }
-
- // Check for a sign without a digit.
- if (!isdigit(CurPtr[0])) {
- if (CurPtr[-1] == '-')
- return tgtok::minus;
- else if (CurPtr[-1] == '+')
- return tgtok::plus;
- }
-
- while (isdigit(CurPtr[0]))
- ++CurPtr;
- CurIntVal = strtoll(TokStart, 0, 10);
- return tgtok::IntVal;
-}
-
-/// LexBracket - We just read '['. If this is a code block, return it,
-/// otherwise return the bracket. Match: '[' and '[{ ( [^}]+ | }[^]] )* }]'
-tgtok::TokKind TGLexer::LexBracket() {
- if (CurPtr[0] != '{')
- return tgtok::l_square;
- ++CurPtr;
- const char *CodeStart = CurPtr;
- while (1) {
- int Char = getNextChar();
- if (Char == EOF) break;
-
- if (Char != '}') continue;
-
- Char = getNextChar();
- if (Char == EOF) break;
- if (Char == ']') {
- CurStrVal.assign(CodeStart, CurPtr-2);
- return tgtok::CodeFragment;
- }
- }
-
- return ReturnError(CodeStart-2, "Unterminated Code Block");
-}
-
-/// LexExclaim - Lex '!' and '![a-zA-Z]+'.
-tgtok::TokKind TGLexer::LexExclaim() {
- if (!isalpha(*CurPtr))
- return ReturnError(CurPtr - 1, "Invalid \"!operator\"");
-
- const char *Start = CurPtr++;
- while (isalpha(*CurPtr))
- ++CurPtr;
-
- // Check to see which operator this is.
- tgtok::TokKind Kind =
- StringSwitch<tgtok::TokKind>(StringRef(Start, CurPtr - Start))
- .Case("eq", tgtok::XEq)
- .Case("if", tgtok::XIf)
- .Case("head", tgtok::XHead)
- .Case("tail", tgtok::XTail)
- .Case("con", tgtok::XConcat)
- .Case("shl", tgtok::XSHL)
- .Case("sra", tgtok::XSRA)
- .Case("srl", tgtok::XSRL)
- .Case("cast", tgtok::XCast)
- .Case("empty", tgtok::XEmpty)
- .Case("subst", tgtok::XSubst)
- .Case("foreach", tgtok::XForEach)
- .Case("strconcat", tgtok::XStrConcat)
- .Default(tgtok::Error);
-
- return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator");
-}
-
diff --git a/utils/TableGen/TGLexer.h b/utils/TableGen/TGLexer.h
deleted file mode 100644
index 84d328b12d..0000000000
--- a/utils/TableGen/TGLexer.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===- TGLexer.h - Lexer for TableGen Files ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class represents the Lexer for tablegen files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TGLEXER_H
-#define TGLEXER_H
-
-#include "llvm/Support/DataTypes.h"
-#include <string>
-#include <vector>
-#include <cassert>
-
-namespace llvm {
-class MemoryBuffer;
-class SourceMgr;
-class SMLoc;
-class Twine;
-
-namespace tgtok {
- enum TokKind {
- // Markers
- Eof, Error,
-
- // Tokens with no info.
- minus, plus, // - +
- l_square, r_square, // [ ]
- l_brace, r_brace, // { }
- l_paren, r_paren, // ( )
- less, greater, // < >
- colon, semi, // : ;
- comma, period, // , .
- equal, question, // = ?
-
- // Keywords.
- Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List,
- MultiClass, String,
-
- // !keywords.
- XConcat, XSRA, XSRL, XSHL, XStrConcat, XCast, XSubst,
- XForEach, XHead, XTail, XEmpty, XIf, XEq,
-
- // Integer value.
- IntVal,
-
- // String valued tokens.
- Id, StrVal, VarName, CodeFragment
- };
-}
-
-/// TGLexer - TableGen Lexer class.
-class TGLexer {
- SourceMgr &SrcMgr;
-
- const char *CurPtr;
- const MemoryBuffer *CurBuf;
-
- // Information about the current token.
- const char *TokStart;
- tgtok::TokKind CurCode;
- std::string CurStrVal; // This is valid for ID, STRVAL, VARNAME, CODEFRAGMENT
- int64_t CurIntVal; // This is valid for INTVAL.
-
- /// CurBuffer - This is the current buffer index we're lexing from as managed
- /// by the SourceMgr object.
- int CurBuffer;
- /// Dependencies - This is the list of all included files.
- std::vector<std::string> Dependencies;
-
-public:
- TGLexer(SourceMgr &SrcMgr);
- ~TGLexer() {}
-
- tgtok::TokKind Lex() {
- return CurCode = LexToken();
- }
-
- const std::vector<std::string> &getDependencies() const {
- return Dependencies;
- }
-
- tgtok::TokKind getCode() const { return CurCode; }
-
- const std::string &getCurStrVal() const {
- assert((CurCode == tgtok::Id || CurCode == tgtok::StrVal ||
- CurCode == tgtok::VarName || CurCode == tgtok::CodeFragment) &&
- "This token doesn't have a string value");
- return CurStrVal;
- }
- int64_t getCurIntVal() const {
- assert(CurCode == tgtok::IntVal && "This token isn't an integer");
- return CurIntVal;
- }
-
- SMLoc getLoc() const;
-
-private:
- /// LexToken - Read the next token and return its code.
- tgtok::TokKind LexToken();
-
- tgtok::TokKind ReturnError(const char *Loc, const Twine &Msg);
-
- int getNextChar();
- void SkipBCPLComment();
- bool SkipCComment();
- tgtok::TokKind LexIdentifier();
- bool LexInclude();
- tgtok::TokKind LexString();
- tgtok::TokKind LexVarName();
- tgtok::TokKind LexNumber();
- tgtok::TokKind LexBracket();
- tgtok::TokKind LexExclaim();
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
deleted file mode 100644
index f734b984e1..0000000000
--- a/utils/TableGen/TGParser.cpp
+++ /dev/null
@@ -1,2163 +0,0 @@
-//===- TGParser.cpp - Parser for TableGen Files ---------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implement the Parser for TableGen.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TGParser.h"
-#include "Record.h"
-#include "llvm/ADT/StringExtras.h"
-#include <algorithm>
-#include <sstream>
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/CommandLine.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-// Support Code for the Semantic Actions.
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-struct SubClassReference {
- SMLoc RefLoc;
- Record *Rec;
- std::vector<Init*> TemplateArgs;
- SubClassReference() : Rec(0) {}
-
- bool isInvalid() const { return Rec == 0; }
-};
-
-struct SubMultiClassReference {
- SMLoc RefLoc;
- MultiClass *MC;
- std::vector<Init*> TemplateArgs;
- SubMultiClassReference() : MC(0) {}
-
- bool isInvalid() const { return MC == 0; }
- void dump() const;
-};
-
-void SubMultiClassReference::dump() const {
- errs() << "Multiclass:\n";
-
- MC->dump();
-
- errs() << "Template args:\n";
- for (std::vector<Init *>::const_iterator i = TemplateArgs.begin(),
- iend = TemplateArgs.end();
- i != iend;
- ++i) {
- (*i)->dump();
- }
-}
-
-} // end namespace llvm
-
-bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
- if (CurRec == 0)
- CurRec = &CurMultiClass->Rec;
-
- if (RecordVal *ERV = CurRec->getValue(RV.getName())) {
- // The value already exists in the class, treat this as a set.
- if (ERV->setValue(RV.getValue()))
- return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
- RV.getType()->getAsString() + "' is incompatible with " +
- "previous definition of type '" +
- ERV->getType()->getAsString() + "'");
- } else {
- CurRec->addValue(RV);
- }
- return false;
-}
-
-/// SetValue -
-/// Return true on error, false on success.
-bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
- const std::vector<unsigned> &BitList, Init *V) {
- if (!V) return false;
-
- if (CurRec == 0) CurRec = &CurMultiClass->Rec;
-
- RecordVal *RV = CurRec->getValue(ValName);
- if (RV == 0)
- return Error(Loc, "Value '" + ValName + "' unknown!");
-
- // Do not allow assignments like 'X = X'. This will just cause infinite loops
- // in the resolution machinery.
- if (BitList.empty())
- if (VarInit *VI = dynamic_cast<VarInit*>(V))
- if (VI->getName() == ValName)
- return false;
-
- // If we are assigning to a subset of the bits in the value... then we must be
- // assigning to a field of BitsRecTy, which must have a BitsInit
- // initializer.
- //
- if (!BitList.empty()) {
- BitsInit *CurVal = dynamic_cast<BitsInit*>(RV->getValue());
- if (CurVal == 0)
- return Error(Loc, "Value '" + ValName + "' is not a bits type");
-
- // Convert the incoming value to a bits type of the appropriate size...
- Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size()));
- if (BI == 0) {
- V->convertInitializerTo(BitsRecTy::get(BitList.size()));
- return Error(Loc, "Initializer is not compatible with bit range");
- }
-
- // We should have a BitsInit type now.
- BitsInit *BInit = dynamic_cast<BitsInit*>(BI);
- assert(BInit != 0);
-
- SmallVector<Init *, 16> NewBits(CurVal->getNumBits());
-
- // Loop over bits, assigning values as appropriate.
- for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
- unsigned Bit = BitList[i];
- if (NewBits[Bit])
- return Error(Loc, "Cannot set bit #" + utostr(Bit) + " of value '" +
- ValName + "' more than once");
- NewBits[Bit] = BInit->getBit(i);
- }
-
- for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
- if (NewBits[i] == 0)
- NewBits[i] = CurVal->getBit(i);
-
- V = BitsInit::get(NewBits);
- }
-
- if (RV->setValue(V))
- return Error(Loc, "Value '" + ValName + "' of type '" +
- RV->getType()->getAsString() +
- "' is incompatible with initializer '" + V->getAsString() +"'");
- return false;
-}
-
-/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template
-/// args as SubClass's template arguments.
-bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
- Record *SC = SubClass.Rec;
- // Add all of the values in the subclass into the current class.
- const std::vector<RecordVal> &Vals = SC->getValues();
- for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- if (AddValue(CurRec, SubClass.RefLoc, Vals[i]))
- return true;
-
- const std::vector<std::string> &TArgs = SC->getTemplateArgs();
-
- // Ensure that an appropriate number of template arguments are specified.
- if (TArgs.size() < SubClass.TemplateArgs.size())
- return Error(SubClass.RefLoc, "More template args specified than expected");
-
- // Loop over all of the template arguments, setting them to the specified
- // value or leaving them as the default if necessary.
- for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
- if (i < SubClass.TemplateArgs.size()) {
- // If a value is specified for this template arg, set it now.
- if (SetValue(CurRec, SubClass.RefLoc, TArgs[i], std::vector<unsigned>(),
- SubClass.TemplateArgs[i]))
- return true;
-
- // Resolve it next.
- CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-
- // Now remove it.
- CurRec->removeValue(TArgs[i]);
-
- } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
- return Error(SubClass.RefLoc,"Value not specified for template argument #"
- + utostr(i) + " (" + TArgs[i] + ") of subclass '" +
- SC->getName() + "'!");
- }
- }
-
- // Since everything went well, we can now set the "superclass" list for the
- // current record.
- const std::vector<Record*> &SCs = SC->getSuperClasses();
- for (unsigned i = 0, e = SCs.size(); i != e; ++i) {
- if (CurRec->isSubClassOf(SCs[i]))
- return Error(SubClass.RefLoc,
- "Already subclass of '" + SCs[i]->getName() + "'!\n");
- CurRec->addSuperClass(SCs[i]);
- }
-
- if (CurRec->isSubClassOf(SC))
- return Error(SubClass.RefLoc,
- "Already subclass of '" + SC->getName() + "'!\n");
- CurRec->addSuperClass(SC);
- return false;
-}
-
-/// AddSubMultiClass - Add SubMultiClass as a subclass to
-/// CurMC, resolving its template args as SubMultiClass's
-/// template arguments.
-bool TGParser::AddSubMultiClass(MultiClass *CurMC,
- SubMultiClassReference &SubMultiClass) {
- MultiClass *SMC = SubMultiClass.MC;
- Record *CurRec = &CurMC->Rec;
-
- const std::vector<RecordVal> &MCVals = CurRec->getValues();
-
- // Add all of the values in the subclass into the current class.
- const std::vector<RecordVal> &SMCVals = SMC->Rec.getValues();
- for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
- if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
- return true;
-
- int newDefStart = CurMC->DefPrototypes.size();
-
- // Add all of the defs in the subclass into the current multiclass.
- for (MultiClass::RecordVector::const_iterator i = SMC->DefPrototypes.begin(),
- iend = SMC->DefPrototypes.end();
- i != iend;
- ++i) {
- // Clone the def and add it to the current multiclass
- Record *NewDef = new Record(**i);
-
- // Add all of the values in the superclass into the current def.
- for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
- if (AddValue(NewDef, SubMultiClass.RefLoc, MCVals[i]))
- return true;
-
- CurMC->DefPrototypes.push_back(NewDef);
- }
-
- const std::vector<std::string> &SMCTArgs = SMC->Rec.getTemplateArgs();
-
- // Ensure that an appropriate number of template arguments are
- // specified.
- if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
- return Error(SubMultiClass.RefLoc,
- "More template args specified than expected");
-
- // Loop over all of the template arguments, setting them to the specified
- // value or leaving them as the default if necessary.
- for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
- if (i < SubMultiClass.TemplateArgs.size()) {
- // If a value is specified for this template arg, set it in the
- // superclass now.
- if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],
- std::vector<unsigned>(),
- SubMultiClass.TemplateArgs[i]))
- return true;
-
- // Resolve it next.
- CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i]));
-
- // Now remove it.
- CurRec->removeValue(SMCTArgs[i]);
-
- // If a value is specified for this template arg, set it in the
- // new defs now.
- for (MultiClass::RecordVector::iterator j =
- CurMC->DefPrototypes.begin() + newDefStart,
- jend = CurMC->DefPrototypes.end();
- j != jend;
- ++j) {
- Record *Def = *j;
-
- if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],
- std::vector<unsigned>(),
- SubMultiClass.TemplateArgs[i]))
- return true;
-
- // Resolve it next.
- Def->resolveReferencesTo(Def->getValue(SMCTArgs[i]));
-
- // Now remove it
- Def->removeValue(SMCTArgs[i]);
- }
- } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
- return Error(SubMultiClass.RefLoc,
- "Value not specified for template argument #"
- + utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" +
- SMC->Rec.getName() + "'!");
- }
- }
-
- return false;
-}
-
-//===----------------------------------------------------------------------===//
-// Parser Code
-//===----------------------------------------------------------------------===//
-
-/// isObjectStart - Return true if this is a valid first token for an Object.
-static bool isObjectStart(tgtok::TokKind K) {
- return K == tgtok::Class || K == tgtok::Def ||
- K == tgtok::Defm || K == tgtok::Let || K == tgtok::MultiClass;
-}
-
-static std::string GetNewAnonymousName() {
- static unsigned AnonCounter = 0;
- return "anonymous."+utostr(AnonCounter++);
-}
-
-/// ParseObjectName - If an object name is specified, return it. Otherwise,
-/// return an anonymous name.
-/// ObjectName ::= ID
-/// ObjectName ::= /*empty*/
-///
-std::string TGParser::ParseObjectName() {
- if (Lex.getCode() != tgtok::Id)
- return GetNewAnonymousName();
-
- std::string Ret = Lex.getCurStrVal();
- Lex.Lex();
- return Ret;
-}
-
-
-/// ParseClassID - Parse and resolve a reference to a class name. This returns
-/// null on error.
-///
-/// ClassID ::= ID
-///
-Record *TGParser::ParseClassID() {
- if (Lex.getCode() != tgtok::Id) {
- TokError("expected name for ClassID");
- return 0;
- }
-
- Record *Result = Records.getClass(Lex.getCurStrVal());
- if (Result == 0)
- TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
-
- Lex.Lex();
- return Result;
-}
-
-/// ParseMultiClassID - Parse and resolve a reference to a multiclass name.
-/// This returns null on error.
-///
-/// MultiClassID ::= ID
-///
-MultiClass *TGParser::ParseMultiClassID() {
- if (Lex.getCode() != tgtok::Id) {
- TokError("expected name for ClassID");
- return 0;
- }
-
- MultiClass *Result = MultiClasses[Lex.getCurStrVal()];
- if (Result == 0)
- TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
-
- Lex.Lex();
- return Result;
-}
-
-Record *TGParser::ParseDefmID() {
- if (Lex.getCode() != tgtok::Id) {
- TokError("expected multiclass name");
- return 0;
- }
-
- MultiClass *MC = MultiClasses[Lex.getCurStrVal()];
- if (MC == 0) {
- TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
- return 0;
- }
-
- Lex.Lex();
- return &MC->Rec;
-}
-
-
-/// ParseSubClassReference - Parse a reference to a subclass or to a templated
-/// subclass. This returns a SubClassRefTy with a null Record* on error.
-///
-/// SubClassRef ::= ClassID
-/// SubClassRef ::= ClassID '<' ValueList '>'
-///
-SubClassReference TGParser::
-ParseSubClassReference(Record *CurRec, bool isDefm) {
- SubClassReference Result;
- Result.RefLoc = Lex.getLoc();
-
- if (isDefm)
- Result.Rec = ParseDefmID();
- else
- Result.Rec = ParseClassID();
- if (Result.Rec == 0) return Result;
-
- // If there is no template arg list, we're done.
- if (Lex.getCode() != tgtok::less)
- return Result;
- Lex.Lex(); // Eat the '<'
-
- if (Lex.getCode() == tgtok::greater) {
- TokError("subclass reference requires a non-empty list of template values");
- Result.Rec = 0;
- return Result;
- }
-
- Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
- if (Result.TemplateArgs.empty()) {
- Result.Rec = 0; // Error parsing value list.
- return Result;
- }
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected '>' in template value list");
- Result.Rec = 0;
- return Result;
- }
- Lex.Lex();
-
- return Result;
-}
-
-/// ParseSubMultiClassReference - Parse a reference to a subclass or to a
-/// templated submulticlass. This returns a SubMultiClassRefTy with a null
-/// Record* on error.
-///
-/// SubMultiClassRef ::= MultiClassID
-/// SubMultiClassRef ::= MultiClassID '<' ValueList '>'
-///
-SubMultiClassReference TGParser::
-ParseSubMultiClassReference(MultiClass *CurMC) {
- SubMultiClassReference Result;
- Result.RefLoc = Lex.getLoc();
-
- Result.MC = ParseMultiClassID();
- if (Result.MC == 0) return Result;
-
- // If there is no template arg list, we're done.
- if (Lex.getCode() != tgtok::less)
- return Result;
- Lex.Lex(); // Eat the '<'
-
- if (Lex.getCode() == tgtok::greater) {
- TokError("subclass reference requires a non-empty list of template values");
- Result.MC = 0;
- return Result;
- }
-
- Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
- if (Result.TemplateArgs.empty()) {
- Result.MC = 0; // Error parsing value list.
- return Result;
- }
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected '>' in template value list");
- Result.MC = 0;
- return Result;
- }
- Lex.Lex();
-
- return Result;
-}
-
-/// ParseRangePiece - Parse a bit/value range.
-/// RangePiece ::= INTVAL
-/// RangePiece ::= INTVAL '-' INTVAL
-/// RangePiece ::= INTVAL INTVAL
-bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
- if (Lex.getCode() != tgtok::IntVal) {
- TokError("expected integer or bitrange");
- return true;
- }
- int64_t Start = Lex.getCurIntVal();
- int64_t End;
-
- if (Start < 0)
- return TokError("invalid range, cannot be negative");
-
- switch (Lex.Lex()) { // eat first character.
- default:
- Ranges.push_back(Start);
- return false;
- case tgtok::minus:
- if (Lex.Lex() != tgtok::IntVal) {
- TokError("expected integer value as end of range");
- return true;
- }
- End = Lex.getCurIntVal();
- break;
- case tgtok::IntVal:
- End = -Lex.getCurIntVal();
- break;
- }
- if (End < 0)
- return TokError("invalid range, cannot be negative");
- Lex.Lex();
-
- // Add to the range.
- if (Start < End) {
- for (; Start <= End; ++Start)
- Ranges.push_back(Start);
- } else {
- for (; Start >= End; --Start)
- Ranges.push_back(Start);
- }
- return false;
-}
-
-/// ParseRangeList - Parse a list of scalars and ranges into scalar values.
-///
-/// RangeList ::= RangePiece (',' RangePiece)*
-///
-std::vector<unsigned> TGParser::ParseRangeList() {
- std::vector<unsigned> Result;
-
- // Parse the first piece.
- if (ParseRangePiece(Result))
- return std::vector<unsigned>();
- while (Lex.getCode() == tgtok::comma) {
- Lex.Lex(); // Eat the comma.
-
- // Parse the next range piece.
- if (ParseRangePiece(Result))
- return std::vector<unsigned>();
- }
- return Result;
-}
-
-/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.
-/// OptionalRangeList ::= '<' RangeList '>'
-/// OptionalRangeList ::= /*empty*/
-bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
- if (Lex.getCode() != tgtok::less)
- return false;
-
- SMLoc StartLoc = Lex.getLoc();
- Lex.Lex(); // eat the '<'
-
- // Parse the range list.
- Ranges = ParseRangeList();
- if (Ranges.empty()) return true;
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected '>' at end of range list");
- return Error(StartLoc, "to match this '<'");
- }
- Lex.Lex(); // eat the '>'.
- return false;
-}
-
-/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing.
-/// OptionalBitList ::= '{' RangeList '}'
-/// OptionalBitList ::= /*empty*/
-bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
- if (Lex.getCode() != tgtok::l_brace)
- return false;
-
- SMLoc StartLoc = Lex.getLoc();
- Lex.Lex(); // eat the '{'
-
- // Parse the range list.
- Ranges = ParseRangeList();
- if (Ranges.empty()) return true;
-
- if (Lex.getCode() != tgtok::r_brace) {
- TokError("expected '}' at end of bit list");
- return Error(StartLoc, "to match this '{'");
- }
- Lex.Lex(); // eat the '}'.
- return false;
-}
-
-
-/// ParseType - Parse and return a tblgen type. This returns null on error.
-///
-/// Type ::= STRING // string type
-/// Type ::= BIT // bit type
-/// Type ::= BITS '<' INTVAL '>' // bits<x> type
-/// Type ::= INT // int type
-/// Type ::= LIST '<' Type '>' // list<x> type
-/// Type ::= CODE // code type
-/// Type ::= DAG // dag type
-/// Type ::= ClassID // Record Type
-///
-RecTy *TGParser::ParseType() {
- switch (Lex.getCode()) {
- default: TokError("Unknown token when expecting a type"); return 0;
- case tgtok::String: Lex.Lex(); return StringRecTy::get();
- case tgtok::Bit: Lex.Lex(); return BitRecTy::get();
- case tgtok::Int: Lex.Lex(); return IntRecTy::get();
- case tgtok::Code: Lex.Lex(); return CodeRecTy::get();
- case tgtok::Dag: Lex.Lex(); return DagRecTy::get();
- case tgtok::Id:
- if (Record *R = ParseClassID()) return RecordRecTy::get(R);
- return 0;
- case tgtok::Bits: {
- if (Lex.Lex() != tgtok::less) { // Eat 'bits'
- TokError("expected '<' after bits type");
- return 0;
- }
- if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
- TokError("expected integer in bits<n> type");
- return 0;
- }
- uint64_t Val = Lex.getCurIntVal();
- if (Lex.Lex() != tgtok::greater) { // Eat count.
- TokError("expected '>' at end of bits<n> type");
- return 0;
- }
- Lex.Lex(); // Eat '>'
- return BitsRecTy::get(Val);
- }
- case tgtok::List: {
- if (Lex.Lex() != tgtok::less) { // Eat 'bits'
- TokError("expected '<' after list type");
- return 0;
- }
- Lex.Lex(); // Eat '<'
- RecTy *SubType = ParseType();
- if (SubType == 0) return 0;
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected '>' at end of list<ty> type");
- return 0;
- }
- Lex.Lex(); // Eat '>'
- return ListRecTy::get(SubType);
- }
- }
-}
-
-/// ParseIDValue - Parse an ID as a value and decode what it means.
-///
-/// IDValue ::= ID [def local value]
-/// IDValue ::= ID [def template arg]
-/// IDValue ::= ID [multiclass local value]
-/// IDValue ::= ID [multiclass template argument]
-/// IDValue ::= ID [def name]
-///
-Init *TGParser::ParseIDValue(Record *CurRec) {
- assert(Lex.getCode() == tgtok::Id && "Expected ID in ParseIDValue");
- std::string Name = Lex.getCurStrVal();
- SMLoc Loc = Lex.getLoc();
- Lex.Lex();
- return ParseIDValue(CurRec, Name, Loc);
-}
-
-/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
-/// has already been read.
-Init *TGParser::ParseIDValue(Record *CurRec,
- const std::string &Name, SMLoc NameLoc) {
- if (CurRec) {
- if (const RecordVal *RV = CurRec->getValue(Name))
- return VarInit::get(Name, RV->getType());
-
- std::string TemplateArgName = CurRec->getName()+":"+Name;
- if (CurRec->isTemplateArg(TemplateArgName)) {
- const RecordVal *RV = CurRec->getValue(TemplateArgName);
- assert(RV && "Template arg doesn't exist??");
- return VarInit::get(TemplateArgName, RV->getType());
- }
- }
-
- if (CurMultiClass) {
- std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
- if (CurMultiClass->Rec.isTemplateArg(MCName)) {
- const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
- assert(RV && "Template arg doesn't exist??");
- return VarInit::get(MCName, RV->getType());
- }
- }
-
- if (Record *D = Records.getDef(Name))
- return DefInit::get(D);
-
- Error(NameLoc, "Variable not defined: '" + Name + "'");
- return 0;
-}
-
-/// ParseOperation - Parse an operator. This returns null on error.
-///
-/// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
-///
-Init *TGParser::ParseOperation(Record *CurRec) {
- switch (Lex.getCode()) {
- default:
- TokError("unknown operation");
- return 0;
- break;
- case tgtok::XHead:
- case tgtok::XTail:
- case tgtok::XEmpty:
- case tgtok::XCast: { // Value ::= !unop '(' Value ')'
- UnOpInit::UnaryOp Code;
- RecTy *Type = 0;
-
- switch (Lex.getCode()) {
- default: assert(0 && "Unhandled code!");
- case tgtok::XCast:
- Lex.Lex(); // eat the operation
- Code = UnOpInit::CAST;
-
- Type = ParseOperatorType();
-
- if (Type == 0) {
- TokError("did not get type for unary operator");
- return 0;
- }
-
- break;
- case tgtok::XHead:
- Lex.Lex(); // eat the operation
- Code = UnOpInit::HEAD;
- break;
- case tgtok::XTail:
- Lex.Lex(); // eat the operation
- Code = UnOpInit::TAIL;
- break;
- case tgtok::XEmpty:
- Lex.Lex(); // eat the operation
- Code = UnOpInit::EMPTY;
- Type = IntRecTy::get();
- break;
- }
- if (Lex.getCode() != tgtok::l_paren) {
- TokError("expected '(' after unary operator");
- return 0;
- }
- Lex.Lex(); // eat the '('
-
- Init *LHS = ParseValue(CurRec);
- if (LHS == 0) return 0;
-
- if (Code == UnOpInit::HEAD
- || Code == UnOpInit::TAIL
- || Code == UnOpInit::EMPTY) {
- ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
- StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
- TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
- if (LHSl == 0 && LHSs == 0 && LHSt == 0) {
- TokError("expected list or string type argument in unary operator");
- return 0;
- }
- if (LHSt) {
- ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
- StringRecTy *SType = dynamic_cast<StringRecTy*>(LHSt->getType());
- if (LType == 0 && SType == 0) {
- TokError("expected list or string type argumnet in unary operator");
- return 0;
- }
- }
-
- if (Code == UnOpInit::HEAD
- || Code == UnOpInit::TAIL) {
- if (LHSl == 0 && LHSt == 0) {
- TokError("expected list type argumnet in unary operator");
- return 0;
- }
-
- if (LHSl && LHSl->getSize() == 0) {
- TokError("empty list argument in unary operator");
- return 0;
- }
- if (LHSl) {
- Init *Item = LHSl->getElement(0);
- TypedInit *Itemt = dynamic_cast<TypedInit*>(Item);
- if (Itemt == 0) {
- TokError("untyped list element in unary operator");
- return 0;
- }
- if (Code == UnOpInit::HEAD) {
- Type = Itemt->getType();
- } else {
- Type = ListRecTy::get(Itemt->getType());
- }
- } else {
- assert(LHSt && "expected list type argument in unary operator");
- ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
- if (LType == 0) {
- TokError("expected list type argumnet in unary operator");
- return 0;
- }
- if (Code == UnOpInit::HEAD) {
- Type = LType->getElementType();
- } else {
- Type = LType;
- }
- }
- }
- }
-
- if (Lex.getCode() != tgtok::r_paren) {
- TokError("expected ')' in unary operator");
- return 0;
- }
- Lex.Lex(); // eat the ')'
- return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
- }
-
- case tgtok::XConcat:
- case tgtok::XSRA:
- case tgtok::XSRL:
- case tgtok::XSHL:
- case tgtok::XEq:
- case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')'
- tgtok::TokKind OpTok = Lex.getCode();
- SMLoc OpLoc = Lex.getLoc();
- Lex.Lex(); // eat the operation
-
- BinOpInit::BinaryOp Code;
- RecTy *Type = 0;
-
- switch (OpTok) {
- default: assert(0 && "Unhandled code!");
- case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break;
- case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break;
- case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break;
- case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break;
- case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break;
- case tgtok::XStrConcat:
- Code = BinOpInit::STRCONCAT;
- Type = StringRecTy::get();
- break;
- }
-
- if (Lex.getCode() != tgtok::l_paren) {
- TokError("expected '(' after binary operator");
- return 0;
- }
- Lex.Lex(); // eat the '('
-
- SmallVector<Init*, 2> InitList;
-
- InitList.push_back(ParseValue(CurRec));
- if (InitList.back() == 0) return 0;
-
- while (Lex.getCode() == tgtok::comma) {
- Lex.Lex(); // eat the ','
-
- InitList.push_back(ParseValue(CurRec));
- if (InitList.back() == 0) return 0;
- }
-
- if (Lex.getCode() != tgtok::r_paren) {
- TokError("expected ')' in operator");
- return 0;
- }
- Lex.Lex(); // eat the ')'
-
- // We allow multiple operands to associative operators like !strconcat as
- // shorthand for nesting them.
- if (Code == BinOpInit::STRCONCAT) {
- while (InitList.size() > 2) {
- Init *RHS = InitList.pop_back_val();
- RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))
- ->Fold(CurRec, CurMultiClass);
- InitList.back() = RHS;
- }
- }
-
- if (InitList.size() == 2)
- return (BinOpInit::get(Code, InitList[0], InitList[1], Type))
- ->Fold(CurRec, CurMultiClass);
-
- Error(OpLoc, "expected two operands to operator");
- return 0;
- }
-
- case tgtok::XIf:
- case tgtok::XForEach:
- case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
- TernOpInit::TernaryOp Code;
- RecTy *Type = 0;
-
- tgtok::TokKind LexCode = Lex.getCode();
- Lex.Lex(); // eat the operation
- switch (LexCode) {
- default: assert(0 && "Unhandled code!");
- case tgtok::XIf:
- Code = TernOpInit::IF;
- break;
- case tgtok::XForEach:
- Code = TernOpInit::FOREACH;
- break;
- case tgtok::XSubst:
- Code = TernOpInit::SUBST;
- break;
- }
- if (Lex.getCode() != tgtok::l_paren) {
- TokError("expected '(' after ternary operator");
- return 0;
- }
- Lex.Lex(); // eat the '('
-
- Init *LHS = ParseValue(CurRec);
- if (LHS == 0) return 0;
-
- if (Lex.getCode() != tgtok::comma) {
- TokError("expected ',' in ternary operator");
- return 0;
- }
- Lex.Lex(); // eat the ','
-
- Init *MHS = ParseValue(CurRec);
- if (MHS == 0) return 0;
-
- if (Lex.getCode() != tgtok::comma) {
- TokError("expected ',' in ternary operator");
- return 0;
- }
- Lex.Lex(); // eat the ','
-
- Init *RHS = ParseValue(CurRec);
- if (RHS == 0) return 0;
-
- if (Lex.getCode() != tgtok::r_paren) {
- TokError("expected ')' in binary operator");
- return 0;
- }
- Lex.Lex(); // eat the ')'
-
- switch (LexCode) {
- default: assert(0 && "Unhandled code!");
- case tgtok::XIf: {
- // FIXME: The `!if' operator doesn't handle non-TypedInit well at
- // all. This can be made much more robust.
- TypedInit *MHSt = dynamic_cast<TypedInit*>(MHS);
- TypedInit *RHSt = dynamic_cast<TypedInit*>(RHS);
-
- RecTy *MHSTy = 0;
- RecTy *RHSTy = 0;
-
- if (MHSt == 0 && RHSt == 0) {
- BitsInit *MHSbits = dynamic_cast<BitsInit*>(MHS);
- BitsInit *RHSbits = dynamic_cast<BitsInit*>(RHS);
-
- if (MHSbits && RHSbits &&
- MHSbits->getNumBits() == RHSbits->getNumBits()) {
- Type = BitRecTy::get();
- break;
- } else {
- BitInit *MHSbit = dynamic_cast<BitInit*>(MHS);
- BitInit *RHSbit = dynamic_cast<BitInit*>(RHS);
-
- if (MHSbit && RHSbit) {
- Type = BitRecTy::get();
- break;
- }
- }
- } else if (MHSt != 0 && RHSt != 0) {
- MHSTy = MHSt->getType();
- RHSTy = RHSt->getType();
- }
-
- if (!MHSTy || !RHSTy) {
- TokError("could not get type for !if");
- return 0;
- }
-
- if (MHSTy->typeIsConvertibleTo(RHSTy)) {
- Type = RHSTy;
- } else if (RHSTy->typeIsConvertibleTo(MHSTy)) {
- Type = MHSTy;
- } else {
- TokError("inconsistent types for !if");
- return 0;
- }
- break;
- }
- case tgtok::XForEach: {
- TypedInit *MHSt = dynamic_cast<TypedInit *>(MHS);
- if (MHSt == 0) {
- TokError("could not get type for !foreach");
- return 0;
- }
- Type = MHSt->getType();
- break;
- }
- case tgtok::XSubst: {
- TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
- if (RHSt == 0) {
- TokError("could not get type for !subst");
- return 0;
- }
- Type = RHSt->getType();
- break;
- }
- }
- return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec,
- CurMultiClass);
- }
- }
- TokError("could not parse operation");
- return 0;
-}
-
-/// ParseOperatorType - Parse a type for an operator. This returns
-/// null on error.
-///
-/// OperatorType ::= '<' Type '>'
-///
-RecTy *TGParser::ParseOperatorType() {
- RecTy *Type = 0;
-
- if (Lex.getCode() != tgtok::less) {
- TokError("expected type name for operator");
- return 0;
- }
- Lex.Lex(); // eat the <
-
- Type = ParseType();
-
- if (Type == 0) {
- TokError("expected type name for operator");
- return 0;
- }
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected type name for operator");
- return 0;
- }
- Lex.Lex(); // eat the >
-
- return Type;
-}
-
-
-/// ParseSimpleValue - Parse a tblgen value. This returns null on error.
-///
-/// SimpleValue ::= IDValue
-/// SimpleValue ::= INTVAL
-/// SimpleValue ::= STRVAL+
-/// SimpleValue ::= CODEFRAGMENT
-/// SimpleValue ::= '?'
-/// SimpleValue ::= '{' ValueList '}'
-/// SimpleValue ::= ID '<' ValueListNE '>'
-/// SimpleValue ::= '[' ValueList ']'
-/// SimpleValue ::= '(' IDValue DagArgList ')'
-/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
-/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
-/// SimpleValue ::= SRATOK '(' Value ',' Value ')'
-/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
-/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
-///
-Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
- Init *R = 0;
- switch (Lex.getCode()) {
- default: TokError("Unknown token when parsing a value"); break;
- case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break;
- case tgtok::StrVal: {
- std::string Val = Lex.getCurStrVal();
- Lex.Lex();
-
- // Handle multiple consecutive concatenated strings.
- while (Lex.getCode() == tgtok::StrVal) {
- Val += Lex.getCurStrVal();
- Lex.Lex();
- }
-
- R = StringInit::get(Val);
- break;
- }
- case tgtok::CodeFragment:
- R = CodeInit::get(Lex.getCurStrVal());
- Lex.Lex();
- break;
- case tgtok::question:
- R = UnsetInit::get();
- Lex.Lex();
- break;
- case tgtok::Id: {
- SMLoc NameLoc = Lex.getLoc();
- std::string Name = Lex.getCurStrVal();
- if (Lex.Lex() != tgtok::less) // consume the Id.
- return ParseIDValue(CurRec, Name, NameLoc); // Value ::= IDValue
-
- // Value ::= ID '<' ValueListNE '>'
- if (Lex.Lex() == tgtok::greater) {
- TokError("expected non-empty value list");
- return 0;
- }
-
- // This is a CLASS<initvalslist> expression. This is supposed to synthesize
- // a new anonymous definition, deriving from CLASS<initvalslist> with no
- // body.
- Record *Class = Records.getClass(Name);
- if (!Class) {
- Error(NameLoc, "Expected a class name, got '" + Name + "'");
- return 0;
- }
-
- std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
- if (ValueList.empty()) return 0;
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected '>' at end of value list");
- return 0;
- }
- Lex.Lex(); // eat the '>'
-
- // Create the new record, set it as CurRec temporarily.
- static unsigned AnonCounter = 0;
- Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++),
- NameLoc,
- Records);
- SubClassReference SCRef;
- SCRef.RefLoc = NameLoc;
- SCRef.Rec = Class;
- SCRef.TemplateArgs = ValueList;
- // Add info about the subclass to NewRec.
- if (AddSubClass(NewRec, SCRef))
- return 0;
- NewRec->resolveReferences();
- Records.addDef(NewRec);
-
- // The result of the expression is a reference to the new record.
- return DefInit::get(NewRec);
- }
- case tgtok::l_brace: { // Value ::= '{' ValueList '}'
- SMLoc BraceLoc = Lex.getLoc();
- Lex.Lex(); // eat the '{'
- std::vector<Init*> Vals;
-
- if (Lex.getCode() != tgtok::r_brace) {
- Vals = ParseValueList(CurRec);
- if (Vals.empty()) return 0;
- }
- if (Lex.getCode() != tgtok::r_brace) {
- TokError("expected '}' at end of bit list value");
- return 0;
- }
- Lex.Lex(); // eat the '}'
-
- SmallVector<Init *, 16> NewBits(Vals.size());
-
- for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
- Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get());
- if (Bit == 0) {
- Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+
- ") is not convertable to a bit");
- return 0;
- }
- NewBits[Vals.size()-i-1] = Bit;
- }
- return BitsInit::get(NewBits);
- }
- case tgtok::l_square: { // Value ::= '[' ValueList ']'
- Lex.Lex(); // eat the '['
- std::vector<Init*> Vals;
-
- RecTy *DeducedEltTy = 0;
- ListRecTy *GivenListTy = 0;
-
- if (ItemType != 0) {
- ListRecTy *ListType = dynamic_cast<ListRecTy*>(ItemType);
- if (ListType == 0) {
- std::stringstream s;
- s << "Type mismatch for list, expected list type, got "
- << ItemType->getAsString();
- TokError(s.str());
- return 0;
- }
- GivenListTy = ListType;
- }
-
- if (Lex.getCode() != tgtok::r_square) {
- Vals = ParseValueList(CurRec, 0,
- GivenListTy ? GivenListTy->getElementType() : 0);
- if (Vals.empty()) return 0;
- }
- if (Lex.getCode() != tgtok::r_square) {
- TokError("expected ']' at end of list value");
- return 0;
- }
- Lex.Lex(); // eat the ']'
-
- RecTy *GivenEltTy = 0;
- if (Lex.getCode() == tgtok::less) {
- // Optional list element type
- Lex.Lex(); // eat the '<'
-
- GivenEltTy = ParseType();
- if (GivenEltTy == 0) {
- // Couldn't parse element type
- return 0;
- }
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected '>' at end of list element type");
- return 0;
- }
- Lex.Lex(); // eat the '>'
- }
-
- // Check elements
- RecTy *EltTy = 0;
- for (std::vector<Init *>::iterator i = Vals.begin(), ie = Vals.end();
- i != ie;
- ++i) {
- TypedInit *TArg = dynamic_cast<TypedInit*>(*i);
- if (TArg == 0) {
- TokError("Untyped list element");
- return 0;
- }
- if (EltTy != 0) {
- EltTy = resolveTypes(EltTy, TArg->getType());
- if (EltTy == 0) {
- TokError("Incompatible types in list elements");
- return 0;
- }
- } else {
- EltTy = TArg->getType();
- }
- }
-
- if (GivenEltTy != 0) {
- if (EltTy != 0) {
- // Verify consistency
- if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
- TokError("Incompatible types in list elements");
- return 0;
- }
- }
- EltTy = GivenEltTy;
- }
-
- if (EltTy == 0) {
- if (ItemType == 0) {
- TokError("No type for list");
- return 0;
- }
- DeducedEltTy = GivenListTy->getElementType();
- } else {
- // Make sure the deduced type is compatible with the given type
- if (GivenListTy) {
- if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
- TokError("Element type mismatch for list");
- return 0;
- }
- }
- DeducedEltTy = EltTy;
- }
-
- return ListInit::get(Vals, DeducedEltTy);
- }
- case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
- Lex.Lex(); // eat the '('
- if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast) {
- TokError("expected identifier in dag init");
- return 0;
- }
-
- Init *Operator = ParseValue(CurRec);
- if (Operator == 0) return 0;
-
- // If the operator name is present, parse it.
- std::string OperatorName;
- if (Lex.getCode() == tgtok::colon) {
- if (Lex.Lex() != tgtok::VarName) { // eat the ':'
- TokError("expected variable name in dag operator");
- return 0;
- }
- OperatorName = Lex.getCurStrVal();
- Lex.Lex(); // eat the VarName.
- }
-
- std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
- if (Lex.getCode() != tgtok::r_paren) {
- DagArgs = ParseDagArgList(CurRec);
- if (DagArgs.empty()) return 0;
- }
-
- if (Lex.getCode() != tgtok::r_paren) {
- TokError("expected ')' in dag init");
- return 0;
- }
- Lex.Lex(); // eat the ')'
-
- return DagInit::get(Operator, OperatorName, DagArgs);
- }
-
- case tgtok::XHead:
- case tgtok::XTail:
- case tgtok::XEmpty:
- case tgtok::XCast: // Value ::= !unop '(' Value ')'
- case tgtok::XConcat:
- case tgtok::XSRA:
- case tgtok::XSRL:
- case tgtok::XSHL:
- case tgtok::XEq:
- case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')'
- case tgtok::XIf:
- case tgtok::XForEach:
- case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
- return ParseOperation(CurRec);
- }
- }
-
- return R;
-}
-
-/// ParseValue - Parse a tblgen value. This returns null on error.
-///
-/// Value ::= SimpleValue ValueSuffix*
-/// ValueSuffix ::= '{' BitList '}'
-/// ValueSuffix ::= '[' BitList ']'
-/// ValueSuffix ::= '.' ID
-///
-Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
- Init *Result = ParseSimpleValue(CurRec, ItemType);
- if (Result == 0) return 0;
-
- // Parse the suffixes now if present.
- while (1) {
- switch (Lex.getCode()) {
- default: return Result;
- case tgtok::l_brace: {
- SMLoc CurlyLoc = Lex.getLoc();
- Lex.Lex(); // eat the '{'
- std::vector<unsigned> Ranges = ParseRangeList();
- if (Ranges.empty()) return 0;
-
- // Reverse the bitlist.
- std::reverse(Ranges.begin(), Ranges.end());
- Result = Result->convertInitializerBitRange(Ranges);
- if (Result == 0) {
- Error(CurlyLoc, "Invalid bit range for value");
- return 0;
- }
-
- // Eat the '}'.
- if (Lex.getCode() != tgtok::r_brace) {
- TokError("expected '}' at end of bit range list");
- return 0;
- }
- Lex.Lex();
- break;
- }
- case tgtok::l_square: {
- SMLoc SquareLoc = Lex.getLoc();
- Lex.Lex(); // eat the '['
- std::vector<unsigned> Ranges = ParseRangeList();
- if (Ranges.empty()) return 0;
-
- Result = Result->convertInitListSlice(Ranges);
- if (Result == 0) {
- Error(SquareLoc, "Invalid range for list slice");
- return 0;
- }
-
- // Eat the ']'.
- if (Lex.getCode() != tgtok::r_square) {
- TokError("expected ']' at end of list slice");
- return 0;
- }
- Lex.Lex();
- break;
- }
- case tgtok::period:
- if (Lex.Lex() != tgtok::Id) { // eat the .
- TokError("expected field identifier after '.'");
- return 0;
- }
- if (!Result->getFieldType(Lex.getCurStrVal())) {
- TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
- Result->getAsString() + "'");
- return 0;
- }
- Result = FieldInit::get(Result, Lex.getCurStrVal());
- Lex.Lex(); // eat field name
- break;
- }
- }
-}
-
-/// ParseDagArgList - Parse the argument list for a dag literal expression.
-///
-/// ParseDagArgList ::= Value (':' VARNAME)?
-/// ParseDagArgList ::= ParseDagArgList ',' Value (':' VARNAME)?
-std::vector<std::pair<llvm::Init*, std::string> >
-TGParser::ParseDagArgList(Record *CurRec) {
- std::vector<std::pair<llvm::Init*, std::string> > Result;
-
- while (1) {
- Init *Val = ParseValue(CurRec);
- if (Val == 0) return std::vector<std::pair<llvm::Init*, std::string> >();
-
- // If the variable name is present, add it.
- std::string VarName;
- if (Lex.getCode() == tgtok::colon) {
- if (Lex.Lex() != tgtok::VarName) { // eat the ':'
- TokError("expected variable name in dag literal");
- return std::vector<std::pair<llvm::Init*, std::string> >();
- }
- VarName = Lex.getCurStrVal();
- Lex.Lex(); // eat the VarName.
- }
-
- Result.push_back(std::make_pair(Val, VarName));
-
- if (Lex.getCode() != tgtok::comma) break;
- Lex.Lex(); // eat the ','
- }
-
- return Result;
-}
-
-
-/// ParseValueList - Parse a comma separated list of values, returning them as a
-/// vector. Note that this always expects to be able to parse at least one
-/// value. It returns an empty list if this is not possible.
-///
-/// ValueList ::= Value (',' Value)
-///
-std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
- RecTy *EltTy) {
- std::vector<Init*> Result;
- RecTy *ItemType = EltTy;
- unsigned int ArgN = 0;
- if (ArgsRec != 0 && EltTy == 0) {
- const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
- const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
- if (!RV) {
- errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN]
- << ")\n";
- }
- assert(RV && "Template argument record not found??");
- ItemType = RV->getType();
- ++ArgN;
- }
- Result.push_back(ParseValue(CurRec, ItemType));
- if (Result.back() == 0) return std::vector<Init*>();
-
- while (Lex.getCode() == tgtok::comma) {
- Lex.Lex(); // Eat the comma
-
- if (ArgsRec != 0 && EltTy == 0) {
- const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
- if (ArgN >= TArgs.size()) {
- TokError("too many template arguments");
- return std::vector<Init*>();
- }
- const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
- assert(RV && "Template argument record not found??");
- ItemType = RV->getType();
- ++ArgN;
- }
- Result.push_back(ParseValue(CurRec, ItemType));
- if (Result.back() == 0) return std::vector<Init*>();
- }
-
- return Result;
-}
-
-
-/// ParseDeclaration - Read a declaration, returning the name of field ID, or an
-/// empty string on error. This can happen in a number of different context's,
-/// including within a def or in the template args for a def (which which case
-/// CurRec will be non-null) and within the template args for a multiclass (in
-/// which case CurRec will be null, but CurMultiClass will be set). This can
-/// also happen within a def that is within a multiclass, which will set both
-/// CurRec and CurMultiClass.
-///
-/// Declaration ::= FIELD? Type ID ('=' Value)?
-///
-std::string TGParser::ParseDeclaration(Record *CurRec,
- bool ParsingTemplateArgs) {
- // Read the field prefix if present.
- bool HasField = Lex.getCode() == tgtok::Field;
- if (HasField) Lex.Lex();
-
- RecTy *Type = ParseType();
- if (Type == 0) return "";
-
- if (Lex.getCode() != tgtok::Id) {
- TokError("Expected identifier in declaration");
- return "";
- }
-
- SMLoc IdLoc = Lex.getLoc();
- std::string DeclName = Lex.getCurStrVal();
- Lex.Lex();
-
- if (ParsingTemplateArgs) {
- if (CurRec) {
- DeclName = CurRec->getName() + ":" + DeclName;
- } else {
- assert(CurMultiClass);
- }
- if (CurMultiClass)
- DeclName = CurMultiClass->Rec.getName() + "::" + DeclName;
- }
-
- // Add the value.
- if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField)))
- return "";
-
- // If a value is present, parse it.
- if (Lex.getCode() == tgtok::equal) {
- Lex.Lex();
- SMLoc ValLoc = Lex.getLoc();
- Init *Val = ParseValue(CurRec, Type);
- if (Val == 0 ||
- SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
- return "";
- }
-
- return DeclName;
-}
-
-/// ParseTemplateArgList - Read a template argument list, which is a non-empty
-/// sequence of template-declarations in <>'s. If CurRec is non-null, these are
-/// template args for a def, which may or may not be in a multiclass. If null,
-/// these are the template args for a multiclass.
-///
-/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
-///
-bool TGParser::ParseTemplateArgList(Record *CurRec) {
- assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
- Lex.Lex(); // eat the '<'
-
- Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
-
- // Read the first declaration.
- std::string TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
- if (TemplArg.empty())
- return true;
-
- TheRecToAddTo->addTemplateArg(TemplArg);
-
- while (Lex.getCode() == tgtok::comma) {
- Lex.Lex(); // eat the ','
-
- // Read the following declarations.
- TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
- if (TemplArg.empty())
- return true;
- TheRecToAddTo->addTemplateArg(TemplArg);
- }
-
- if (Lex.getCode() != tgtok::greater)
- return TokError("expected '>' at end of template argument list");
- Lex.Lex(); // eat the '>'.
- return false;
-}
-
-
-/// ParseBodyItem - Parse a single item at within the body of a def or class.
-///
-/// BodyItem ::= Declaration ';'
-/// BodyItem ::= LET ID OptionalBitList '=' Value ';'
-bool TGParser::ParseBodyItem(Record *CurRec) {
- if (Lex.getCode() != tgtok::Let) {
- if (ParseDeclaration(CurRec, false).empty())
- return true;
-
- if (Lex.getCode() != tgtok::semi)
- return TokError("expected ';' after declaration");
- Lex.Lex();
- return false;
- }
-
- // LET ID OptionalRangeList '=' Value ';'
- if (Lex.Lex() != tgtok::Id)
- return TokError("expected field identifier after let");
-
- SMLoc IdLoc = Lex.getLoc();
- std::string FieldName = Lex.getCurStrVal();
- Lex.Lex(); // eat the field name.
-
- std::vector<unsigned> BitList;
- if (ParseOptionalBitList(BitList))
- return true;
- std::reverse(BitList.begin(), BitList.end());
-
- if (Lex.getCode() != tgtok::equal)
- return TokError("expected '=' in let expression");
- Lex.Lex(); // eat the '='.
-
- RecordVal *Field = CurRec->getValue(FieldName);
- if (Field == 0)
- return TokError("Value '" + FieldName + "' unknown!");
-
- RecTy *Type = Field->getType();
-
- Init *Val = ParseValue(CurRec, Type);
- if (Val == 0) return true;
-
- if (Lex.getCode() != tgtok::semi)
- return TokError("expected ';' after let expression");
- Lex.Lex();
-
- return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
-}
-
-/// ParseBody - Read the body of a class or def. Return true on error, false on
-/// success.
-///
-/// Body ::= ';'
-/// Body ::= '{' BodyList '}'
-/// BodyList BodyItem*
-///
-bool TGParser::ParseBody(Record *CurRec) {
- // If this is a null definition, just eat the semi and return.
- if (Lex.getCode() == tgtok::semi) {
- Lex.Lex();
- return false;
- }
-
- if (Lex.getCode() != tgtok::l_brace)
- return TokError("Expected ';' or '{' to start body");
- // Eat the '{'.
- Lex.Lex();
-
- while (Lex.getCode() != tgtok::r_brace)
- if (ParseBodyItem(CurRec))
- return true;
-
- // Eat the '}'.
- Lex.Lex();
- return false;
-}
-
-/// ParseObjectBody - Parse the body of a def or class. This consists of an
-/// optional ClassList followed by a Body. CurRec is the current def or class
-/// that is being parsed.
-///
-/// ObjectBody ::= BaseClassList Body
-/// BaseClassList ::= /*empty*/
-/// BaseClassList ::= ':' BaseClassListNE
-/// BaseClassListNE ::= SubClassRef (',' SubClassRef)*
-///
-bool TGParser::ParseObjectBody(Record *CurRec) {
- // If there is a baseclass list, read it.
- if (Lex.getCode() == tgtok::colon) {
- Lex.Lex();
-
- // Read all of the subclasses.
- SubClassReference SubClass = ParseSubClassReference(CurRec, false);
- while (1) {
- // Check for error.
- if (SubClass.Rec == 0) return true;
-
- // Add it.
- if (AddSubClass(CurRec, SubClass))
- return true;
-
- if (Lex.getCode() != tgtok::comma) break;
- Lex.Lex(); // eat ','.
- SubClass = ParseSubClassReference(CurRec, false);
- }
- }
-
- // Process any variables on the let stack.
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
- LetStack[i][j].Bits, LetStack[i][j].Value))
- return true;
-
- return ParseBody(CurRec);
-}
-
-/// ParseDef - Parse and return a top level or multiclass def, return the record
-/// corresponding to it. This returns null on error.
-///
-/// DefInst ::= DEF ObjectName ObjectBody
-///
-bool TGParser::ParseDef(MultiClass *CurMultiClass) {
- SMLoc DefLoc = Lex.getLoc();
- assert(Lex.getCode() == tgtok::Def && "Unknown tok");
- Lex.Lex(); // Eat the 'def' token.
-
- // Parse ObjectName and make a record for it.
- Record *CurRec = new Record(ParseObjectName(), DefLoc, Records);
-
- if (!CurMultiClass) {
- // Top-level def definition.
-
- // Ensure redefinition doesn't happen.
- if (Records.getDef(CurRec->getName())) {
- Error(DefLoc, "def '" + CurRec->getName() + "' already defined");
- return true;
- }
- Records.addDef(CurRec);
- } else {
- // Otherwise, a def inside a multiclass, add it to the multiclass.
- for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i)
- if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) {
- Error(DefLoc, "def '" + CurRec->getName() +
- "' already defined in this multiclass!");
- return true;
- }
- CurMultiClass->DefPrototypes.push_back(CurRec);
- }
-
- if (ParseObjectBody(CurRec))
- return true;
-
- if (CurMultiClass == 0) // Def's in multiclasses aren't really defs.
- // See Record::setName(). This resolve step will see any new name
- // for the def that might have been created when resolving
- // inheritance, values and arguments above.
- CurRec->resolveReferences();
-
- // If ObjectBody has template arguments, it's an error.
- assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
-
- if (CurMultiClass) {
- // Copy the template arguments for the multiclass into the def.
- const std::vector<std::string> &TArgs =
- CurMultiClass->Rec.getTemplateArgs();
-
- for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
- const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
- assert(RV && "Template arg doesn't exist?");
- CurRec->addValue(*RV);
- }
- }
-
- return false;
-}
-
-
-/// ParseClass - Parse a tblgen class definition.
-///
-/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody
-///
-bool TGParser::ParseClass() {
- assert(Lex.getCode() == tgtok::Class && "Unexpected token!");
- Lex.Lex();
-
- if (Lex.getCode() != tgtok::Id)
- return TokError("expected class name after 'class' keyword");
-
- Record *CurRec = Records.getClass(Lex.getCurStrVal());
- if (CurRec) {
- // If the body was previously defined, this is an error.
- if (!CurRec->getValues().empty() ||
- !CurRec->getSuperClasses().empty() ||
- !CurRec->getTemplateArgs().empty())
- return TokError("Class '" + CurRec->getName() + "' already defined");
- } else {
- // If this is the first reference to this class, create and add it.
- CurRec = new Record(Lex.getCurStrVal(), Lex.getLoc(), Records);
- Records.addClass(CurRec);
- }
- Lex.Lex(); // eat the name.
-
- // If there are template args, parse them.
- if (Lex.getCode() == tgtok::less)
- if (ParseTemplateArgList(CurRec))
- return true;
-
- // Finally, parse the object body.
- return ParseObjectBody(CurRec);
-}
-
-/// ParseLetList - Parse a non-empty list of assignment expressions into a list
-/// of LetRecords.
-///
-/// LetList ::= LetItem (',' LetItem)*
-/// LetItem ::= ID OptionalRangeList '=' Value
-///
-std::vector<LetRecord> TGParser::ParseLetList() {
- std::vector<LetRecord> Result;
-
- while (1) {
- if (Lex.getCode() != tgtok::Id) {
- TokError("expected identifier in let definition");
- return std::vector<LetRecord>();
- }
- std::string Name = Lex.getCurStrVal();
- SMLoc NameLoc = Lex.getLoc();
- Lex.Lex(); // Eat the identifier.
-
- // Check for an optional RangeList.
- std::vector<unsigned> Bits;
- if (ParseOptionalRangeList(Bits))
- return std::vector<LetRecord>();
- std::reverse(Bits.begin(), Bits.end());
-
- if (Lex.getCode() != tgtok::equal) {
- TokError("expected '=' in let expression");
- return std::vector<LetRecord>();
- }
- Lex.Lex(); // eat the '='.
-
- Init *Val = ParseValue(0);
- if (Val == 0) return std::vector<LetRecord>();
-
- // Now that we have everything, add the record.
- Result.push_back(LetRecord(Name, Bits, Val, NameLoc));
-
- if (Lex.getCode() != tgtok::comma)
- return Result;
- Lex.Lex(); // eat the comma.
- }
-}
-
-/// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of
-/// different related productions. This works inside multiclasses too.
-///
-/// Object ::= LET LetList IN '{' ObjectList '}'
-/// Object ::= LET LetList IN Object
-///
-bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
- assert(Lex.getCode() == tgtok::Let && "Unexpected token");
- Lex.Lex();
-
- // Add this entry to the let stack.
- std::vector<LetRecord> LetInfo = ParseLetList();
- if (LetInfo.empty()) return true;
- LetStack.push_back(LetInfo);
-
- if (Lex.getCode() != tgtok::In)
- return TokError("expected 'in' at end of top-level 'let'");
- Lex.Lex();
-
- // If this is a scalar let, just handle it now
- if (Lex.getCode() != tgtok::l_brace) {
- // LET LetList IN Object
- if (ParseObject(CurMultiClass))
- return true;
- } else { // Object ::= LETCommand '{' ObjectList '}'
- SMLoc BraceLoc = Lex.getLoc();
- // Otherwise, this is a group let.
- Lex.Lex(); // eat the '{'.
-
- // Parse the object list.
- if (ParseObjectList(CurMultiClass))
- return true;
-
- if (Lex.getCode() != tgtok::r_brace) {
- TokError("expected '}' at end of top level let command");
- return Error(BraceLoc, "to match this '{'");
- }
- Lex.Lex();
- }
-
- // Outside this let scope, this let block is not active.
- LetStack.pop_back();
- return false;
-}
-
-/// ParseMultiClass - Parse a multiclass definition.
-///
-/// MultiClassInst ::= MULTICLASS ID TemplateArgList?
-/// ':' BaseMultiClassList '{' MultiClassDef+ '}'
-///
-bool TGParser::ParseMultiClass() {
- assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
- Lex.Lex(); // Eat the multiclass token.
-
- if (Lex.getCode() != tgtok::Id)
- return TokError("expected identifier after multiclass for name");
- std::string Name = Lex.getCurStrVal();
-
- if (MultiClasses.count(Name))
- return TokError("multiclass '" + Name + "' already defined");
-
- CurMultiClass = MultiClasses[Name] = new MultiClass(Name,
- Lex.getLoc(), Records);
- Lex.Lex(); // Eat the identifier.
-
- // If there are template args, parse them.
- if (Lex.getCode() == tgtok::less)
- if (ParseTemplateArgList(0))
- return true;
-
- bool inherits = false;
-
- // If there are submulticlasses, parse them.
- if (Lex.getCode() == tgtok::colon) {
- inherits = true;
-
- Lex.Lex();
-
- // Read all of the submulticlasses.
- SubMultiClassReference SubMultiClass =
- ParseSubMultiClassReference(CurMultiClass);
- while (1) {
- // Check for error.
- if (SubMultiClass.MC == 0) return true;
-
- // Add it.
- if (AddSubMultiClass(CurMultiClass, SubMultiClass))
- return true;
-
- if (Lex.getCode() != tgtok::comma) break;
- Lex.Lex(); // eat ','.
- SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
- }
- }
-
- if (Lex.getCode() != tgtok::l_brace) {
- if (!inherits)
- return TokError("expected '{' in multiclass definition");
- else if (Lex.getCode() != tgtok::semi)
- return TokError("expected ';' in multiclass definition");
- else
- Lex.Lex(); // eat the ';'.
- } else {
- if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
- return TokError("multiclass must contain at least one def");
-
- while (Lex.getCode() != tgtok::r_brace) {
- switch (Lex.getCode()) {
- default:
- return TokError("expected 'let', 'def' or 'defm' in multiclass body");
- case tgtok::Let:
- case tgtok::Def:
- case tgtok::Defm:
- if (ParseObject(CurMultiClass))
- return true;
- break;
- }
- }
- Lex.Lex(); // eat the '}'.
- }
-
- CurMultiClass = 0;
- return false;
-}
-
-/// ParseDefm - Parse the instantiation of a multiclass.
-///
-/// DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
-///
-bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
- assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
-
- std::string DefmPrefix;
- if (Lex.Lex() == tgtok::Id) { // eat the defm.
- DefmPrefix = Lex.getCurStrVal();
- Lex.Lex(); // Eat the defm prefix.
- }
-
- SMLoc DefmPrefixLoc = Lex.getLoc();
- if (Lex.getCode() != tgtok::colon)
- return TokError("expected ':' after defm identifier");
-
- // Keep track of the new generated record definitions.
- std::vector<Record*> NewRecDefs;
-
- // This record also inherits from a regular class (non-multiclass)?
- bool InheritFromClass = false;
-
- // eat the colon.
- Lex.Lex();
-
- SMLoc SubClassLoc = Lex.getLoc();
- SubClassReference Ref = ParseSubClassReference(0, true);
-
- while (1) {
- if (Ref.Rec == 0) return true;
-
- // To instantiate a multiclass, we need to first get the multiclass, then
- // instantiate each def contained in the multiclass with the SubClassRef
- // template parameters.
- MultiClass *MC = MultiClasses[Ref.Rec->getName()];
- assert(MC && "Didn't lookup multiclass correctly?");
- std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
-
- // Verify that the correct number of template arguments were specified.
- const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
- if (TArgs.size() < TemplateVals.size())
- return Error(SubClassLoc,
- "more template args specified than multiclass expects");
-
- // Loop over all the def's in the multiclass, instantiating each one.
- for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
- Record *DefProto = MC->DefPrototypes[i];
-
- // Add in the defm name. If the defm prefix is empty, give each
- // instantiated def a unique name. Otherwise, if "#NAME#" exists in the
- // name, substitute the prefix for #NAME#. Otherwise, use the defm name
- // as a prefix.
- std::string DefName = DefProto->getName();
- if (DefmPrefix.empty()) {
- DefName = GetNewAnonymousName();
- } else {
- std::string::size_type idx = DefName.find("#NAME#");
- if (idx != std::string::npos) {
- DefName.replace(idx, 6, DefmPrefix);
- } else {
- // Add the suffix to the defm name to get the new name.
- DefName = DefmPrefix + DefName;
- }
- }
-
- Record *CurRec = new Record(DefName, DefmPrefixLoc, Records);
-
- SubClassReference Ref;
- Ref.RefLoc = DefmPrefixLoc;
- Ref.Rec = DefProto;
- AddSubClass(CurRec, Ref);
-
- // Loop over all of the template arguments, setting them to the specified
- // value or leaving them as the default if necessary.
- for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
- // Check if a value is specified for this temp-arg.
- if (i < TemplateVals.size()) {
- // Set it now.
- if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
- TemplateVals[i]))
- return true;
-
- // Resolve it next.
- CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-
- // Now remove it.
- CurRec->removeValue(TArgs[i]);
-
- } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
- return Error(SubClassLoc,
- "value not specified for template argument #"+
- utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
- MC->Rec.getName() + "'");
- }
- }
-
- // If the mdef is inside a 'let' expression, add to each def.
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
- LetStack[i][j].Bits, LetStack[i][j].Value)) {
- Error(DefmPrefixLoc, "when instantiating this defm");
- return true;
- }
-
- // Ensure redefinition doesn't happen.
- if (Records.getDef(CurRec->getName()))
- return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
- "' already defined, instantiating defm with subdef '" +
- DefProto->getName() + "'");
-
- // Don't create a top level definition for defm inside multiclasses,
- // instead, only update the prototypes and bind the template args
- // with the new created definition.
- if (CurMultiClass) {
- for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size();
- i != e; ++i) {
- if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) {
- Error(DefmPrefixLoc, "defm '" + CurRec->getName() +
- "' already defined in this multiclass!");
- return 0;
- }
- }
- CurMultiClass->DefPrototypes.push_back(CurRec);
-
- // Copy the template arguments for the multiclass into the new def.
- const std::vector<std::string> &TA =
- CurMultiClass->Rec.getTemplateArgs();
-
- for (unsigned i = 0, e = TA.size(); i != e; ++i) {
- const RecordVal *RV = CurMultiClass->Rec.getValue(TA[i]);
- assert(RV && "Template arg doesn't exist?");
- CurRec->addValue(*RV);
- }
- } else {
- Records.addDef(CurRec);
- }
-
- NewRecDefs.push_back(CurRec);
- }
-
- if (Lex.getCode() != tgtok::comma) break;
- Lex.Lex(); // eat ','.
-
- SubClassLoc = Lex.getLoc();
-
- // A defm can inherit from regular classes (non-multiclass) as
- // long as they come in the end of the inheritance list.
- InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != 0);
-
- if (InheritFromClass)
- break;
-
- Ref = ParseSubClassReference(0, true);
- }
-
- if (InheritFromClass) {
- // Process all the classes to inherit as if they were part of a
- // regular 'def' and inherit all record values.
- SubClassReference SubClass = ParseSubClassReference(0, false);
- while (1) {
- // Check for error.
- if (SubClass.Rec == 0) return true;
-
- // Get the expanded definition prototypes and teach them about
- // the record values the current class to inherit has
- for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i) {
- Record *CurRec = NewRecDefs[i];
-
- // Add it.
- if (AddSubClass(CurRec, SubClass))
- return true;
-
- // Process any variables on the let stack.
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
- LetStack[i][j].Bits, LetStack[i][j].Value))
- return true;
- }
-
- if (Lex.getCode() != tgtok::comma) break;
- Lex.Lex(); // eat ','.
- SubClass = ParseSubClassReference(0, false);
- }
- }
-
- if (!CurMultiClass)
- for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i)
- // See Record::setName(). This resolve step will see any new
- // name for the def that might have been created when resolving
- // inheritance, values and arguments above.
- NewRecDefs[i]->resolveReferences();
-
- if (Lex.getCode() != tgtok::semi)
- return TokError("expected ';' at end of defm");
- Lex.Lex();
-
- return false;
-}
-
-/// ParseObject
-/// Object ::= ClassInst
-/// Object ::= DefInst
-/// Object ::= MultiClassInst
-/// Object ::= DefMInst
-/// Object ::= LETCommand '{' ObjectList '}'
-/// Object ::= LETCommand Object
-bool TGParser::ParseObject(MultiClass *MC) {
- switch (Lex.getCode()) {
- default:
- return TokError("Expected class, def, defm, multiclass or let definition");
- case tgtok::Let: return ParseTopLevelLet(MC);
- case tgtok::Def: return ParseDef(MC);
- case tgtok::Defm: return ParseDefm(MC);
- case tgtok::Class: return ParseClass();
- case tgtok::MultiClass: return ParseMultiClass();
- }
-}
-
-/// ParseObjectList
-/// ObjectList :== Object*
-bool TGParser::ParseObjectList(MultiClass *MC) {
- while (isObjectStart(Lex.getCode())) {
- if (ParseObject(MC))
- return true;
- }
- return false;
-}
-
-bool TGParser::ParseFile() {
- Lex.Lex(); // Prime the lexer.
- if (ParseObjectList()) return true;
-
- // If we have unread input at the end of the file, report it.
- if (Lex.getCode() == tgtok::Eof)
- return false;
-
- return TokError("Unexpected input at top level");
-}
-
diff --git a/utils/TableGen/TGParser.h b/utils/TableGen/TGParser.h
deleted file mode 100644
index 8b56b8a329..0000000000
--- a/utils/TableGen/TGParser.h
+++ /dev/null
@@ -1,122 +0,0 @@
-//===- TGParser.h - Parser for TableGen Files -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class represents the Parser for tablegen files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TGPARSER_H
-#define TGPARSER_H
-
-#include "TGLexer.h"
-#include "Error.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/SourceMgr.h"
-#include <map>
-
-namespace llvm {
- class Record;
- class RecordVal;
- class RecordKeeper;
- class RecTy;
- class Init;
- struct MultiClass;
- struct SubClassReference;
- struct SubMultiClassReference;
-
- struct LetRecord {
- std::string Name;
- std::vector<unsigned> Bits;
- Init *Value;
- SMLoc Loc;
- LetRecord(const std::string &N, const std::vector<unsigned> &B, Init *V,
- SMLoc L)
- : Name(N), Bits(B), Value(V), Loc(L) {
- }
- };
-
-class TGParser {
- TGLexer Lex;
- std::vector<std::vector<LetRecord> > LetStack;
- std::map<std::string, MultiClass*> MultiClasses;
-
- /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
- /// current value.
- MultiClass *CurMultiClass;
-
- // Record tracker
- RecordKeeper &Records;
-public:
- TGParser(SourceMgr &SrcMgr, RecordKeeper &records) :
- Lex(SrcMgr), CurMultiClass(0), Records(records) {}
-
- /// ParseFile - Main entrypoint for parsing a tblgen file. These parser
- /// routines return true on error, or false on success.
- bool ParseFile();
-
- bool Error(SMLoc L, const Twine &Msg) const {
- PrintError(L, Msg);
- return true;
- }
- bool TokError(const Twine &Msg) const {
- return Error(Lex.getLoc(), Msg);
- }
- const std::vector<std::string> &getDependencies() const {
- return Lex.getDependencies();
- }
-private: // Semantic analysis methods.
- bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV);
- bool SetValue(Record *TheRec, SMLoc Loc, const std::string &ValName,
- const std::vector<unsigned> &BitList, Init *V);
- bool AddSubClass(Record *Rec, SubClassReference &SubClass);
- bool AddSubMultiClass(MultiClass *CurMC,
- SubMultiClassReference &SubMultiClass);
-
-private: // Parser methods.
- bool ParseObjectList(MultiClass *MC = 0);
- bool ParseObject(MultiClass *MC);
- bool ParseClass();
- bool ParseMultiClass();
- bool ParseDefm(MultiClass *CurMultiClass);
- bool ParseDef(MultiClass *CurMultiClass);
- bool ParseTopLevelLet(MultiClass *CurMultiClass);
- std::vector<LetRecord> ParseLetList();
-
- bool ParseObjectBody(Record *CurRec);
- bool ParseBody(Record *CurRec);
- bool ParseBodyItem(Record *CurRec);
-
- bool ParseTemplateArgList(Record *CurRec);
- std::string ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
-
- SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
- SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
-
- Init *ParseIDValue(Record *CurRec);
- Init *ParseIDValue(Record *CurRec, const std::string &Name, SMLoc NameLoc);
- Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = 0);
- Init *ParseValue(Record *CurRec, RecTy *ItemType = 0);
- std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0, RecTy *EltTy = 0);
- std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
- bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
- bool ParseOptionalBitList(std::vector<unsigned> &Ranges);
- std::vector<unsigned> ParseRangeList();
- bool ParseRangePiece(std::vector<unsigned> &Ranges);
- RecTy *ParseType();
- Init *ParseOperation(Record *CurRec);
- RecTy *ParseOperatorType();
- std::string ParseObjectName();
- Record *ParseClassID();
- MultiClass *ParseMultiClassID();
- Record *ParseDefmID();
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index f060711200..a1cb4272de 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -1,4 +1,4 @@
-//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
+//===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// TableGen is a tool which can be used to build up a description of something,
-// then invoke one or more "tablegen backends" to emit information about the
-// description in some predefined format. In practice, this is used by the LLVM
-// code generators to automate generation of a code generator through a
-// high-level description of the target.
+// This file contains the main function for LLVM's TableGen.
//
//===----------------------------------------------------------------------===//
@@ -26,28 +22,25 @@
#include "DAGISelEmitter.h"
#include "DisassemblerEmitter.h"
#include "EDEmitter.h"
-#include "Error.h"
#include "FastISelEmitter.h"
#include "InstrInfoEmitter.h"
#include "IntrinsicEmitter.h"
#include "NeonEmitter.h"
#include "OptParserEmitter.h"
#include "PseudoLoweringEmitter.h"
-#include "Record.h"
#include "RegisterInfoEmitter.h"
#include "ARMDecoderEmitter.h"
#include "SubtargetEmitter.h"
#include "SetTheory.h"
-#include "TGParser.h"
-#include "llvm/ADT/OwningPtr.h"
+
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/system_error.h"
-#include <algorithm>
-#include <cstdio>
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Main.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenAction.h"
+
using namespace llvm;
enum ActionType {
@@ -173,196 +166,124 @@ namespace {
cl::value_desc("class name"));
cl::opt<std::string>
- OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
- cl::init("-"));
-
- cl::opt<std::string>
- DependFilename("d", cl::desc("Dependency filename"), cl::value_desc("filename"),
- cl::init(""));
-
- cl::opt<std::string>
- InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
-
- cl::list<std::string>
- IncludeDirs("I", cl::desc("Directory of include files"),
- cl::value_desc("directory"), cl::Prefix);
-
- cl::opt<std::string>
ClangComponent("clang-component",
cl::desc("Only use warnings from specified component"),
cl::value_desc("component"), cl::Hidden);
}
-
-int main(int argc, char **argv) {
- RecordKeeper Records;
-
- sys::PrintStackTraceOnErrorSignal();
- PrettyStackTraceProgram X(argc, argv);
- cl::ParseCommandLineOptions(argc, argv);
-
-
- try {
- // Parse the input file.
- OwningPtr<MemoryBuffer> File;
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
- errs() << "Could not open input file '" << InputFilename << "': "
- << ec.message() <<"\n";
- return 1;
- }
- MemoryBuffer *F = File.take();
-
- // Tell SrcMgr about this buffer, which is what TGParser will pick up.
- SrcMgr.AddNewSourceBuffer(F, SMLoc());
-
- // Record the location of the include directory so that the lexer can find
- // it later.
- SrcMgr.setIncludeDirs(IncludeDirs);
-
- TGParser Parser(SrcMgr, Records);
-
- if (Parser.ParseFile())
- return 1;
-
- std::string Error;
- tool_output_file Out(OutputFilename.c_str(), Error);
- if (!Error.empty()) {
- errs() << argv[0] << ": error opening " << OutputFilename
- << ":" << Error << "\n";
- return 1;
- }
- if (!DependFilename.empty()) {
- if (OutputFilename == "-") {
- errs() << argv[0] << ": the option -d must be used together with -o\n";
- return 1;
- }
- tool_output_file DepOut(DependFilename.c_str(), Error);
- if (!Error.empty()) {
- errs() << argv[0] << ": error opening " << DependFilename
- << ":" << Error << "\n";
- return 1;
- }
- DepOut.os() << OutputFilename << ":";
- const std::vector<std::string> &Dependencies = Parser.getDependencies();
- for (std::vector<std::string>::const_iterator I = Dependencies.begin(),
- E = Dependencies.end();
- I != E; ++I) {
- DepOut.os() << " " << (*I);
- }
- DepOut.os() << "\n";
- DepOut.keep();
- }
-
+class LLVMTableGenAction : public TableGenAction {
+public:
+ bool operator()(raw_ostream &OS, RecordKeeper &Records) {
switch (Action) {
case PrintRecords:
- Out.os() << Records; // No argument, dump all contents
+ OS << Records; // No argument, dump all contents
break;
case GenEmitter:
- CodeEmitterGen(Records).run(Out.os());
+ CodeEmitterGen(Records).run(OS);
break;
case GenRegisterInfo:
- RegisterInfoEmitter(Records).run(Out.os());
+ RegisterInfoEmitter(Records).run(OS);
break;
case GenInstrInfo:
- InstrInfoEmitter(Records).run(Out.os());
+ InstrInfoEmitter(Records).run(OS);
break;
case GenCallingConv:
- CallingConvEmitter(Records).run(Out.os());
+ CallingConvEmitter(Records).run(OS);
break;
case GenAsmWriter:
- AsmWriterEmitter(Records).run(Out.os());
+ AsmWriterEmitter(Records).run(OS);
break;
case GenARMDecoder:
- ARMDecoderEmitter(Records).run(Out.os());
+ ARMDecoderEmitter(Records).run(OS);
break;
case GenAsmMatcher:
- AsmMatcherEmitter(Records).run(Out.os());
+ AsmMatcherEmitter(Records).run(OS);
break;
case GenClangAttrClasses:
- ClangAttrClassEmitter(Records).run(Out.os());
+ ClangAttrClassEmitter(Records).run(OS);
break;
case GenClangAttrImpl:
- ClangAttrImplEmitter(Records).run(Out.os());
+ ClangAttrImplEmitter(Records).run(OS);
break;
case GenClangAttrList:
- ClangAttrListEmitter(Records).run(Out.os());
+ ClangAttrListEmitter(Records).run(OS);
break;
case GenClangAttrPCHRead:
- ClangAttrPCHReadEmitter(Records).run(Out.os());
+ ClangAttrPCHReadEmitter(Records).run(OS);
break;
case GenClangAttrPCHWrite:
- ClangAttrPCHWriteEmitter(Records).run(Out.os());
+ ClangAttrPCHWriteEmitter(Records).run(OS);
break;
case GenClangAttrSpellingList:
- ClangAttrSpellingListEmitter(Records).run(Out.os());
+ ClangAttrSpellingListEmitter(Records).run(OS);
break;
case GenClangAttrLateParsedList:
- ClangAttrLateParsedListEmitter(Records).run(Out.os());
+ ClangAttrLateParsedListEmitter(Records).run(OS);
break;
case GenClangDiagsDefs:
- ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os());
+ ClangDiagsDefsEmitter(Records, ClangComponent).run(OS);
break;
case GenClangDiagGroups:
- ClangDiagGroupsEmitter(Records).run(Out.os());
+ ClangDiagGroupsEmitter(Records).run(OS);
break;
case GenClangDiagsIndexName:
- ClangDiagsIndexNameEmitter(Records).run(Out.os());
+ ClangDiagsIndexNameEmitter(Records).run(OS);
break;
case GenClangDeclNodes:
- ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os());
- ClangDeclContextEmitter(Records).run(Out.os());
+ ClangASTNodesEmitter(Records, "Decl", "Decl").run(OS);
+ ClangDeclContextEmitter(Records).run(OS);
break;
case GenClangStmtNodes:
- ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os());
+ ClangASTNodesEmitter(Records, "Stmt", "").run(OS);
break;
case GenClangSACheckers:
- ClangSACheckersEmitter(Records).run(Out.os());
+ ClangSACheckersEmitter(Records).run(OS);
break;
case GenDisassembler:
- DisassemblerEmitter(Records).run(Out.os());
+ DisassemblerEmitter(Records).run(OS);
break;
case GenPseudoLowering:
- PseudoLoweringEmitter(Records).run(Out.os());
+ PseudoLoweringEmitter(Records).run(OS);
break;
case GenOptParserDefs:
- OptParserEmitter(Records, true).run(Out.os());
+ OptParserEmitter(Records, true).run(OS);
break;
case GenOptParserImpl:
- OptParserEmitter(Records, false).run(Out.os());
+ OptParserEmitter(Records, false).run(OS);
break;
case GenDAGISel:
- DAGISelEmitter(Records).run(Out.os());
+ DAGISelEmitter(Records).run(OS);
break;
case GenFastISel:
- FastISelEmitter(Records).run(Out.os());
+ FastISelEmitter(Records).run(OS);
break;
case GenSubtarget:
- SubtargetEmitter(Records).run(Out.os());
+ SubtargetEmitter(Records).run(OS);
break;
case GenIntrinsic:
- IntrinsicEmitter(Records).run(Out.os());
+ IntrinsicEmitter(Records).run(OS);
break;
case GenTgtIntrinsic:
- IntrinsicEmitter(Records, true).run(Out.os());
+ IntrinsicEmitter(Records, true).run(OS);
break;
case GenEDInfo:
- EDEmitter(Records).run(Out.os());
+ EDEmitter(Records).run(OS);
break;
case GenArmNeon:
- NeonEmitter(Records).run(Out.os());
+ NeonEmitter(Records).run(OS);
break;
case GenArmNeonSema:
- NeonEmitter(Records).runHeader(Out.os());
+ NeonEmitter(Records).runHeader(OS);
break;
case GenArmNeonTest:
- NeonEmitter(Records).runTests(Out.os());
+ NeonEmitter(Records).runTests(OS);
break;
case PrintEnums:
{
std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
for (unsigned i = 0, e = Recs.size(); i != e; ++i)
- Out.os() << Recs[i]->getName() << ", ";
- Out.os() << "\n";
+ OS << Recs[i]->getName() << ", ";
+ OS << "\n";
break;
}
case PrintSets:
@@ -371,33 +292,29 @@ int main(int argc, char **argv) {
Sets.addFieldExpander("Set", "Elements");
std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Set");
for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
- Out.os() << Recs[i]->getName() << " = [";
+ OS << Recs[i]->getName() << " = [";
const std::vector<Record*> *Elts = Sets.expand(Recs[i]);
assert(Elts && "Couldn't expand Set instance");
for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei)
- Out.os() << ' ' << (*Elts)[ei]->getName();
- Out.os() << " ]\n";
+ OS << ' ' << (*Elts)[ei]->getName();
+ OS << " ]\n";
}
break;
}
default:
assert(1 && "Invalid Action");
- return 1;
+ return true;
}
- // Declare success.
- Out.keep();
- return 0;
-
- } catch (const TGError &Error) {
- PrintError(Error);
- } catch (const std::string &Error) {
- PrintError(Error);
- } catch (const char *Error) {
- PrintError(Error);
- } catch (...) {
- errs() << argv[0] << ": Unknown unexpected exception occurred.\n";
+ return false;
}
+};
+
+int main(int argc, char **argv) {
+ sys::PrintStackTraceOnErrorSignal();
+ PrettyStackTraceProgram X(argc, argv);
+ cl::ParseCommandLineOptions(argc, argv);
- return 1;
+ LLVMTableGenAction Action;
+ return TableGenMain(argv[0], Action);
}
diff --git a/utils/TableGen/TableGenBackend.cpp b/utils/TableGen/TableGenBackend.cpp
deleted file mode 100644
index b3e33b5f9c..0000000000
--- a/utils/TableGen/TableGenBackend.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//===- TableGenBackend.cpp - Base class for TableGen Backends ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides useful services for TableGen backends...
-//
-//===----------------------------------------------------------------------===//
-
-#include "TableGenBackend.h"
-#include "Record.h"
-using namespace llvm;
-
-void TableGenBackend::EmitSourceFileHeader(const std::string &Desc,
- raw_ostream &OS) const {
- OS << "//===- TableGen'erated file -------------------------------------*-"
- " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate"
- "d file, do not edit!\n//\n//===------------------------------------"
- "----------------------------------===//\n\n";
-}
-
diff --git a/utils/TableGen/TableGenBackend.h b/utils/TableGen/TableGenBackend.h
deleted file mode 100644
index 9c2b948b0d..0000000000
--- a/utils/TableGen/TableGenBackend.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===- TableGenBackend.h - Base class for TableGen Backends -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The TableGenBackend class is provided as a common interface for all TableGen
-// backends. It provides useful services and an standardized interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TABLEGENBACKEND_H
-#define TABLEGENBACKEND_H
-
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-
-namespace llvm {
-
-class Record;
-class RecordKeeper;
-
-struct TableGenBackend {
- virtual ~TableGenBackend() {}
-
- // run - All TableGen backends should implement the run method, which should
- // be the main entry point.
- virtual void run(raw_ostream &OS) = 0;
-
-
-public: // Useful helper routines...
- /// EmitSourceFileHeader - Output a LLVM style file header to the specified
- /// ostream.
- void EmitSourceFileHeader(const std::string &Desc, raw_ostream &OS) const;
-
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp
index b12660eea2..e7b608306c 100644
--- a/utils/TableGen/X86DisassemblerTables.cpp
+++ b/utils/TableGen/X86DisassemblerTables.cpp
@@ -17,7 +17,7 @@
#include "X86DisassemblerShared.h"
#include "X86DisassemblerTables.h"
-#include "TableGenBackend.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h
index 390b89e032..0b600df872 100644
--- a/utils/TableGen/X86RecognizableInstr.h
+++ b/utils/TableGen/X86RecognizableInstr.h
@@ -20,8 +20,8 @@
#include "X86DisassemblerTables.h"
#include "CodeGenTarget.h"
-#include "Record.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/SmallVector.h"