summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-12-01 11:07:05 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-12-01 11:07:05 +0000
commit06f9d4012fb8acea3e9861d5722b5965dbb724d9 (patch)
treeffe0478472eaa0686f11cb02c6df7d257b8719b0 /utils
parent76e2e0ebfdd3d91b07a75822865ea3e9121a99ce (diff)
Notes
Diffstat (limited to 'utils')
-rw-r--r--utils/FileCheck/FileCheck.cpp115
-rw-r--r--utils/TableGen/CMakeLists.txt1
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp1
-rw-r--r--utils/TableGen/DisassemblerEmitter.cpp30
-rw-r--r--utils/TableGen/DisassemblerEmitter.h28
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp3
-rw-r--r--utils/TableGen/OptParserEmitter.cpp13
-rw-r--r--utils/TableGen/Record.cpp190
-rw-r--r--utils/TableGen/Record.h80
-rw-r--r--utils/TableGen/TGParser.cpp379
-rw-r--r--utils/TableGen/TableGen.cpp7
-rwxr-xr-xutils/buildit/build_llvm8
12 files changed, 488 insertions, 367 deletions
diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp
index b4d1f84859cef..078028a115cf2 100644
--- a/utils/FileCheck/FileCheck.cpp
+++ b/utils/FileCheck/FileCheck.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include <algorithm>
using namespace llvm;
@@ -82,10 +83,21 @@ public:
/// variables and is updated if this match defines new values.
size_t Match(StringRef Buffer, size_t &MatchLen,
StringMap<StringRef> &VariableTable) const;
-
+
+ /// PrintFailureInfo - Print additional information about a failure to match
+ /// involving this pattern.
+ void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
+ const StringMap<StringRef> &VariableTable) const;
+
private:
static void AddFixedStringToRegEx(StringRef FixedStr, std::string &TheStr);
bool AddRegExToRegEx(StringRef RegExStr, unsigned &CurParen, SourceMgr &SM);
+
+ /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
+ /// matching this pattern at the start of \arg Buffer; a distance of zero
+ /// should correspond to a perfect match.
+ unsigned ComputeMatchDistance(StringRef Buffer,
+ const StringMap<StringRef> &VariableTable) const;
};
@@ -140,7 +152,7 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
// Named RegEx matches. These are of two forms: [[foo:.*]] which matches .*
// (or some other regex) and assigns it to the FileCheck variable 'foo'. The
// second form is [[foo]] which is a reference to foo. The variable name
- // itself must be of the form "[a-zA-Z][0-9a-zA-Z]*", otherwise we reject
+ // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
// it. This is to catch some common errors.
if (PatternStr.size() >= 2 &&
PatternStr[0] == '[' && PatternStr[1] == '[') {
@@ -167,7 +179,8 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
// Verify that the name is well formed.
for (unsigned i = 0, e = Name.size(); i != e; ++i)
- if ((Name[i] < 'a' || Name[i] > 'z') &&
+ if (Name[i] != '_' &&
+ (Name[i] < 'a' || Name[i] > 'z') &&
(Name[i] < 'A' || Name[i] > 'Z') &&
(Name[i] < '0' || Name[i] > '9')) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
@@ -275,9 +288,15 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
unsigned InsertOffset = 0;
for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
+ StringMap<StringRef>::iterator it =
+ VariableTable.find(VariableUses[i].first);
+ // If the variable is undefined, return an error.
+ if (it == VariableTable.end())
+ return StringRef::npos;
+
// Look up the value and escape it so that we can plop it into the regex.
std::string Value;
- AddFixedStringToRegEx(VariableTable[VariableUses[i].first], Value);
+ AddFixedStringToRegEx(it->second, Value);
// Plop it into the regex at the adjusted offset.
TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset,
@@ -309,6 +328,86 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
return FullMatch.data()-Buffer.data();
}
+unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
+ const StringMap<StringRef> &VariableTable) const {
+ // Just compute the number of matching characters. For regular expressions, we
+ // just compare against the regex itself and hope for the best.
+ //
+ // FIXME: One easy improvement here is have the regex lib generate a single
+ // example regular expression which matches, and use that as the example
+ // string.
+ StringRef ExampleString(FixedStr);
+ if (ExampleString.empty())
+ ExampleString = RegExStr;
+
+ unsigned Distance = 0;
+ for (unsigned i = 0, e = ExampleString.size(); i != e; ++i)
+ if (Buffer.substr(i, 1) != ExampleString.substr(i, 1))
+ ++Distance;
+
+ return Distance;
+}
+
+void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
+ const StringMap<StringRef> &VariableTable) const{
+ // If this was a regular expression using variables, print the current
+ // variable values.
+ if (!VariableUses.empty()) {
+ for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
+ StringRef Var = VariableUses[i].first;
+ StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
+ SmallString<256> Msg;
+ raw_svector_ostream OS(Msg);
+
+ // Check for undefined variable references.
+ if (it == VariableTable.end()) {
+ OS << "uses undefined variable \"";
+ OS.write_escaped(Var) << "\"";;
+ } else {
+ OS << "with variable \"";
+ OS.write_escaped(Var) << "\" equal to \"";
+ OS.write_escaped(it->second) << "\"";
+ }
+
+ SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
+ /*ShowLine=*/false);
+ }
+ }
+
+ // Attempt to find the closest/best fuzzy match. Usually an error happens
+ // because some string in the output didn't exactly match. In these cases, we
+ // would like to show the user a best guess at what "should have" matched, to
+ // save them having to actually check the input manually.
+ size_t NumLinesForward = 0;
+ size_t Best = StringRef::npos;
+ double BestQuality = 0;
+
+ // Use an arbitrary 4k limit on how far we will search.
+ for (size_t i = 0, e = std::min(4096, int(Buffer.size())); i != e; ++i) {
+ if (Buffer[i] == '\n')
+ ++NumLinesForward;
+
+ // Compute the "quality" of this match as an arbitrary combination of the
+ // match distance and the number of lines skipped to get to this match.
+ unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
+ double Quality = Distance + (NumLinesForward / 100.);
+
+ if (Quality < BestQuality || Best == StringRef::npos) {
+ Best = i;
+ BestQuality = Quality;
+ }
+ }
+
+ if (Best != StringRef::npos && BestQuality < 50) {
+ // Print the "possible intended match here" line if we found something
+ // reasonable.
+ SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
+ "possible intended match here", "note");
+
+ // FIXME: If we wanted to be really friendly we would show why the match
+ // failed, as it can be hard to spot simple one character differences.
+ }
+}
//===----------------------------------------------------------------------===//
// Check Strings.
@@ -477,7 +576,8 @@ static bool ReadCheckFile(SourceMgr &SM,
}
static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
- StringRef Buffer) {
+ StringRef Buffer,
+ StringMap<StringRef> &VariableTable) {
// Otherwise, we have an error, emit an error message.
SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
"error");
@@ -488,6 +588,9 @@ static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
"note");
+
+ // Allow the pattern to print additional information if desired.
+ CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable);
}
/// CountNumNewlinesBetween - Count the number of newlines in the specified
@@ -558,7 +661,7 @@ int main(int argc, char **argv) {
// If we didn't find a match, reject the input.
if (Buffer.empty()) {
- PrintCheckFailed(SM, CheckStr, SearchFrom);
+ PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
return 1;
}
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt
index d9ec6f7d1a1d8..daf867682656c 100644
--- a/utils/TableGen/CMakeLists.txt
+++ b/utils/TableGen/CMakeLists.txt
@@ -8,6 +8,7 @@ add_executable(tblgen
CodeGenInstruction.cpp
CodeGenTarget.cpp
DAGISelEmitter.cpp
+ DisassemblerEmitter.cpp
FastISelEmitter.cpp
InstrEnumEmitter.cpp
InstrInfoEmitter.cpp
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 0c78f56404fc7..66debe2e1deb8 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1947,7 +1947,6 @@ void DAGISelEmitter::EmitInstructionSelector(raw_ostream &OS) {
<< " return NULL;\n"
<< " }\n"
<< " case ISD::INLINEASM: return Select_INLINEASM(N);\n"
- << " case ISD::DBG_LABEL: return Select_DBG_LABEL(N);\n"
<< " case ISD::EH_LABEL: return Select_EH_LABEL(N);\n"
<< " case ISD::UNDEF: return Select_UNDEF(N);\n";
diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp
new file mode 100644
index 0000000000000..cc131257cffd4
--- /dev/null
+++ b/utils/TableGen/DisassemblerEmitter.cpp
@@ -0,0 +1,30 @@
+//===- DisassemblerEmitter.cpp - Generate a disassembler ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DisassemblerEmitter.h"
+#include "CodeGenTarget.h"
+#include "Record.h"
+using namespace llvm;
+
+void DisassemblerEmitter::run(raw_ostream &OS) {
+ CodeGenTarget Target;
+
+ OS << "/*===- TableGen'erated file "
+ << "---------------------------------------*- C -*-===*\n"
+ << " *\n"
+ << " * " << Target.getName() << " Disassembler\n"
+ << " *\n"
+ << " * Automatically generated file, do not edit!\n"
+ << " *\n"
+ << " *===---------------------------------------------------------------"
+ << "-------===*/\n";
+
+ throw TGError(Target.getTargetRecord()->getLoc(),
+ "Unable to generate disassembler for this target");
+}
diff --git a/utils/TableGen/DisassemblerEmitter.h b/utils/TableGen/DisassemblerEmitter.h
new file mode 100644
index 0000000000000..7229d81649eed
--- /dev/null
+++ b/utils/TableGen/DisassemblerEmitter.h
@@ -0,0 +1,28 @@
+//===- DisassemblerEmitter.h - Disassembler Generator -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DISASSEMBLEREMITTER_H
+#define DISASSEMBLEREMITTER_H
+
+#include "TableGenBackend.h"
+
+namespace llvm {
+
+ class DisassemblerEmitter : public TableGenBackend {
+ RecordKeeper &Records;
+ public:
+ DisassemblerEmitter(RecordKeeper &R) : Records(R) {}
+
+ /// run - Output the disassembler.
+ void run(raw_ostream &o);
+ };
+
+} // end llvm namespace
+
+#endif
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index 546988a10e4d1..8b55b81eae46d 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -1155,6 +1155,9 @@ public:
if (OptName == "o") {
O << Neg << "OutputFilename.empty()";
}
+ else if (OptName == "save-temps") {
+ O << Neg << "(SaveTemps == SaveTempsEnum::Unset)";
+ }
else {
const OptionDescription& OptDesc = OptDescs_.FindListOrParameter(OptName);
O << Neg << OptDesc.GenVariableName() << ".empty()";
diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp
index a09ba083f3e03..ce1aef5e4dadd 100644
--- a/utils/TableGen/OptParserEmitter.cpp
+++ b/utils/TableGen/OptParserEmitter.cpp
@@ -35,9 +35,16 @@ static int CompareOptionRecords(const void *Av, const void *Bv) {
const Record *A = *(Record**) Av;
const Record *B = *(Record**) Bv;
- // Compare options by name first.
- if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
- B->getValueAsString("Name").c_str()))
+ // Sentinel options preceed all others and are only ordered by precedence.
+ bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");
+ bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel");
+ if (ASent != BSent)
+ return ASent ? -1 : 1;
+
+ // Compare options by name, unless they are sentinels.
+ if (!ASent)
+ if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
+ B->getValueAsString("Name").c_str()))
return Cmp;
// Then by the kind precedence;
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index 25fe5c4ddf348..53f90146a75a2 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -274,7 +274,7 @@ bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
}
-/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// 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) {
@@ -284,7 +284,8 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
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();
+ const std::vector<Record *> &T1SuperClasses =
+ RecTy1->getRecord()->getSuperClasses();
for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
iend = T1SuperClasses.end();
i != iend;
@@ -302,8 +303,9 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
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(),
+ const std::vector<Record *> &T2SuperClasses =
+ RecTy2->getRecord()->getSuperClasses();
+ for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
iend = T2SuperClasses.end();
i != iend;
++i) {
@@ -344,10 +346,6 @@ Init *BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
}
std::string BitsInit::getAsString() const {
- //if (!printInHex(OS)) return;
- //if (!printAsVariable(OS)) return;
- //if (!printAsUnset(OS)) return;
-
std::string Result = "{ ";
for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
if (i) Result += ", ";
@@ -359,51 +357,6 @@ std::string BitsInit::getAsString() const {
return Result + " }";
}
-bool BitsInit::printInHex(raw_ostream &OS) const {
- // First, attempt to convert the value into an integer value...
- int64_t Result = 0;
- for (unsigned i = 0, e = getNumBits(); i != e; ++i)
- if (BitInit *Bit = dynamic_cast<BitInit*>(getBit(i))) {
- Result |= Bit->getValue() << i;
- } else {
- return true;
- }
-
- OS << format("0x%x", Result);
- return false;
-}
-
-bool BitsInit::printAsVariable(raw_ostream &OS) const {
- // Get the variable that we may be set equal to...
- assert(getNumBits() != 0);
- VarBitInit *FirstBit = dynamic_cast<VarBitInit*>(getBit(0));
- if (FirstBit == 0) return true;
- TypedInit *Var = FirstBit->getVariable();
-
- // Check to make sure the types are compatible.
- BitsRecTy *Ty = dynamic_cast<BitsRecTy*>(FirstBit->getVariable()->getType());
- if (Ty == 0) return true;
- if (Ty->getNumBits() != getNumBits()) return true; // Incompatible types!
-
- // Check to make sure all bits are referring to the right bits in the variable
- for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
- VarBitInit *Bit = dynamic_cast<VarBitInit*>(getBit(i));
- if (Bit == 0 || Bit->getVariable() != Var || Bit->getBitNum() != i)
- return true;
- }
-
- Var->print(OS);
- return false;
-}
-
-bool BitsInit::printAsUnset(raw_ostream &OS) const {
- for (unsigned i = 0, e = getNumBits(); i != e; ++i)
- if (!dynamic_cast<UnsetInit*>(getBit(i)))
- return true;
- OS << "?";
- return false;
-}
-
// resolveReferences - If there are any field references that refer to fields
// that have been filled in, we can propagate the values now.
//
@@ -486,12 +439,15 @@ Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
}
Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
- unsigned Elt) {
+ unsigned Elt) {
if (Elt >= getSize())
return 0; // Out of range reference.
Init *E = getElement(Elt);
- if (!dynamic_cast<UnsetInit*>(E)) // If the element is set
- return E; // Replace the VarListElementInit with it.
+ // 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;
}
@@ -505,30 +461,30 @@ std::string ListInit::getAsString() const {
}
Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV,
- unsigned Bit) {
+ unsigned Bit) {
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) {
+ unsigned Elt) {
Init *Folded = Fold(&R, 0);
if (Folded != this) {
TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
if (Typed) {
return Typed->resolveListElementReference(R, IRV, Elt);
- }
+ }
}
-
+
return 0;
}
@@ -546,8 +502,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (LHSd) {
return new StringInit(LHSd->getDef()->getName());
}
- }
- else {
+ } else {
StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
if (LHSs) {
std::string Name = LHSs->getValue();
@@ -579,15 +534,15 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
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 nameconcat";
}
-
+
return new VarInit(MCName, RV->getType());
}
}
-
+
if (Record *D = Records.getDef(Name))
return new DefInit(D);
@@ -616,7 +571,8 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
assert(0 && "Empty list in cdr");
return 0;
}
- ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(), LHSl->getType());
+ ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(),
+ LHSl->getType());
return Result;
}
break;
@@ -626,8 +582,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (LHSl) {
if (LHSl->getSize() == 0) {
return new IntInit(1);
- }
- else {
+ } else {
return new IntInit(0);
}
}
@@ -635,12 +590,11 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (LHSs) {
if (LHSs->getValue().empty()) {
return new IntInit(1);
- }
- else {
+ } else {
return new IntInit(0);
}
}
-
+
break;
}
}
@@ -649,7 +603,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
Init *lhs = LHS->resolveReferences(R, RV);
-
+
if (LHS != lhs)
return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
return Fold(&R, 0);
@@ -739,7 +693,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
}
return new VarInit(Name, RV->getType());
}
-
+
std::string TemplateArgName = CurRec->getName()+":"+Name;
if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName);
@@ -762,7 +716,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (RV->getType() != getType()) {
throw "type mismatch in nameconcat";
}
-
+
return new VarInit(MCName, RV->getType());
}
}
@@ -801,7 +755,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
Init *lhs = LHS->resolveReferences(R, RV);
Init *rhs = RHS->resolveReferences(R, RV);
-
+
if (LHS != lhs || RHS != rhs)
return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
return Fold(&R, 0);
@@ -815,7 +769,7 @@ std::string BinOpInit::getAsString() const {
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
case STRCONCAT: Result = "!strconcat"; break;
- case NAMECONCAT:
+ case NAMECONCAT:
Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
}
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
@@ -837,8 +791,7 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
CurRec, CurMultiClass);
if (Result != 0) {
return Result;
- }
- else {
+ } else {
return 0;
}
}
@@ -851,15 +804,12 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg,
Type, CurRec, CurMultiClass);
if (Result != 0) {
NewOperands.push_back(Result);
- }
- else {
+ } else {
NewOperands.push_back(Arg);
}
- }
- else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+ } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
NewOperands.push_back(Arg);
- }
- else {
+ } else {
NewOperands.push_back(RHSo->getOperand(i));
}
}
@@ -939,8 +889,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
// First, replace the foreach variable with the list item
if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
NewOperands.push_back(Item);
- }
- else {
+ } else {
NewOperands.push_back(RHSo->getOperand(i));
}
}
@@ -1007,7 +956,7 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
}
}
break;
- }
+ }
case FOREACH: {
Init *Result = ForeachHelper(LHS, MHS, RHS, getType(),
@@ -1023,8 +972,7 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (LHSi) {
if (LHSi->getValue()) {
return MHS;
- }
- else {
+ } else {
return RHS;
}
}
@@ -1044,15 +992,16 @@ Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
// Short-circuit
if (Value->getValue()) {
Init *mhs = MHS->resolveReferences(R, RV);
- return (new TernOpInit(getOpcode(), lhs, mhs, RHS, getType()))->Fold(&R, 0);
- }
- else {
+ return (new TernOpInit(getOpcode(), lhs, mhs,
+ RHS, getType()))->Fold(&R, 0);
+ } else {
Init *rhs = RHS->resolveReferences(R, RV);
- return (new TernOpInit(getOpcode(), lhs, MHS, rhs, getType()))->Fold(&R, 0);
+ return (new TernOpInit(getOpcode(), lhs, MHS,
+ rhs, getType()))->Fold(&R, 0);
}
}
}
-
+
Init *mhs = MHS->resolveReferences(R, RV);
Init *rhs = RHS->resolveReferences(R, RV);
@@ -1065,10 +1014,10 @@ 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;
+ case FOREACH: Result = "!foreach"; break;
+ case IF: Result = "!if"; break;
}
- return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
+ return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
+ RHS->getAsString() + ")";
}
@@ -1109,15 +1058,18 @@ Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV,
if (IRV && IRV->getName() != getName()) return 0;
RecordVal *RV = R.getValue(getName());
- assert(RV && "Reference to a non-existant variable?");
+ 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 (!dynamic_cast<UnsetInit*>(B)) // If the bit is not set...
- return B; // Replace the VarBitInit with it.
+ // 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;
}
@@ -1127,19 +1079,22 @@ Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV,
if (IRV && IRV->getName() != getName()) return 0;
RecordVal *RV = R.getValue(getName());
- assert(RV && "Reference to a non-existant variable?");
+ 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 new VarListElementInit(VI, Elt);
}
-
+
if (Elt >= LI->getSize())
return 0; // Out of range reference.
Init *E = LI->getElement(Elt);
- if (!dynamic_cast<UnsetInit*>(E)) // If the element is set
- return E; // Replace the VarListElementInit with it.
+ // 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;
}
@@ -1165,7 +1120,7 @@ Init *VarInit::getFieldInit(Record &R, 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.
+/// 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.
///
@@ -1246,8 +1201,11 @@ Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV,
if (Elt >= LI->getSize()) return 0;
Init *E = LI->getElement(Elt);
- if (!dynamic_cast<UnsetInit*>(E)) // If the bit is set...
- return E; // Replace the VarListElementInit with it.
+ // 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;
}
@@ -1271,12 +1229,12 @@ Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) {
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 new DagInit(Op, "", NewArgs, ArgNames);
-
+
return this;
}
@@ -1445,7 +1403,7 @@ ListInit *Record::getValueAsListInit(StringRef FieldName) const {
/// 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*>
+std::vector<Record*>
Record::getValueAsListOfDefs(StringRef FieldName) const {
ListInit *List = getValueAsListInit(FieldName);
std::vector<Record*> Defs;
@@ -1480,7 +1438,7 @@ int64_t Record::getValueAsInt(StringRef FieldName) const {
/// 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>
+std::vector<int64_t>
Record::getValueAsListOfInts(StringRef FieldName) const {
ListInit *List = getValueAsListInit(FieldName);
std::vector<int64_t> Ints;
@@ -1548,7 +1506,7 @@ std::string Record::getValueAsCode(StringRef FieldName) const {
if (R == 0 || R->getValue() == 0)
throw "Record `" + getName() + "' does not have a field named `" +
FieldName.str() + "'!\n";
-
+
if (const CodeInit *CI = dynamic_cast<const CodeInit*>(R->getValue()))
return CI->getValue();
throw "Record `" + getName() + "', field `" + FieldName.str() +
@@ -1559,7 +1517,7 @@ std::string Record::getValueAsCode(StringRef FieldName) const {
void MultiClass::dump() const {
errs() << "Record:\n";
Rec.dump();
-
+
errs() << "Defs:\n";
for (RecordVector::const_iterator r = DefPrototypes.begin(),
rend = DefPrototypes.end();
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 752bd0cdfc787..278c349dd65e5 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -22,7 +22,7 @@
namespace llvm {
class raw_ostream;
-
+
// RecTy subclasses.
class BitRecTy;
class BitsRecTy;
@@ -443,7 +443,7 @@ public:
virtual bool baseClassOf(const RecordRecTy *RHS) const;
};
-/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// resolveTypes - Find a common type that T1 and T2 convert to.
/// Return 0 if no such type exists.
///
RecTy *resolveTypes(RecTy *T1, RecTy *T2);
@@ -508,7 +508,7 @@ struct Init {
}
/// resolveReferences - This method is used by classes that refer to other
- /// variables which may not be defined at the time they expression is formed.
+ /// 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.
///
@@ -611,12 +611,6 @@ public:
virtual std::string getAsString() const;
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
- // printXX - Print this bitstream with the specified format, returning true if
- // it is not possible.
- bool printInHex(raw_ostream &OS) const;
- bool printAsVariable(raw_ostream &OS) const;
- bool printAsUnset(raw_ostream &OS) const;
};
@@ -731,7 +725,7 @@ public:
}
Record *getElementAsRecord(unsigned i) const;
-
+
Init *convertInitListSlice(const std::vector<unsigned> &Elements);
virtual Init *convertInitializerTo(RecTy *Ty) {
@@ -792,7 +786,7 @@ public:
virtual Init *convertInitializerTo(RecTy *Ty) {
return Ty->convertValue(this);
}
-
+
virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
unsigned Bit);
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
@@ -825,7 +819,7 @@ public:
assert(i == 0 && "Invalid operand id for unary operator");
return getOperand();
}
-
+
UnaryOp getOpcode() const { return Opc; }
Init *getOperand() const { return LHS; }
@@ -834,7 +828,7 @@ public:
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
+
/// 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.
@@ -856,7 +850,7 @@ public:
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
}
-
+
// Clone - Clone this operator, replacing arguments with the new list
virtual OpInit *clone(std::vector<Init *> &Operands) {
assert(Operands.size() == 2 &&
@@ -869,8 +863,7 @@ public:
assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
if (i == 0) {
return getLHS();
- }
- else {
+ } else {
return getRHS();
}
}
@@ -884,7 +877,7 @@ public:
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
+
virtual std::string getAsString() const;
};
@@ -900,7 +893,7 @@ public:
TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
}
-
+
// Clone - Clone this operator, replacing arguments with the new list
virtual OpInit *clone(std::vector<Init *> &Operands) {
assert(Operands.size() == 3 &&
@@ -915,11 +908,9 @@ public:
"Invalid operand id for ternary operator");
if (i == 0) {
return getLHS();
- }
- else if (i == 1) {
+ } else if (i == 1) {
return getMHS();
- }
- else {
+ } else {
return getRHS();
}
}
@@ -932,9 +923,9 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
-
+
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
+
virtual std::string getAsString() const;
};
@@ -1106,7 +1097,7 @@ class DagInit : public TypedInit {
std::vector<Init*> Args;
std::vector<std::string> ArgNames;
public:
- DagInit(Init *V, std::string VN,
+ DagInit(Init *V, std::string VN,
const std::vector<std::pair<Init*, std::string> > &args)
: TypedInit(new DagRecTy), Val(V), ValName(VN) {
Args.reserve(args.size());
@@ -1116,11 +1107,11 @@ public:
ArgNames.push_back(args[i].second);
}
}
- DagInit(Init *V, std::string VN, const std::vector<Init*> &args,
+ DagInit(Init *V, std::string VN, const std::vector<Init*> &args,
const std::vector<std::string> &argNames)
- : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args), ArgNames(argNames) {
- }
-
+ : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args),
+ ArgNames(argNames) { }
+
virtual Init *convertInitializerTo(RecTy *Ty) {
return Ty->convertValue(this);
}
@@ -1143,7 +1134,7 @@ public:
assert(Num < Args.size() && "Arg number out of range!");
Args[Num] = I;
}
-
+
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
virtual std::string getAsString() const;
@@ -1174,13 +1165,12 @@ public:
assert(0 && "Illegal bit reference off dag");
return 0;
}
-
+
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
unsigned Elt) {
assert(0 && "Illegal element reference off dag");
return 0;
}
-
};
//===----------------------------------------------------------------------===//
@@ -1231,17 +1221,17 @@ class Record {
std::vector<Record*> SuperClasses;
public:
- explicit Record(const std::string &N, SMLoc loc) :
+ explicit Record(const std::string &N, SMLoc loc) :
ID(LastID++), Name(N), Loc(loc) {}
~Record() {}
-
+
unsigned getID() const { return ID; }
const std::string &getName() const { return Name; }
void setName(const std::string &Name); // Also updates RecordKeeper.
-
+
SMLoc getLoc() const { return Loc; }
-
+
const std::vector<std::string> &getTemplateArgs() const {
return TemplateArgs;
}
@@ -1276,13 +1266,12 @@ public:
}
void removeValue(StringRef Name) {
- assert(getValue(Name) && "Cannot remove an entry that does not exist!");
for (unsigned i = 0, e = Values.size(); i != e; ++i)
if (Values[i].getName() == Name) {
Values.erase(Values.begin()+i);
return;
}
- assert(0 && "Name does not exist in record!");
+ assert(0 && "Cannot remove an entry that does not exist!");
}
bool isSubClassOf(const Record *R) const {
@@ -1354,7 +1343,7 @@ public:
/// not exist or if the value is not the right type.
///
std::vector<int64_t> getValueAsListOfInts(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.
@@ -1378,7 +1367,7 @@ public:
/// 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.
@@ -1442,7 +1431,7 @@ public:
assert(Defs.count(Name) && "Def does not exist!");
Defs.erase(Name);
}
-
+
//===--------------------------------------------------------------------===//
// High-level helper methods, useful for tablegen backends...
@@ -1464,7 +1453,7 @@ struct LessRecord {
}
};
-/// LessRecordFieldName - Sorting predicate to sort record pointers by their
+/// LessRecordFieldName - Sorting predicate to sort record pointers by their
/// name field.
///
struct LessRecordFieldName {
@@ -1479,19 +1468,18 @@ class TGError {
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; }
};
-
-
+
+
raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
extern RecordKeeper Records;
void PrintError(SMLoc ErrorLoc, const std::string &Msg);
-
} // End llvm namespace
#endif
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index 712226500540c..b095a6c30148a 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -44,9 +44,9 @@ struct SubMultiClassReference {
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();
@@ -61,13 +61,13 @@ void SubMultiClassReference::dump() const {
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 '" +
+ "previous definition of type '" +
ERV->getType()->getAsString() + "'");
} else {
CurRec->addValue(RV);
@@ -77,7 +77,7 @@ bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
/// SetValue -
/// Return true on error, false on success.
-bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
+bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
const std::vector<unsigned> &BitList, Init *V) {
if (!V) return false;
@@ -93,7 +93,7 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
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.
@@ -109,7 +109,7 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
V->convertInitializerTo(new BitsRecTy(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);
@@ -133,8 +133,8 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName,
}
if (RV->setValue(V))
- return Error(Loc, "Value '" + ValName + "' of type '" +
- RV->getType()->getAsString() +
+ return Error(Loc, "Value '" + ValName + "' of type '" +
+ RV->getType()->getAsString() +
"' is incompatible with initializer '" + V->getAsString() +"'");
return false;
}
@@ -154,25 +154,25 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
// 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>(),
+ 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 '" +
+ + utostr(i) + " (" + TArgs[i] + ") of subclass '" +
SC->getName() + "'!");
}
}
@@ -186,7 +186,7 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
"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");
@@ -291,7 +291,7 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
/// 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;
+ K == tgtok::Defm || K == tgtok::Let || K == tgtok::MultiClass;
}
/// ParseObjectName - If an object name is specified, return it. Otherwise,
@@ -305,7 +305,7 @@ std::string TGParser::ParseObjectName() {
Lex.Lex();
return Ret;
}
-
+
static unsigned AnonCounter = 0;
return "anonymous."+utostr(AnonCounter++);
}
@@ -321,11 +321,11 @@ Record *TGParser::ParseClassID() {
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;
}
@@ -354,17 +354,16 @@ Record *TGParser::ParseDefmID() {
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
@@ -377,37 +376,37 @@ 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;
}
@@ -464,12 +463,12 @@ bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
}
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:
+ default:
Ranges.push_back(Start);
return false;
case tgtok::minus:
@@ -483,10 +482,10 @@ bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
End = -Lex.getCurIntVal();
break;
}
- if (End < 0)
+ if (End < 0)
return TokError("invalid range, cannot be negative");
Lex.Lex();
-
+
// Add to the range.
if (Start < End) {
for (; Start <= End; ++Start)
@@ -504,7 +503,7 @@ bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
///
std::vector<unsigned> TGParser::ParseRangeList() {
std::vector<unsigned> Result;
-
+
// Parse the first piece.
if (ParseRangePiece(Result))
return std::vector<unsigned>();
@@ -524,14 +523,14 @@ std::vector<unsigned> TGParser::ParseRangeList() {
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 '<'");
@@ -546,14 +545,14 @@ bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
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 '{'");
@@ -610,7 +609,7 @@ RecTy *TGParser::ParseType() {
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;
@@ -618,7 +617,7 @@ RecTy *TGParser::ParseType() {
Lex.Lex(); // Eat '>'
return new ListRecTy(SubType);
}
- }
+ }
}
/// ParseIDValue - Parse an ID as a value and decode what it means.
@@ -639,12 +638,12 @@ Init *TGParser::ParseIDValue(Record *CurRec) {
/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
/// has already been read.
-Init *TGParser::ParseIDValue(Record *CurRec,
+Init *TGParser::ParseIDValue(Record *CurRec,
const std::string &Name, SMLoc NameLoc) {
if (CurRec) {
if (const RecordVal *RV = CurRec->getValue(Name))
return new VarInit(Name, RV->getType());
-
+
std::string TemplateArgName = CurRec->getName()+":"+Name;
if (CurRec->isTemplateArg(TemplateArgName)) {
const RecordVal *RV = CurRec->getValue(TemplateArgName);
@@ -652,7 +651,7 @@ Init *TGParser::ParseIDValue(Record *CurRec,
return new VarInit(TemplateArgName, RV->getType());
}
}
-
+
if (CurMultiClass) {
std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
if (CurMultiClass->Rec.isTemplateArg(MCName)) {
@@ -661,7 +660,7 @@ Init *TGParser::ParseIDValue(Record *CurRec,
return new VarInit(MCName, RV->getType());
}
}
-
+
if (Record *D = Records.getDef(Name))
return new DefInit(D);
@@ -748,7 +747,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
TokError("expected list type argumnet in unary operator");
return 0;
}
-
+
if (LHSl && LHSl->getSize() == 0) {
TokError("empty list argument in unary operator");
return 0;
@@ -762,12 +761,10 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
if (Code == UnOpInit::CAR) {
Type = Itemt->getType();
- }
- else {
+ } else {
Type = new ListRecTy(Itemt->getType());
}
- }
- else {
+ } else {
assert(LHSt && "expected list type argument in unary operator");
ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
if (LType == 0) {
@@ -776,8 +773,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
if (Code == UnOpInit::CAR) {
Type = LType->getElementType();
- }
- else {
+ } else {
Type = LType;
}
}
@@ -793,7 +789,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
case tgtok::XConcat:
- case tgtok::XSRA:
+ case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
case tgtok::XStrConcat:
@@ -804,32 +800,32 @@ Init *TGParser::ParseOperation(Record *CurRec) {
switch (Lex.getCode()) {
default: assert(0 && "Unhandled code!");
- case tgtok::XConcat:
+ case tgtok::XConcat:
Lex.Lex(); // eat the operation
Code = BinOpInit::CONCAT;
Type = new DagRecTy();
break;
- case tgtok::XSRA:
+ case tgtok::XSRA:
Lex.Lex(); // eat the operation
Code = BinOpInit::SRA;
Type = new IntRecTy();
break;
- case tgtok::XSRL:
+ case tgtok::XSRL:
Lex.Lex(); // eat the operation
Code = BinOpInit::SRL;
Type = new IntRecTy();
break;
- case tgtok::XSHL:
+ case tgtok::XSHL:
Lex.Lex(); // eat the operation
Code = BinOpInit::SHL;
Type = new IntRecTy();
break;
- case tgtok::XStrConcat:
+ case tgtok::XStrConcat:
Lex.Lex(); // eat the operation
Code = BinOpInit::STRCONCAT;
Type = new StringRecTy();
break;
- case tgtok::XNameConcat:
+ case tgtok::XNameConcat:
Lex.Lex(); // eat the operation
Code = BinOpInit::NAMECONCAT;
@@ -856,7 +852,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ','
-
+
Init *RHS = ParseValue(CurRec);
if (RHS == 0) return 0;
@@ -903,7 +899,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ','
-
+
Init *MHS = ParseValue(CurRec);
if (MHS == 0) return 0;
@@ -912,7 +908,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ','
-
+
Init *RHS = ParseValue(CurRec);
if (RHS == 0) return 0;
@@ -933,11 +929,9 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
if (MHSt->getType()->typeIsConvertibleTo(RHSt->getType())) {
Type = RHSt->getType();
- }
- else if (RHSt->getType()->typeIsConvertibleTo(MHSt->getType())) {
+ } else if (RHSt->getType()->typeIsConvertibleTo(MHSt->getType())) {
Type = MHSt->getType();
- }
- else {
+ } else {
TokError("inconsistent types for !if");
return 0;
}
@@ -962,7 +956,8 @@ Init *TGParser::ParseOperation(Record *CurRec) {
break;
}
}
- return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+ return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec,
+ CurMultiClass);
}
}
TokError("could not parse operation");
@@ -1025,25 +1020,25 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
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 = new StringInit(Val);
break;
}
case tgtok::CodeFragment:
- R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break;
+ R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break;
case tgtok::question: R = new UnsetInit(); 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");
@@ -1061,13 +1056,13 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
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);
@@ -1080,15 +1075,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
return 0;
NewRec->resolveReferences();
Records.addDef(NewRec);
-
+
// The result of the expression is a reference to the new record.
return new DefInit(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;
@@ -1098,7 +1093,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
return 0;
}
Lex.Lex(); // eat the '}'
-
+
BitsInit *Result = new BitsInit(Vals.size());
for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
Init *Bit = Vals[i]->convertInitializerTo(new BitRecTy());
@@ -1114,23 +1109,24 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
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 "
+ s << "Type mismatch for list, expected list type, got "
<< ItemType->getAsString();
TokError(s.str());
}
GivenListTy = ListType;
- }
+ }
if (Lex.getCode() != tgtok::r_square) {
- Vals = ParseValueList(CurRec, 0, GivenListTy ? GivenListTy->getElementType() : 0);
+ Vals = ParseValueList(CurRec, 0,
+ GivenListTy ? GivenListTy->getElementType() : 0);
if (Vals.empty()) return 0;
}
if (Lex.getCode() != tgtok::r_square) {
@@ -1173,8 +1169,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
TokError("Incompatible types in list elements");
return 0;
}
- }
- else {
+ } else {
EltTy = TArg->getType();
}
}
@@ -1196,8 +1191,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
return 0;
}
DeducedEltTy = GivenListTy->getElementType();
- }
- else {
+ } else {
// Make sure the deduced type is compatible with the given type
if (GivenListTy) {
if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
@@ -1207,7 +1201,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
}
DeducedEltTy = EltTy;
}
-
+
return new ListInit(Vals, DeducedEltTy);
}
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
@@ -1218,13 +1212,12 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
TokError("expected identifier in dag init");
return 0;
}
-
+
Init *Operator = 0;
if (Lex.getCode() == tgtok::Id) {
Operator = ParseIDValue(CurRec);
if (Operator == 0) return 0;
- }
- else {
+ } else {
Operator = ParseOperation(CurRec);
if (Operator == 0) return 0;
}
@@ -1239,29 +1232,29 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
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 new DagInit(Operator, OperatorName, DagArgs);
break;
}
-
+
case tgtok::XCar:
case tgtok::XCdr:
case tgtok::XNull:
case tgtok::XCast: // Value ::= !unop '(' Value ')'
case tgtok::XConcat:
- case tgtok::XSRA:
+ case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
case tgtok::XStrConcat:
@@ -1273,7 +1266,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
break;
}
}
-
+
return R;
}
@@ -1287,7 +1280,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
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()) {
@@ -1297,7 +1290,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
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);
@@ -1305,7 +1298,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
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");
@@ -1319,13 +1312,13 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
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");
@@ -1355,14 +1348,14 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
///
/// ParseDagArgList ::= Value (':' VARNAME)?
/// ParseDagArgList ::= ParseDagArgList ',' Value (':' VARNAME)?
-std::vector<std::pair<llvm::Init*, std::string> >
+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) {
@@ -1373,13 +1366,13 @@ TGParser::ParseDagArgList(Record *CurRec) {
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 ','
+ Lex.Lex(); // eat the ','
}
-
+
return Result;
}
@@ -1390,7 +1383,8 @@ TGParser::ParseDagArgList(Record *CurRec) {
///
/// ValueList ::= Value (',' Value)
///
-std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, RecTy *EltTy) {
+std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec,
+ RecTy *EltTy) {
std::vector<Init*> Result;
RecTy *ItemType = EltTy;
unsigned int ArgN = 0;
@@ -1403,16 +1397,16 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, Rec
}
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();
@@ -1421,12 +1415,11 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, Rec
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
@@ -1437,24 +1430,24 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, Rec
///
/// Declaration ::= FIELD? Type ID ('=' Value)?
///
-std::string TGParser::ParseDeclaration(Record *CurRec,
+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;
@@ -1464,11 +1457,11 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
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();
@@ -1478,7 +1471,7 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
return "";
}
-
+
return DeclName;
}
@@ -1488,30 +1481,30 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
/// 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 '>'.
@@ -1525,9 +1518,9 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
/// BodyItem ::= LET ID OptionalBitList '=' Value ';'
bool TGParser::ParseBodyItem(Record *CurRec) {
if (Lex.getCode() != tgtok::Let) {
- if (ParseDeclaration(CurRec, false).empty())
+ if (ParseDeclaration(CurRec, false).empty())
return true;
-
+
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' after declaration");
Lex.Lex();
@@ -1537,33 +1530,33 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
// 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))
+ 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);
}
@@ -1580,12 +1573,12 @@ bool TGParser::ParseBody(Record *CurRec) {
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;
@@ -1608,17 +1601,17 @@ 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);
@@ -1631,7 +1624,7 @@ bool TGParser::ParseObjectBody(Record *CurRec) {
if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
LetStack[i][j].Bits, LetStack[i][j].Value))
return true;
-
+
return ParseBody(CurRec);
}
@@ -1644,14 +1637,14 @@ bool TGParser::ParseObjectBody(Record *CurRec) {
llvm::Record *TGParser::ParseDef(MultiClass *CurMultiClass) {
SMLoc DefLoc = Lex.getLoc();
assert(Lex.getCode() == tgtok::Def && "Unknown tok");
- Lex.Lex(); // Eat the 'def' token.
+ Lex.Lex(); // Eat the 'def' token.
// Parse ObjectName and make a record for it.
Record *CurRec = new Record(ParseObjectName(), DefLoc);
-
+
if (!CurMultiClass) {
// Top-level def definition.
-
+
// Ensure redefinition doesn't happen.
if (Records.getDef(CurRec->getName())) {
Error(DefLoc, "def '" + CurRec->getName() + "' already defined");
@@ -1668,13 +1661,13 @@ llvm::Record *TGParser::ParseDef(MultiClass *CurMultiClass) {
}
CurMultiClass->DefPrototypes.push_back(CurRec);
}
-
+
if (ParseObjectBody(CurRec))
return 0;
-
+
if (CurMultiClass == 0) // Def's in multiclasses aren't really defs.
CurRec->resolveReferences();
-
+
// If ObjectBody has template arguments, it's an error.
assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?");
return CurRec;
@@ -1688,10 +1681,10 @@ llvm::Record *TGParser::ParseDef(MultiClass *CurMultiClass) {
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.
@@ -1705,7 +1698,7 @@ bool TGParser::ParseClass() {
Records.addClass(CurRec);
}
Lex.Lex(); // eat the name.
-
+
// If there are template args, parse them.
if (Lex.getCode() == tgtok::less)
if (ParseTemplateArgList(CurRec))
@@ -1723,7 +1716,7 @@ bool TGParser::ParseClass() {
///
std::vector<LetRecord> TGParser::ParseLetList() {
std::vector<LetRecord> Result;
-
+
while (1) {
if (Lex.getCode() != tgtok::Id) {
TokError("expected identifier in let definition");
@@ -1731,29 +1724,29 @@ std::vector<LetRecord> TGParser::ParseLetList() {
}
std::string Name = Lex.getCurStrVal();
SMLoc NameLoc = Lex.getLoc();
- Lex.Lex(); // Eat the identifier.
+ Lex.Lex(); // Eat the identifier.
// Check for an optional RangeList.
std::vector<unsigned> Bits;
- if (ParseOptionalRangeList(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.
+ Lex.Lex(); // eat the comma.
}
}
@@ -1766,7 +1759,7 @@ std::vector<LetRecord> TGParser::ParseLetList() {
bool TGParser::ParseTopLevelLet() {
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;
@@ -1775,7 +1768,7 @@ bool TGParser::ParseTopLevelLet() {
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
@@ -1785,18 +1778,18 @@ bool TGParser::ParseTopLevelLet() {
SMLoc BraceLoc = Lex.getLoc();
// Otherwise, this is a group let.
Lex.Lex(); // eat the '{'.
-
+
// Parse the object list.
if (ParseObjectList())
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;
@@ -1807,15 +1800,15 @@ bool TGParser::ParseTopLevelLet() {
/// MultiClassDef ::= DefInst
///
bool TGParser::ParseMultiClassDef(MultiClass *CurMC) {
- if (Lex.getCode() != tgtok::Def)
+ if (Lex.getCode() != tgtok::Def)
return TokError("expected 'def' in multiclass body");
Record *D = ParseDef(CurMC);
if (D == 0) return true;
-
+
// Copy the template arguments for the multiclass into the def.
const std::vector<std::string> &TArgs = CurMC->Rec.getTemplateArgs();
-
+
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
const RecordVal *RV = CurMC->Rec.getValue(TArgs[i]);
assert(RV && "Template arg doesn't exist?");
@@ -1837,13 +1830,13 @@ bool TGParser::ParseMultiClass() {
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());
Lex.Lex(); // Eat the identifier.
-
+
// If there are template args, parse them.
if (Lex.getCode() == tgtok::less)
if (ParseTemplateArgList(0))
@@ -1877,23 +1870,21 @@ bool TGParser::ParseMultiClass() {
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
- if (Lex.getCode() != tgtok::semi)
- return TokError("expected ';' in multiclass definition");
- else
- Lex.Lex(); // eat the ';'.
- }
- 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)
if (ParseMultiClassDef(CurMultiClass))
return true;
-
+
Lex.Lex(); // eat the '}'.
}
-
+
CurMultiClass = 0;
return false;
}
@@ -1906,12 +1897,12 @@ bool TGParser::ParseDefm() {
assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
if (Lex.Lex() != tgtok::Id) // eat the defm.
return TokError("expected identifier after defm");
-
+
SMLoc DefmPrefixLoc = Lex.getLoc();
std::string DefmPrefix = Lex.getCurStrVal();
if (Lex.Lex() != tgtok::colon)
return TokError("expected ':' after defm identifier");
-
+
// eat the colon.
Lex.Lex();
@@ -1926,7 +1917,7 @@ bool TGParser::ParseDefm() {
// template parameters.
MultiClass *MC = MultiClasses[Ref.Rec->getName()];
assert(MC && "Didn't lookup multiclass correctly?");
- std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
+ 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();
@@ -1943,8 +1934,7 @@ bool TGParser::ParseDefm() {
std::string::size_type idx = DefName.find("#NAME#");
if (idx != std::string::npos) {
DefName.replace(idx, 6, DefmPrefix);
- }
- else {
+ } else {
// Add the suffix to the defm name to get the new name.
DefName = DefmPrefix + DefName;
}
@@ -1991,8 +1981,8 @@ bool TGParser::ParseDefm() {
// Ensure redefinition doesn't happen.
if (Records.getDef(CurRec->getName()))
- return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
- "' already defined, instantiating defm with subdef '" +
+ return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
+ "' already defined, instantiating defm with subdef '" +
DefProto->getName() + "'");
Records.addDef(CurRec);
CurRec->resolveReferences();
@@ -2008,7 +1998,7 @@ bool TGParser::ParseDefm() {
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' at end of defm");
Lex.Lex();
-
+
return false;
}
@@ -2040,15 +2030,14 @@ bool TGParser::ParseObjectList() {
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/TableGen.cpp b/utils/TableGen/TableGen.cpp
index c6c4306295888..7c8d288db9377 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -21,6 +21,7 @@
#include "ClangDiagnosticsEmitter.h"
#include "CodeEmitterGen.h"
#include "DAGISelEmitter.h"
+#include "DisassemblerEmitter.h"
#include "FastISelEmitter.h"
#include "InstrEnumEmitter.h"
#include "InstrInfoEmitter.h"
@@ -46,6 +47,7 @@ enum ActionType {
GenEmitter,
GenRegisterEnums, GenRegister, GenRegisterHeader,
GenInstrEnums, GenInstrs, GenAsmWriter, GenAsmMatcher,
+ GenDisassembler,
GenCallingConv,
GenClangDiagsDefs,
GenClangDiagGroups,
@@ -80,6 +82,8 @@ namespace {
"Generate calling convention descriptions"),
clEnumValN(GenAsmWriter, "gen-asm-writer",
"Generate assembly writer"),
+ clEnumValN(GenDisassembler, "gen-disassembler",
+ "Generate disassembler"),
clEnumValN(GenAsmMatcher, "gen-asm-matcher",
"Generate assembly instruction matcher"),
clEnumValN(GenDAGISel, "gen-dag-isel",
@@ -228,6 +232,9 @@ int main(int argc, char **argv) {
case GenClangDiagGroups:
ClangDiagGroupsEmitter(Records).run(*Out);
break;
+ case GenDisassembler:
+ DisassemblerEmitter(Records).run(*Out);
+ break;
case GenOptParserDefs:
OptParserEmitter(Records, true).run(*Out);
break;
diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm
index 9168d1a48584c..4392b27ee1b68 100755
--- a/utils/buildit/build_llvm
+++ b/utils/buildit/build_llvm
@@ -341,6 +341,14 @@ chgrp -R wheel $DEST_DIR
find $DEST_DIR -name html.tar.gz -exec rm {} \;
################################################################################
+# symlinks so that B&I can find things
+
+cd $DEST_DIR
+mkdir -p ./usr/lib/
+cd usr/lib
+ln -s ../../Developer/usr/lib/libLTO.dylib ./libLTO.dylib
+
+################################################################################
# w00t! Done!
exit 0