mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
eliminate the Records global variable, patch by Garrison Venn!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121659 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9d6250f52b
commit
67db883487
@ -1488,11 +1488,11 @@ bool FilterChooser::emit(raw_ostream &o, unsigned &Indentation) {
|
||||
|
||||
class ARMDecoderEmitter::ARMDEBackend {
|
||||
public:
|
||||
ARMDEBackend(ARMDecoderEmitter &frontend) :
|
||||
ARMDEBackend(ARMDecoderEmitter &frontend, RecordKeeper &Records) :
|
||||
NumberedInstructions(),
|
||||
Opcodes(),
|
||||
Frontend(frontend),
|
||||
Target(),
|
||||
Target(Records),
|
||||
FC(NULL)
|
||||
{
|
||||
if (Target.getName() == "ARM")
|
||||
@ -1843,7 +1843,7 @@ void ARMDecoderEmitter::ARMDEBackend::emit(raw_ostream &o) {
|
||||
|
||||
void ARMDecoderEmitter::initBackend()
|
||||
{
|
||||
Backend = new ARMDEBackend(*this);
|
||||
Backend = new ARMDEBackend(*this, Records);
|
||||
}
|
||||
|
||||
void ARMDecoderEmitter::run(raw_ostream &o)
|
||||
|
@ -492,6 +492,9 @@ struct SubtargetFeatureInfo {
|
||||
|
||||
class AsmMatcherInfo {
|
||||
public:
|
||||
/// Tracked Records
|
||||
RecordKeeper& Records;
|
||||
|
||||
/// The tablegen AsmParser record.
|
||||
Record *AsmParser;
|
||||
|
||||
@ -546,7 +549,9 @@ private:
|
||||
MatchableInfo::AsmOperand &Op);
|
||||
|
||||
public:
|
||||
AsmMatcherInfo(Record *AsmParser, CodeGenTarget &Target);
|
||||
AsmMatcherInfo(Record *AsmParser,
|
||||
CodeGenTarget &Target,
|
||||
RecordKeeper& Records);
|
||||
|
||||
/// BuildInfo - Construct the various tables used during matching.
|
||||
void BuildInfo();
|
||||
@ -559,6 +564,14 @@ public:
|
||||
SubtargetFeatures.find(Def);
|
||||
return I == SubtargetFeatures.end() ? 0 : I->second;
|
||||
}
|
||||
|
||||
RecordKeeper& getRecords() {
|
||||
return(Records);
|
||||
}
|
||||
|
||||
RecordKeeper& getRecords() const {
|
||||
return(Records);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@ -989,8 +1002,10 @@ void AsmMatcherInfo::BuildOperandClasses() {
|
||||
}
|
||||
}
|
||||
|
||||
AsmMatcherInfo::AsmMatcherInfo(Record *asmParser, CodeGenTarget &target)
|
||||
: AsmParser(asmParser), Target(target),
|
||||
AsmMatcherInfo::AsmMatcherInfo(Record *asmParser,
|
||||
CodeGenTarget &target,
|
||||
RecordKeeper& records)
|
||||
: Records(records), AsmParser(asmParser), Target(target),
|
||||
RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")) {
|
||||
}
|
||||
|
||||
@ -1659,7 +1674,7 @@ static std::string GetAliasRequiredFeatures(Record *R,
|
||||
/// emit a function for them and return true, otherwise return false.
|
||||
static bool EmitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) {
|
||||
std::vector<Record*> Aliases =
|
||||
Records.getAllDerivedDefinitions("MnemonicAlias");
|
||||
Info.getRecords().getAllDerivedDefinitions("MnemonicAlias");
|
||||
if (Aliases.empty()) return false;
|
||||
|
||||
OS << "static void ApplyMnemonicAliases(StringRef &Mnemonic, "
|
||||
@ -1732,12 +1747,12 @@ static bool EmitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info) {
|
||||
}
|
||||
|
||||
void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
Record *AsmParser = Target.getAsmParser();
|
||||
std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
|
||||
|
||||
// Compute the information on the instructions to match.
|
||||
AsmMatcherInfo Info(AsmParser, Target);
|
||||
AsmMatcherInfo Info(AsmParser, Target, Records);
|
||||
Info.BuildInfo();
|
||||
|
||||
// Sort the instruction table using the partial order on classes. We use
|
||||
|
@ -240,7 +240,7 @@ static void UnescapeString(std::string &Str) {
|
||||
/// EmitPrintInstruction - Generate the code for the "printInstruction" method
|
||||
/// implementation.
|
||||
void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
Record *AsmWriter = Target.getAsmWriter();
|
||||
std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
|
||||
bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter");
|
||||
@ -459,7 +459,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
|
||||
|
||||
|
||||
void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
Record *AsmWriter = Target.getAsmWriter();
|
||||
std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
|
||||
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
|
||||
@ -501,7 +501,7 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
|
||||
}
|
||||
|
||||
void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
Record *AsmWriter = Target.getAsmWriter();
|
||||
std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
|
||||
|
||||
|
@ -57,7 +57,7 @@ class ClangASTNodesEmitter : public TableGenBackend {
|
||||
public:
|
||||
explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N,
|
||||
const std::string &S)
|
||||
: Records(R), Root(N, SMLoc()), BaseSuffix(S)
|
||||
: Records(R), Root(N, SMLoc(), R), BaseSuffix(S)
|
||||
{}
|
||||
|
||||
// run - Output the .inc file contents
|
||||
|
@ -29,9 +29,10 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class DiagGroupParentMap {
|
||||
RecordKeeper &Records;
|
||||
std::map<const Record*, std::vector<Record*> > Mapping;
|
||||
public:
|
||||
DiagGroupParentMap() {
|
||||
DiagGroupParentMap(RecordKeeper &records) : Records(records) {
|
||||
std::vector<Record*> DiagGroups
|
||||
= Records.getAllDerivedDefinitions("DiagGroup");
|
||||
for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) {
|
||||
@ -84,11 +85,12 @@ static std::string getDiagnosticCategory(const Record *R,
|
||||
|
||||
namespace {
|
||||
class DiagCategoryIDMap {
|
||||
RecordKeeper &Records;
|
||||
StringMap<unsigned> CategoryIDs;
|
||||
std::vector<std::string> CategoryStrings;
|
||||
public:
|
||||
DiagCategoryIDMap() {
|
||||
DiagGroupParentMap ParentInfo;
|
||||
DiagCategoryIDMap(RecordKeeper &records) : Records(records) {
|
||||
DiagGroupParentMap ParentInfo(Records);
|
||||
|
||||
// The zero'th category is "".
|
||||
CategoryStrings.push_back("");
|
||||
@ -138,8 +140,8 @@ void ClangDiagsDefsEmitter::run(raw_ostream &OS) {
|
||||
const std::vector<Record*> &Diags =
|
||||
Records.getAllDerivedDefinitions("Diagnostic");
|
||||
|
||||
DiagCategoryIDMap CategoryIDs;
|
||||
DiagGroupParentMap DGParentMap;
|
||||
DiagCategoryIDMap CategoryIDs(Records);
|
||||
DiagGroupParentMap DGParentMap(Records);
|
||||
|
||||
for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
|
||||
const Record &R = *Diags[i];
|
||||
@ -187,7 +189,7 @@ struct GroupInfo {
|
||||
|
||||
void ClangDiagGroupsEmitter::run(raw_ostream &OS) {
|
||||
// Compute a mapping from a DiagGroup to all of its parents.
|
||||
DiagGroupParentMap DGParentMap;
|
||||
DiagGroupParentMap DGParentMap(Records);
|
||||
|
||||
// Invert the 1-[0/1] mapping of diags to group into a one to many mapping of
|
||||
// groups to diags in the group.
|
||||
@ -277,7 +279,7 @@ void ClangDiagGroupsEmitter::run(raw_ostream &OS) {
|
||||
OS << "#endif // GET_DIAG_TABLE\n\n";
|
||||
|
||||
// Emit the category table next.
|
||||
DiagCategoryIDMap CategoriesByID;
|
||||
DiagCategoryIDMap CategoriesByID(Records);
|
||||
OS << "\n#ifdef GET_CATEGORY_TABLE\n";
|
||||
for (DiagCategoryIDMap::iterator I = CategoriesByID.begin(),
|
||||
E = CategoriesByID.end(); I != E; ++I)
|
||||
|
@ -198,7 +198,7 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
|
||||
}
|
||||
|
||||
void CodeEmitterGen::run(raw_ostream &o) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
|
||||
|
||||
// For little-endian instruction bit encodings, reverse the bit order
|
||||
|
@ -1785,7 +1785,9 @@ void TreePattern::dump() const { print(errs()); }
|
||||
// CodeGenDAGPatterns implementation
|
||||
//
|
||||
|
||||
CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
|
||||
CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) :
|
||||
Records(R), Target(R) {
|
||||
|
||||
Intrinsics = LoadIntrinsics(Records, false);
|
||||
TgtIntrinsics = LoadIntrinsics(Records, true);
|
||||
ParseNodeInfo();
|
||||
|
@ -108,7 +108,7 @@ std::string llvm::getQualifiedName(const Record *R) {
|
||||
|
||||
/// getTarget - Return the current instance of the Target class.
|
||||
///
|
||||
CodeGenTarget::CodeGenTarget() {
|
||||
CodeGenTarget::CodeGenTarget(RecordKeeper& records) : Records(records) {
|
||||
std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
|
||||
if (Targets.size() == 0)
|
||||
throw std::string("ERROR: No 'Target' subclasses defined!");
|
||||
@ -314,7 +314,8 @@ void CodeGenTarget::ReadInstructions() const {
|
||||
|
||||
static const CodeGenInstruction *
|
||||
GetInstByName(const char *Name,
|
||||
const DenseMap<const Record*, CodeGenInstruction*> &Insts) {
|
||||
const DenseMap<const Record*, CodeGenInstruction*> &Insts,
|
||||
RecordKeeper &Records) {
|
||||
const Record *Rec = Records.getDef(Name);
|
||||
|
||||
DenseMap<const Record*, CodeGenInstruction*>::const_iterator
|
||||
@ -358,7 +359,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
|
||||
};
|
||||
const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
|
||||
for (const char *const *p = FixedInstrs; *p; ++p) {
|
||||
const CodeGenInstruction *Instr = GetInstByName(*p, Insts);
|
||||
const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
|
||||
assert(Instr && "Missing target independent instruction");
|
||||
assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
|
||||
InstrsByEnum.push_back(Instr);
|
||||
|
@ -61,6 +61,7 @@ std::string getQualifiedName(const Record *R);
|
||||
/// CodeGenTarget - This class corresponds to the Target class in the .td files.
|
||||
///
|
||||
class CodeGenTarget {
|
||||
RecordKeeper &Records;
|
||||
Record *TargetRec;
|
||||
|
||||
mutable DenseMap<const Record*, CodeGenInstruction*> Instructions;
|
||||
@ -76,7 +77,7 @@ class CodeGenTarget {
|
||||
|
||||
mutable std::vector<const CodeGenInstruction*> InstrsByEnum;
|
||||
public:
|
||||
CodeGenTarget();
|
||||
CodeGenTarget(RecordKeeper &Records);
|
||||
|
||||
Record *getTargetRecord() const { return TargetRec; }
|
||||
const std::string &getName() const;
|
||||
|
@ -94,7 +94,7 @@ using namespace llvm::X86Disassembler;
|
||||
/// instruction.
|
||||
|
||||
void DisassemblerEmitter::run(raw_ostream &OS) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
|
||||
OS << "/*===- TableGen'erated file "
|
||||
<< "---------------------------------------*- C -*-===*\n"
|
||||
|
@ -880,7 +880,7 @@ void EDEmitter::run(raw_ostream &o) {
|
||||
unsigned int i = 0;
|
||||
|
||||
CompoundConstantEmitter infoArray;
|
||||
CodeGenTarget target;
|
||||
CodeGenTarget target(Records);
|
||||
|
||||
populateInstInfo(infoArray, target);
|
||||
|
||||
|
@ -23,7 +23,7 @@ void InstrEnumEmitter::run(raw_ostream &OS) {
|
||||
EmitSourceFileHeader("Target Instruction Enum Values", OS);
|
||||
OS << "namespace llvm {\n\n";
|
||||
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
|
||||
// We must emit the PHI opcode first...
|
||||
std::string Namespace = Target.getInstNamespace();
|
||||
|
@ -3028,7 +3028,8 @@ void CheckDriverData(DriverData& Data) {
|
||||
CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs);
|
||||
}
|
||||
|
||||
void EmitDriverCode(const DriverData& Data, raw_ostream& O) {
|
||||
void EmitDriverCode(const DriverData& Data,
|
||||
raw_ostream& O, RecordKeeper &Records) {
|
||||
// Emit file header.
|
||||
EmitIncludes(O);
|
||||
|
||||
@ -3089,7 +3090,7 @@ void LLVMCConfigurationEmitter::run (raw_ostream &O) {
|
||||
CheckDriverData(Data);
|
||||
|
||||
this->EmitSourceFileHeader("llvmc-based driver: auto-generated code", O);
|
||||
EmitDriverCode(Data, O);
|
||||
EmitDriverCode(Data, O, Records);
|
||||
|
||||
} catch (std::exception& Error) {
|
||||
throw Error.what() + std::string(" - usually this means a syntax error.");
|
||||
|
@ -21,8 +21,10 @@ namespace llvm {
|
||||
/// LLVMCConfigurationEmitter - TableGen backend that generates
|
||||
/// configuration code for LLVMC.
|
||||
class LLVMCConfigurationEmitter : public TableGenBackend {
|
||||
RecordKeeper &Records;
|
||||
public:
|
||||
explicit LLVMCConfigurationEmitter(RecordKeeper&) {}
|
||||
explicit LLVMCConfigurationEmitter(RecordKeeper& records) :
|
||||
Records(records) {}
|
||||
|
||||
// run - Output the asmwriter, returning true on failure.
|
||||
void run(raw_ostream &o);
|
||||
|
@ -528,7 +528,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
|
||||
}
|
||||
}
|
||||
|
||||
if (Record *D = Records.getDef(Name))
|
||||
if (Record *D = (CurRec->getRecords()).getDef(Name))
|
||||
return new DefInit(D);
|
||||
|
||||
errs() << "Variable not defined: '" + Name + "'\n";
|
||||
@ -1227,14 +1227,14 @@ void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
|
||||
unsigned Record::LastID = 0;
|
||||
|
||||
void Record::setName(const std::string &Name) {
|
||||
if (Records.getDef(getName()) == this) {
|
||||
Records.removeDef(getName());
|
||||
if (TrackedRecords.getDef(getName()) == this) {
|
||||
TrackedRecords.removeDef(getName());
|
||||
this->Name = Name;
|
||||
Records.addDef(this);
|
||||
TrackedRecords.addDef(this);
|
||||
} else {
|
||||
Records.removeClass(getName());
|
||||
TrackedRecords.removeClass(getName());
|
||||
this->Name = Name;
|
||||
Records.addClass(this);
|
||||
TrackedRecords.addClass(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ class VarListElementInit;
|
||||
class Record;
|
||||
class RecordVal;
|
||||
struct MultiClass;
|
||||
class RecordKeeper;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Type Classes
|
||||
@ -1227,10 +1228,15 @@ class Record {
|
||||
std::vector<std::string> TemplateArgs;
|
||||
std::vector<RecordVal> Values;
|
||||
std::vector<Record*> SuperClasses;
|
||||
|
||||
// Tracks Record instances. Not owned by Record.
|
||||
RecordKeeper &TrackedRecords;
|
||||
|
||||
public:
|
||||
|
||||
explicit Record(const std::string &N, SMLoc loc) :
|
||||
ID(LastID++), Name(N), Loc(loc) {}
|
||||
// Constructs a record. See also RecordKeeper::createRecord.
|
||||
explicit Record(const std::string &N, SMLoc loc, RecordKeeper& records) :
|
||||
ID(LastID++), Name(N), Loc(loc), TrackedRecords(records) {}
|
||||
~Record() {}
|
||||
|
||||
|
||||
@ -1315,6 +1321,10 @@ public:
|
||||
/// possible references.
|
||||
void resolveReferencesTo(const RecordVal *RV);
|
||||
|
||||
RecordKeeper &getRecords() const {
|
||||
return(TrackedRecords);
|
||||
}
|
||||
|
||||
void dump() const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -1396,7 +1406,8 @@ struct MultiClass {
|
||||
|
||||
void dump() const;
|
||||
|
||||
MultiClass(const std::string &Name, SMLoc Loc) : Rec(Name, Loc) {}
|
||||
MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
|
||||
Rec(Name, Loc, Records) {}
|
||||
};
|
||||
|
||||
class RecordKeeper {
|
||||
@ -1453,6 +1464,11 @@ public:
|
||||
std::vector<Record*>
|
||||
getAllDerivedDefinitions(const std::string &ClassName) const;
|
||||
|
||||
// allocates and returns a record.
|
||||
Record *createRecord(const std::string &N, SMLoc loc) {
|
||||
return(new Record(N, loc, *this));
|
||||
}
|
||||
|
||||
|
||||
void dump() const;
|
||||
};
|
||||
@ -1488,8 +1504,6 @@ public:
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
|
||||
|
||||
extern RecordKeeper Records;
|
||||
|
||||
void PrintError(SMLoc ErrorLoc, const Twine &Msg);
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -25,7 +25,7 @@ using namespace llvm;
|
||||
|
||||
// runEnums - Print out enum values for all of the registers.
|
||||
void RegisterInfoEmitter::runEnums(raw_ostream &OS) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
|
||||
|
||||
std::string Namespace = Registers[0].TheDef->getValueAsString("Namespace");
|
||||
@ -63,7 +63,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) {
|
||||
|
||||
void RegisterInfoEmitter::runHeader(raw_ostream &OS) {
|
||||
EmitSourceFileHeader("Register Information Header Fragment", OS);
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
const std::string &TargetName = Target.getName();
|
||||
std::string ClassName = TargetName + "GenRegisterInfo";
|
||||
|
||||
@ -333,7 +333,7 @@ public:
|
||||
// RegisterInfoEmitter::run - Main register file description emitter.
|
||||
//
|
||||
void RegisterInfoEmitter::run(raw_ostream &OS) {
|
||||
CodeGenTarget Target;
|
||||
CodeGenTarget Target(Records);
|
||||
EmitSourceFileHeader("Register Information Source Fragment", OS);
|
||||
|
||||
OS << "namespace llvm {\n\n";
|
||||
|
@ -638,7 +638,7 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
|
||||
// SubtargetEmitter::run - Main subtarget enumeration emitter.
|
||||
//
|
||||
void SubtargetEmitter::run(raw_ostream &OS) {
|
||||
Target = CodeGenTarget().getName();
|
||||
Target = CodeGenTarget(Records).getName();
|
||||
|
||||
EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
|
||||
|
||||
|
@ -1068,7 +1068,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
|
||||
|
||||
// Create the new record, set it as CurRec temporarily.
|
||||
static unsigned AnonCounter = 0;
|
||||
Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++),NameLoc);
|
||||
Record *NewRec = Records.createRecord(
|
||||
"anonymous.val."+utostr(AnonCounter++),NameLoc);
|
||||
SubClassReference SCRef;
|
||||
SCRef.RefLoc = NameLoc;
|
||||
SCRef.Rec = Class;
|
||||
@ -1632,7 +1633,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
|
||||
Lex.Lex(); // Eat the 'def' token.
|
||||
|
||||
// Parse ObjectName and make a record for it.
|
||||
Record *CurRec = new Record(ParseObjectName(), DefLoc);
|
||||
Record *CurRec = Records.createRecord(ParseObjectName(), DefLoc);
|
||||
|
||||
if (!CurMultiClass) {
|
||||
// Top-level def definition.
|
||||
@ -1699,7 +1700,7 @@ bool TGParser::ParseClass() {
|
||||
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());
|
||||
CurRec = Records.createRecord(Lex.getCurStrVal(), Lex.getLoc());
|
||||
Records.addClass(CurRec);
|
||||
}
|
||||
Lex.Lex(); // eat the name.
|
||||
@ -1816,7 +1817,8 @@ bool TGParser::ParseMultiClass() {
|
||||
if (MultiClasses.count(Name))
|
||||
return TokError("multiclass '" + Name + "' already defined");
|
||||
|
||||
CurMultiClass = MultiClasses[Name] = new MultiClass(Name, Lex.getLoc());
|
||||
CurMultiClass = MultiClasses[Name] = new MultiClass(Name,
|
||||
Lex.getLoc(), Records);
|
||||
Lex.Lex(); // Eat the identifier.
|
||||
|
||||
// If there are template args, parse them.
|
||||
@ -1945,7 +1947,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
|
||||
}
|
||||
}
|
||||
|
||||
Record *CurRec = new Record(DefName, DefmPrefixLoc);
|
||||
Record *CurRec = Records.createRecord(DefName, DefmPrefixLoc);
|
||||
|
||||
SubClassReference Ref;
|
||||
Ref.RefLoc = DefmPrefixLoc;
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace llvm {
|
||||
class Record;
|
||||
class RecordVal;
|
||||
class RecordKeeper;
|
||||
struct RecTy;
|
||||
struct Init;
|
||||
struct MultiClass;
|
||||
@ -47,8 +48,12 @@ class TGParser {
|
||||
/// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
|
||||
/// current value.
|
||||
MultiClass *CurMultiClass;
|
||||
|
||||
// Record tracker
|
||||
RecordKeeper& Records;
|
||||
public:
|
||||
TGParser(SourceMgr &SrcMgr) : Lex(SrcMgr), CurMultiClass(0) {}
|
||||
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.
|
||||
|
@ -173,9 +173,6 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Eliminate globals from tblgen.
|
||||
RecordKeeper llvm::Records;
|
||||
|
||||
static SourceMgr SrcMgr;
|
||||
|
||||
void llvm::PrintError(SMLoc ErrorLoc, const Twine &Msg) {
|
||||
@ -188,7 +185,8 @@ void llvm::PrintError(SMLoc ErrorLoc, const Twine &Msg) {
|
||||
/// file.
|
||||
static bool ParseFile(const std::string &Filename,
|
||||
const std::vector<std::string> &IncludeDirs,
|
||||
SourceMgr &SrcMgr) {
|
||||
SourceMgr &SrcMgr,
|
||||
RecordKeeper& Records) {
|
||||
error_code ec;
|
||||
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), ec);
|
||||
if (F == 0) {
|
||||
@ -204,19 +202,21 @@ static bool ParseFile(const std::string &Filename,
|
||||
// it later.
|
||||
SrcMgr.setIncludeDirs(IncludeDirs);
|
||||
|
||||
TGParser Parser(SrcMgr);
|
||||
TGParser Parser(SrcMgr, Records);
|
||||
|
||||
return Parser.ParseFile();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
RecordKeeper Records;
|
||||
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
PrettyStackTraceProgram X(argc, argv);
|
||||
cl::ParseCommandLineOptions(argc, argv);
|
||||
|
||||
|
||||
// Parse the input file.
|
||||
if (ParseFile(InputFilename, IncludeDirs, SrcMgr))
|
||||
if (ParseFile(InputFilename, IncludeDirs, SrcMgr, Records))
|
||||
return 1;
|
||||
|
||||
std::string Error;
|
||||
|
Loading…
Reference in New Issue
Block a user