//===-- FileParser.y - Parser for TableGen files ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
//
// This file implements the bison parser for Table Generator files...
//
-//===------------------------------------------------------------------------=//
+//===----------------------------------------------------------------------===//
%{
#include "Record.h"
int yyerror(const char *ErrorMsg);
int yylex();
+
+namespace llvm {
+
extern int Filelineno;
static Record *CurRec = 0;
err() << "New definition of '" << RV.getName() << "' of type '"
<< *RV.getType() << "' is incompatible with previous "
<< "definition of type '" << *ERV->getType() << "'!\n";
- abort();
+ exit(1);
}
} else {
CurRec->addValue(RV);
static void addSuperClass(Record *SC) {
if (CurRec->isSubClassOf(SC)) {
err() << "Already subclass of '" << SC->getName() << "'!\n";
- abort();
+ exit(1);
}
CurRec->addSuperClass(SC);
}
static void setValue(const std::string &ValName,
std::vector<unsigned> *BitList, Init *V) {
- if (!V) return ;
+ if (!V) return;
RecordVal *RV = CurRec->getValue(ValName);
if (RV == 0) {
err() << "Value '" << ValName << "' unknown!\n";
- abort();
+ exit(1);
}
+
+ // Do not allow assignments like 'X = X'. This will just cause infinite loops
+ // in the resolution machinery.
+ if (!BitList)
+ if (VarInit *VI = dynamic_cast<VarInit*>(V))
+ if (VI->getName() == ValName)
+ return;
// 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
BitsInit *CurVal = dynamic_cast<BitsInit*>(RV->getValue());
if (CurVal == 0) {
err() << "Value '" << ValName << "' is not a bits type!\n";
- abort();
+ exit(1);
}
// Convert the incoming value to a bits type of the appropriate size...
if (BI == 0) {
V->convertInitializerTo(new BitsRecTy(BitList->size()));
err() << "Initializer '" << *V << "' not compatible with bit range!\n";
- abort();
+ exit(1);
}
// We should have a BitsInit type now...
if (NewVal->getBit(Bit)) {
err() << "Cannot set bit #" << Bit << " of value '" << ValName
<< "' more than once!\n";
- abort();
+ exit(1);
}
NewVal->setBit(Bit, BInit->getBit(i));
}
if (RV->setValue(V)) {
err() << "Value '" << ValName << "' of type '" << *RV->getType()
<< "' is incompatible with initializer '" << *V << "'!\n";
- abort();
+ exit(1);
}
}
// Ensure that an appropriate number of template arguments are specified...
if (TArgs.size() < TemplateArgs.size()) {
err() << "ERROR: More template args specified than expected!\n";
- abort();
+ exit(1);
} else { // This class expects template arguments...
// Loop over all of the template arguments, setting them to the specified
- // value or leaving them as the default as neccesary.
+ // value or leaving them as the default as necessary.
for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
if (i < TemplateArgs.size()) { // A value is specified for this temp-arg?
// Set it now.
err() << "ERROR: Value not specified for template argument #"
<< i << " (" << TArgs[i] << ") of subclass '" << SC->getName()
<< "'!\n";
- abort();
+ exit(1);
}
}
}
-
// Since everything went well, we can now set the "superclass" list for the
// current record.
- const std::vector<Record*> &SCs = SC->getSuperClasses();
+ const std::vector<Record*> &SCs = SC->getSuperClasses();
for (unsigned i = 0, e = SCs.size(); i != e; ++i)
addSuperClass(SCs[i]);
addSuperClass(SC);
}
+} // End llvm namespace
+
+using namespace llvm;
%}
%union {
- std::string *StrVal;
- int IntVal;
- RecTy *Ty;
- Init *Initializer;
- std::vector<Init*> *DagValueList;
- std::vector<Init*> *FieldList;
- std::vector<unsigned>*BitList;
- Record *Rec;
- SubClassRefTy *SubClassRef;
- std::vector<SubClassRefTy> *SubClassList;
+ std::string* StrVal;
+ int IntVal;
+ llvm::RecTy* Ty;
+ llvm::Init* Initializer;
+ std::vector<llvm::Init*>* FieldList;
+ std::vector<unsigned>* BitList;
+ llvm::Record* Rec;
+ SubClassRefTy* SubClassRef;
+ std::vector<SubClassRefTy>* SubClassList;
+ std::vector<std::pair<llvm::Init*, std::string> >* DagValueList;
};
%token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN
%type <DagValueList> DagArgList DagArgListNE
%type <FieldList> ValueList ValueListNE
%type <BitList> BitList OptBitList RBitList
-%type <StrVal> Declaration OptID
+%type <StrVal> Declaration OptID OptVarName
%start File
+
%%
ClassID : ID {
$$ = Records.getClass(*$1);
if ($$ == 0) {
err() << "Couldn't find class '" << *$1 << "'!\n";
- abort();
+ exit(1);
}
delete $1;
};
if (Bit == 0) {
err() << "Element #" << i << " (" << *(*$2)[i]
<< ") is not convertable to a bit!\n";
- abort();
+ exit(1);
}
Init->setBit($2->size()-i-1, Bit);
}
$$ = new DefInit(D);
} else {
err() << "Variable not defined: '" << *$1 << "'!\n";
- abort();
+ exit(1);
}
delete $1;
$$ = $1->convertInitializerBitRange(*$3);
if ($$ == 0) {
err() << "Invalid bit range for value '" << *$1 << "'!\n";
- abort();
+ exit(1);
}
delete $3;
} | '[' ValueList ']' {
} | Value '.' ID {
if (!$1->getFieldType(*$3)) {
err() << "Cannot access field '" << *$3 << "' of value '" << *$1 << "!\n";
- abort();
+ exit(1);
}
$$ = new FieldInit($1, *$3);
delete $3;
Record *D = Records.getDef(*$2);
if (D == 0) {
err() << "Invalid def '" << *$2 << "'!\n";
- abort();
+ exit(1);
}
$$ = new DagInit(D, *$3);
delete $2; delete $3;
};
-DagArgListNE : Value {
- $$ = new std::vector<Init*>();
- $$->push_back($1);
+OptVarName : /* empty */ {
+ $$ = new std::string();
+ }
+ | ':' VARNAME {
+ $$ = $2;
+ };
+
+DagArgListNE : Value OptVarName {
+ $$ = new std::vector<std::pair<Init*, std::string> >();
+ $$->push_back(std::make_pair($1, *$2));
+ delete $2;
}
- | DagArgListNE ',' Value {
- $1->push_back($3);
+ | DagArgListNE ',' Value OptVarName {
+ $1->push_back(std::make_pair($3, *$4));
+ delete $4;
+ $$ = $1;
};
DagArgList : /*empty*/ {
- $$ = new std::vector<Init*>();
+ $$ = new std::vector<std::pair<Init*, std::string> >();
}
| DagArgListNE { $$ = $1; };
} | INTVAL '-' INTVAL {
if ($1 < $3 || $1 < 0 || $3 < 0) {
err() << "Invalid bit range: " << $1 << "-" << $3 << "!\n";
- abort();
+ exit(1);
}
$$ = new std::vector<unsigned>();
for (int i = $1; i >= $3; --i)
$2 = -$2;
if ($1 < $2 || $1 < 0 || $2 < 0) {
err() << "Invalid bit range: " << $1 << "-" << $2 << "!\n";
- abort();
+ exit(1);
}
$$ = new std::vector<unsigned>();
for (int i = $1; i >= $2; --i)
} | RBitList ',' INTVAL '-' INTVAL {
if ($3 < $5 || $3 < 0 || $5 < 0) {
err() << "Invalid bit range: " << $3 << "-" << $5 << "!\n";
- abort();
+ exit(1);
}
$$ = $1;
for (int i = $3; i >= $5; --i)
$4 = -$4;
if ($3 < $4 || $3 < 0 || $4 < 0) {
err() << "Invalid bit range: " << $3 << "-" << $4 << "!\n";
- abort();
+ exit(1);
}
$$ = $1;
for (int i = $3; i >= $4; --i)
for (unsigned i = 0, e = $4->size(); i != e; ++i) {
Record *SuperClass = (*$4)[i].first;
for (unsigned i = 0, e = SuperClass->getTemplateArgs().size(); i != e; ++i)
- CurRec->removeValue(SuperClass->getTemplateArgs()[i]);
+ if (!CurRec->isTemplateArg(SuperClass->getTemplateArgs()[i]))
+ CurRec->removeValue(SuperClass->getTemplateArgs()[i]);
}
delete $4; // Delete the class list...
ClassInst : CLASS ObjectBody {
if (Records.getClass($2->getName())) {
err() << "Class '" << $2->getName() << "' already defined!\n";
- abort();
+ exit(1);
}
Records.addClass($$ = $2);
};
if (!$2->getTemplateArgs().empty()) {
err() << "Def '" << $2->getName()
<< "' is not permitted to have template arguments!\n";
- abort();
+ exit(1);
}
// If ObjectBody has template arguments, it's an error.
if (Records.getDef($2->getName())) {
err() << "Def '" << $2->getName() << "' already defined!\n";
- abort();
+ exit(1);
}
Records.addDef($$ = $2);
};
int yyerror(const char *ErrorMsg) {
err() << "Error parsing: " << ErrorMsg << "\n";
- abort();
+ exit(1);
}