[Assembler] Allow non-fatal errors after parsing
authorOliver Stannard <oliver.stannard@arm.com>
Tue, 17 Nov 2015 09:58:07 +0000 (09:58 +0000)
committerOliver Stannard <oliver.stannard@arm.com>
Tue, 17 Nov 2015 09:58:07 +0000 (09:58 +0000)
This adds reportError to MCContext, which can be used as an alternative to
reportFatalError when the assembler wants to try to continue processing the
rest of the file after the error is reported, so that all of the errors ina
file can be reported. It records the fact that an error was encountered, so we
can avoid emitting an object file if any errors occurred.

This patch doesn't add any uses of this function (a later patch will convert
most uses of reportFatalError to use it), but there is a small functional
change: we use the SourceManager to print the error message, even if we have a
null SMLoc. This means that we get a SourceManager-style message, with the file
and line information shown as <unknown>, rather than the "LLVM ERROR" style
used by report_fatal_error.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253327 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCContext.h
lib/MC/MCContext.cpp
lib/MC/MCParser/AsmParser.cpp
test/MC/Mips/micromips-diagnostic-fixup.s
test/MC/Mips/mips-diagnostic-fixup.s

index c675c8623df7eadbebfcf32b74434873d87e54ff..db2afa50b6628c2ccdeadcb9765d74fd3094f383 100644 (file)
@@ -213,6 +213,8 @@ namespace llvm {
     /// Do automatic reset in destructor
     bool AutoReset;
 
+    bool HadError;
+
     MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
                                bool CanBeUnnamed);
     MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix,
@@ -514,11 +516,13 @@ namespace llvm {
     }
     void deallocate(void *Ptr) {}
 
+    bool hadError() { return HadError; }
+    void reportError(SMLoc L, const Twine &Msg);
     // Unrecoverable error has occurred. Display the best diagnostic we can
     // and bail via exit(1). For now, most MC backend errors are unrecoverable.
     // FIXME: We should really do something about that.
     LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L,
-                                                  const Twine &Msg) const;
+                                                  const Twine &Msg);
   };
 
 } // end namespace llvm
index 93c7aaf36ee0ec17e96663b9876d270cd26b93db..383540a7a8fa3714ccfc45ca34c3cc1d85f5b372 100644 (file)
@@ -42,7 +42,7 @@ MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
       CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
       GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
       AllowTemporaryLabels(true), DwarfCompileUnitID(0),
-      AutoReset(DoAutoReset) {
+      AutoReset(DoAutoReset), HadError(false) {
 
   std::error_code EC = llvm::sys::fs::current_path(CompilationDir);
   if (EC)
@@ -102,6 +102,8 @@ void MCContext::reset() {
   DwarfLocSeen = false;
   GenDwarfForAssembly = false;
   GenDwarfFileNumber = 0;
+
+  HadError = false;
 }
 
 //===----------------------------------------------------------------------===//
@@ -475,14 +477,24 @@ void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
       [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
 }
 
-void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) const {
-  // If we have a source manager and a location, use it. Otherwise just
-  // use the generic report_fatal_error().
-  if (!SrcMgr || Loc == SMLoc())
+//===----------------------------------------------------------------------===//
+// Error Reporting
+//===----------------------------------------------------------------------===//
+
+void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
+  HadError = true;
+
+  // If we have a source manager use it. Otherwise just use the generic
+  // report_fatal_error().
+  if (!SrcMgr)
     report_fatal_error(Msg, false);
 
   // Use the source manager to print the message.
   SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+}
+
+void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
+  reportError(Loc, Msg);
 
   // If we reached here, we are failing ungracefully. Run the interrupt handlers
   // to make sure any special cleanups get done, in particular that we remove
index dd0e6bde9d89a476c41d64cdd7b7d52d4748cb0d..8e8be8e52f6394b30f35374a38588397108e0f0c 100644 (file)
@@ -703,7 +703,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
   if (!HadError && !NoFinalize)
     Out.Finish();
 
-  return HadError;
+  return HadError || getContext().hadError();
 }
 
 void AsmParser::checkForValidSection() {
index 041338ac2d3bd2efb14d2e0350c878c9cb9ca5af..6300561cd100154b305befb45c4c269d56eb5bf8 100644 (file)
@@ -1,6 +1,6 @@
 # RUN: not llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -arch=mips -mattr=+micromips 2>&1 -filetype=obj | FileCheck %s
 #
-# CHECK: LLVM ERROR: out of range PC16 fixup
+# CHECK: error: out of range PC16 fixup
 
 .text
   b foo
index 864d7397271df8b5c720c945e65461c4948999d5..6c74c134a9e3b4fe7f4c03fa385e3ab5291ca5e0 100644 (file)
@@ -1,6 +1,6 @@
 # RUN: not llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -arch=mips 2>&1 -filetype=obj | FileCheck %s
 #
-# CHECK: LLVM ERROR: out of range PC16 fixup
+# CHECK: error: out of range PC16 fixup
 
 .text
   b foo