Index: llvm/include/llvm/TableGen/Error.h =================================================================== --- llvm/include/llvm/TableGen/Error.h +++ llvm/include/llvm/TableGen/Error.h @@ -21,16 +21,22 @@ void PrintNote(const Twine &Msg); void PrintNote(ArrayRef NoteLoc, const Twine &Msg); + LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(ArrayRef ErrorLoc, const Twine &Msg); +LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const Record *Rec, + const Twine &Msg); +LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(const RecordVal *RecVal, + const Twine &Msg); +void PrintWarning(const Twine &Msg); void PrintWarning(ArrayRef WarningLoc, const Twine &Msg); void PrintWarning(const char *Loc, const Twine &Msg); -void PrintWarning(const Twine &Msg); +void PrintError(const Twine &Msg); void PrintError(ArrayRef ErrorLoc, const Twine &Msg); void PrintError(const char *Loc, const Twine &Msg); -void PrintError(const Twine &Msg); +void PrintError(const Record *Rec, const Twine &Msg); LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Twine &Msg); LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef ErrorLoc, Index: llvm/lib/TableGen/Error.cpp =================================================================== --- llvm/lib/TableGen/Error.cpp +++ llvm/lib/TableGen/Error.cpp @@ -40,12 +40,18 @@ "instantiated from multiclass"); } -void PrintNote(const Twine &Msg) { WithColor::note() << Msg << "\n"; } +// Functions to print notes. + +void PrintNote(const Twine &Msg) { + WithColor::note() << Msg << "\n"; +} void PrintNote(ArrayRef NoteLoc, const Twine &Msg) { PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg); } +// Functions to print fatal notes. + void PrintFatalNote(ArrayRef NoteLoc, const Twine &Msg) { PrintNote(NoteLoc, Msg); // The following call runs the file cleanup handlers. @@ -53,6 +59,28 @@ std::exit(1); } +// This method takes a Record and uses the source location +// stored in it. +void PrintFatalNote(const Record *Rec, const Twine &Msg) { + PrintNote(Rec->getLoc(), Msg); + // The following call runs the file cleanup handlers. + sys::RunInterruptHandlers(); + std::exit(1); +} + +// This method takes a RecordVal and uses the source location +// stored in it. +void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) { + PrintNote(RecVal->getLoc(), Msg); + // The following call runs the file cleanup handlers. + sys::RunInterruptHandlers(); + std::exit(1); +} + +// Functions to print warnings. + +void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; } + void PrintWarning(ArrayRef WarningLoc, const Twine &Msg) { PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg); } @@ -61,7 +89,9 @@ SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg); } -void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; } +// Functions to print errors. + +void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; } void PrintError(ArrayRef ErrorLoc, const Twine &Msg) { PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg); @@ -71,7 +101,13 @@ SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg); } -void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; } +// This method takes a Record and uses the source location +// stored in it. +void PrintError(const Record *Rec, const Twine &Msg) { + PrintMessage(Rec->getLoc(), SourceMgr::DK_Error, Msg); +} + +// Functions to print fatal errors. void PrintFatalError(const Twine &Msg) { PrintError(Msg); Index: llvm/utils/TableGen/PseudoLoweringEmitter.cpp =================================================================== --- llvm/utils/TableGen/PseudoLoweringEmitter.cpp +++ llvm/utils/TableGen/PseudoLoweringEmitter.cpp @@ -89,11 +89,15 @@ // problem. // FIXME: We probably shouldn't ever get a non-zero BaseIdx here. assert(BaseIdx == 0 && "Named subargument in pseudo expansion?!"); - if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec) - PrintFatalError(Rec->getLoc(), - "Pseudo operand type '" + DI->getDef()->getName() + - "' does not match expansion operand type '" + - Insn.Operands[BaseIdx + i].Rec->getName() + "'"); + // FIXME: Are the message operand types backward? + if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec) { + PrintError(Rec, "In pseudo instruction '" + Rec->getName() + + "', operand type '" + DI->getDef()->getName() + + "' does not match expansion operand type '" + + Insn.Operands[BaseIdx + i].Rec->getName() + "'"); + PrintFatalNote(DI->getDef(), + "Value was assigned at the following location:"); + } // Source operand maps to destination operand. The Data element // will be filled in later, just set the Kind for now. Do it // for each corresponding MachineInstr operand, not just the first. @@ -128,23 +132,38 @@ LLVM_DEBUG(dbgs() << " Result: " << *Dag << "\n"); DefInit *OpDef = dyn_cast(Dag->getOperator()); - if (!OpDef) - PrintFatalError(Rec->getLoc(), Rec->getName() + - " has unexpected operator type!"); + if (!OpDef) { + PrintError(Rec, "In pseudo instruction '" + Rec->getName() + + "', result operator is not a record"); + PrintFatalNote(Rec->getValue("ResultInst"), + "Result was assigned at the following location:"); + } Record *Operator = OpDef->getDef(); - if (!Operator->isSubClassOf("Instruction")) - PrintFatalError(Rec->getLoc(), "Pseudo result '" + Operator->getName() + - "' is not an instruction!"); + if (!Operator->isSubClassOf("Instruction")) { + PrintError(Rec, "In pseudo instruction '" + Rec->getName() + + "', result operator '" + Operator->getName() + + "' is not an instruction"); + PrintFatalNote(Rec->getValue("ResultInst"), + "Result was assigned at the following location:"); + } CodeGenInstruction Insn(Operator); - if (Insn.isCodeGenOnly || Insn.isPseudo) - PrintFatalError(Rec->getLoc(), "Pseudo result '" + Operator->getName() + - "' cannot be another pseudo instruction!"); + if (Insn.isCodeGenOnly || Insn.isPseudo) { + PrintError(Rec, "In pseudo instruction '" + Rec->getName() + + "', result operator '" + Operator->getName() + + "' cannot be a pseudo instruction"); + PrintFatalNote(Rec->getValue("ResultInst"), + "Result was assigned at the following location:"); + } - if (Insn.Operands.size() != Dag->getNumArgs()) - PrintFatalError(Rec->getLoc(), "Pseudo result '" + Operator->getName() + - "' operand count mismatch"); + if (Insn.Operands.size() != Dag->getNumArgs()) { + PrintError(Rec, "In pseudo instruction '" + Rec->getName() + + "', result operator '" + Operator->getName() + + "' has the wrong number of operands"); + PrintFatalNote(Rec->getValue("ResultInst"), + "Result was assigned at the following location:"); + } unsigned NumMIOperands = 0; for (unsigned i = 0, e = Insn.Operands.size(); i != e; ++i) @@ -177,10 +196,13 @@ continue; StringMap::iterator SourceOp = SourceOperands.find(Dag->getArgNameStr(i)); - if (SourceOp == SourceOperands.end()) - PrintFatalError(Rec->getLoc(), - "Pseudo output operand '" + Dag->getArgNameStr(i) + - "' has no matching source operand."); + if (SourceOp == SourceOperands.end()) { + PrintError(Rec, "In pseudo instruction '" + Rec->getName() + + "', output operand '" + Dag->getArgNameStr(i) + + "' has no matching source operand"); + PrintFatalNote(Rec->getValue("ResultInst"), + "Value was assigned at the following location:"); + } // Map the source operand to the destination operand index for each // MachineInstr operand. for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I)