ARM IAS: allow more depth in contextual diagnostics
authorSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 7 Jan 2014 02:29:00 +0000 (02:29 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 7 Jan 2014 02:29:00 +0000 (02:29 +0000)
Switch the context to be SmallVectors.  This allows for saving additional
context when providing previous emission sites.

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

lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/unwind-stack-diagnostics.s [new file with mode: 0644]

index f864af70e29a33dd82551bd7ccfb3eee014db87c..0076939b4ae670be83b1becab9cb04bbc0f60049 100644 (file)
@@ -116,46 +116,56 @@ typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy;
 class UnwindContext {
   MCAsmParser &Parser;
 
-  SMLoc FnStartLoc;
-  SMLoc CantUnwindLoc;
-  SMLoc PersonalityLoc;
-  SMLoc HandlerDataLoc;
+  typedef SmallVector<SMLoc, 4> Locs;
+
+  Locs FnStartLocs;
+  Locs CantUnwindLocs;
+  Locs PersonalityLocs;
+  Locs HandlerDataLocs;
   int FPReg;
 
 public:
   UnwindContext(MCAsmParser &P) : Parser(P), FPReg(-1) {}
 
-  bool hasFnStart() const { return FnStartLoc.isValid(); }
-  bool cantUnwind() const { return CantUnwindLoc.isValid(); }
-  bool hasHandlerData() const { return HandlerDataLoc.isValid(); }
-  bool hasPersonality() const { return PersonalityLoc.isValid(); }
+  bool hasFnStart() const { return !FnStartLocs.empty(); }
+  bool cantUnwind() const { return !CantUnwindLocs.empty(); }
+  bool hasHandlerData() const { return !HandlerDataLocs.empty(); }
+  bool hasPersonality() const { return !PersonalityLocs.empty(); }
 
-  void recordFnStart(SMLoc L) { FnStartLoc = L; }
-  void recordCantUnwind(SMLoc L) { CantUnwindLoc = L; }
-  void recordPersonality(SMLoc L) { PersonalityLoc = L; }
-  void recordHandlerData(SMLoc L) { HandlerDataLoc = L; }
+  void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); }
+  void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); }
+  void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); }
+  void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); }
 
   void saveFPReg(int Reg) { FPReg = Reg; }
   int getFPReg() const { return FPReg; }
 
   void emitFnStartLocNotes() const {
-    Parser.Note(FnStartLoc, ".fnstart was specified here");
+    for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end();
+         FI != FE; ++FI)
+      Parser.Note(*FI, ".fnstart was specified here");
   }
   void emitCantUnwindLocNotes() const {
-    Parser.Note(CantUnwindLoc, ".cantunwind was specified here");
+    for (Locs::const_iterator UI = CantUnwindLocs.begin(),
+                              UE = CantUnwindLocs.end(); UI != UE; ++UI)
+      Parser.Note(*UI, ".cantunwind was specified here");
   }
   void emitHandlerDataLocNotes() const {
-    Parser.Note(HandlerDataLoc, ".handlerdata was specified here");
+    for (Locs::const_iterator HI = HandlerDataLocs.begin(),
+                              HE = HandlerDataLocs.end(); HI != HE; ++HI)
+      Parser.Note(*HI, ".handlerdata was specified here");
   }
   void emitPersonalityLocNotes() const {
-    Parser.Note(PersonalityLoc, ".personality was specified here");
+    for (Locs::const_iterator PI = PersonalityLocs.begin(),
+                              PE = PersonalityLocs.end(); PI != PE; ++PI)
+      Parser.Note(*PI, ".personality was specified here");
   }
 
   void reset() {
-    FnStartLoc = SMLoc();
-    CantUnwindLoc = SMLoc();
-    PersonalityLoc = SMLoc();
-    HandlerDataLoc = SMLoc();
+    FnStartLocs = Locs();
+    CantUnwindLocs = Locs();
+    PersonalityLocs = Locs();
+    HandlerDataLocs = Locs();
     FPReg = -1;
   }
 };
diff --git a/test/MC/ARM/unwind-stack-diagnostics.s b/test/MC/ARM/unwind-stack-diagnostics.s
new file mode 100644 (file)
index 0000000..28d5672
--- /dev/null
@@ -0,0 +1,30 @@
+@ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null 2>&1 %s \
+@ RUN:   | FileCheck %s
+
+       .syntax unified
+       .thumb
+
+       .text
+
+       .global multiple_personality_disorder
+       .type multiple_personality_disorder,%function
+multiple_personality_disorder:
+       .fnstart
+       .personality __gcc_personality_v0
+       .personality __gxx_personality_v0
+       .personality __gxx_personality_sj0
+       .cantunwind
+
+@ CHECK: error: .cantunwind can't be used with .personality directive
+@ CHECK: .cantunwind
+@ CHECK: ^
+@ CHECK: note: .personality was specified here
+@ CHECK: .personality __gcc_personality_v0
+@ CHECK: ^
+@ CHECK: note: .personality was specified here
+@ CHECK: .personality __gxx_personality_v0
+@ CHECK: ^
+@ CHECK: note: .personality was specified here
+@ CHECK: .personality __gxx_personality_sj0
+@ CHECK: ^
+