Add a test for the .seh_handler directive. Fix problems with the parsing
authorCharles Davis <cdavis@mines.edu>
Wed, 25 May 2011 01:33:42 +0000 (01:33 +0000)
committerCharles Davis <cdavis@mines.edu>
Wed, 25 May 2011 01:33:42 +0000 (01:33 +0000)
method exposed by the test. While we're at it, simplify the .seh_proc
parsing method.

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

lib/MC/MCParser/COFFAsmParser.cpp
test/MC/AsmParser/directive_seh.s

index ce99509fe78fcae14307fb0052009538d4a7cf7b..fa7ae5cf148a829369602de0076d0d7b601dddb6 100644 (file)
@@ -184,20 +184,17 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
 }
 
 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
-  const MCExpr *e;
-  const MCSymbolRefExpr *funcExpr;
-  SMLoc startLoc = getLexer().getLoc();
-  if (getParser().ParseExpression(e))
+  StringRef SymbolID;
+  if (getParser().ParseIdentifier(SymbolID))
     return true;
 
-  if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
-    return Error(startLoc, "expected symbol");
-
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
+  MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
+
   Lex();
-  getStreamer().EmitWin64EHStartProc(&funcExpr->getSymbol());
+  getStreamer().EmitWin64EHStartProc(Symbol);
   return false;
 }
 
@@ -220,29 +217,28 @@ bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
 }
 
 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
-  const MCExpr *e;
-  const MCSymbolRefExpr *funcExpr;
-  SMLoc startLoc = getLexer().getLoc();
-  if (getParser().ParseExpression(e))
+  StringRef SymbolID;
+  if (getParser().ParseIdentifier(SymbolID))
     return true;
 
-  if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
-    return Error(startLoc, "expected symbol");
-
+  if (getLexer().isNot(AsmToken::Comma))
+    return TokError("you must specify one or both of @unwind or @except");
+  Lex();
   bool unwind = false, except = false;
-  startLoc = getLexer().getLoc();
-  if (!ParseAtUnwindOrAtExcept(unwind, except))
-    return Error(startLoc,"you must specify one or both of @unwind or @except");
+  if (ParseAtUnwindOrAtExcept(unwind, except))
+    return true;
   if (getLexer().is(AsmToken::Comma)) {
     Lex();
-    if (!ParseAtUnwindOrAtExcept(unwind, except))
+    if (ParseAtUnwindOrAtExcept(unwind, except))
       return true;
   }
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
+  MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID);
+
   Lex();
-  getStreamer().EmitWin64EHHandler(&funcExpr->getSymbol(), unwind, except);
+  getStreamer().EmitWin64EHHandler(handler, unwind, except);
   return false;
 }
 
@@ -372,12 +368,15 @@ bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
 
 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
   StringRef identifier;
+  if (getLexer().isNot(AsmToken::At))
+    return TokError("a handler attribute must begin with '@'");
   SMLoc startLoc = getLexer().getLoc();
-  if (!getParser().ParseIdentifier(identifier))
+  Lex();
+  if (getParser().ParseIdentifier(identifier))
     return Error(startLoc, "expected @unwind or @except");
-  if (identifier == "@unwind")
+  if (identifier == "unwind")
     unwind = true;
-  else if (identifier == "@except")
+  else if (identifier == "except")
     except = true;
   else
     return Error(startLoc, "expected @unwind or @except");
index 5fd2efad39a23a1f88aeb130a2624d2cfa33c9f7..7111fcc6b20ad413f7f77e36b41833ef3591f00e 100644 (file)
@@ -1,8 +1,9 @@
 # RUN: llvm-mc -triple x86_64-pc-win32 %s | FileCheck %s
 
 # CHECK: .seh_proc func
-# CHECK: .seh_stackalloc 8
+# CHECK: .seh_stackalloc 24
 # CHECK: .seh_endprologue
+# CHECK: .seh_handler __C_specific_handler, @except
 # CHECK: .seh_endproc
 
     .text
     .def func; .scl 2; .type 32; .endef
     .seh_proc func
 func:
-    subq $8, %rsp
-    .seh_stackalloc 8
+    subq $24, %rsp
+    .seh_stackalloc 24
     .seh_endprologue
-    addq $8, %rsp
+    .seh_handler __C_specific_handler, @except
+    addq $24, %rsp
     ret
     .seh_endproc