[cfe-commits] r38929 - in /cfe/cfe/trunk: Parse/ParseStmt.cpp Parse/Parser.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:25:53 PDT 2007


Author: sabre
Date: Wed Jul 11 11:25:52 2007
New Revision: 38929

URL: http://llvm.org/viewvc/llvm-project?rev=38929&view=rev
Log:
Implement asm statement parsing.

Modified:
    cfe/cfe/trunk/Parse/ParseStmt.cpp
    cfe/cfe/trunk/Parse/Parser.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=38929&r1=38928&r2=38929&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:25:52 2007
@@ -37,7 +37,7 @@
 /// [OBC]   objc-throw-statement         [TODO]
 /// [OBC]   objc-try-catch-statement     [TODO]
 /// [OBC]   objc-synchronized-statement  [TODO]
-/// [GNU]   asm-statement                [TODO]
+/// [GNU]   asm-statement
 /// [OMP]   openmp-construct             [TODO]
 ///
 ///       labeled-statement:
@@ -159,6 +159,11 @@
     ParseReturnStatement();
     SemiError = "return statement";
     break;
+    
+  case tok::kw_asm:
+    ParseAsmStatement();
+    SemiError = "asm statement";
+    break;
   }
   
   // If we reached this code, the statement must end in a semicolon.
@@ -543,3 +548,126 @@
       SkipUntil(tok::semi, false, true);
   }
 }
+
+/// ParseAsmStatement - Parse a GNU extended asm statement.
+/// [GNU] asm-statement:
+///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
+///
+/// [GNU] asm-argument:
+///         asm-string-literal
+///         asm-string-literal ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///                 ':' asm-clobbers
+///
+/// [GNU] asm-clobbers:
+///         asm-string-literal
+///         asm-clobbers ',' asm-string-literal
+///
+void Parser::ParseAsmStatement() {
+  assert(Tok.getKind() == tok::kw_asm && "Not an asm stmt");
+  ConsumeToken();
+  
+  DeclSpec DS;
+  SourceLocation Loc = Tok.getLocation();
+  ParseTypeQualifierListOpt(DS);
+  
+  // GNU asms accept, but warn, about type-qualifiers other than volatile.
+  if (DS.TypeQualifiers & DeclSpec::TQ_const)
+    Diag(Loc, diag::w_asm_qualifier_ignored, "const");
+  if (DS.TypeQualifiers & DeclSpec::TQ_restrict)
+    Diag(Loc, diag::w_asm_qualifier_ignored, "restrict");
+  
+  // Remember if this was a volatile asm.
+  bool isVolatile = DS.TypeQualifiers & DeclSpec::TQ_volatile;
+  
+  if (Tok.getKind() != tok::l_paren) {
+    Diag(Tok, diag::err_expected_lparen_after, "asm");
+    SkipUntil(tok::r_paren);
+    return;
+  }
+  Loc = Tok.getLocation();
+  ConsumeParen();
+  
+  ParseAsmStringLiteral();
+  
+  // Parse Outputs, if present.
+  ParseAsmOperandsOpt();
+  
+  // Parse Inputs, if present.
+  ParseAsmOperandsOpt();
+  
+  // Parse the clobbers, if present.
+  if (Tok.getKind() == tok::colon) {
+    ConsumeToken();
+    
+    if (Tok.getKind() == tok::string_literal) {
+      // Parse the asm-string list for clobbers.
+      while (1) {
+        ParseAsmStringLiteral();
+
+        if (Tok.getKind() != tok::comma) break;
+        ConsumeToken();
+      }
+    }
+  }
+  
+  MatchRHSPunctuation(tok::r_paren, Loc);
+}
+
+/// ParseAsmOperands - Parse the asm-operands production as used by
+/// asm-statement.  We also parse a leading ':' token.  If the leading colon is
+/// not present, we do not parse anything.
+///
+/// [GNU] asm-operands:
+///         asm-operand
+///         asm-operands ',' asm-operand
+///
+/// [GNU] asm-operand:
+///         asm-string-literal '(' expression ')'
+///         '[' identifier ']' asm-string-literal '(' expression ')'
+///
+void Parser::ParseAsmOperandsOpt() {
+  // Only do anything if this operand is present.
+  if (Tok.getKind() != tok::colon) return;
+  ConsumeToken();
+  
+  // 'asm-operands' isn't present?
+  if (Tok.getKind() != tok::string_literal && Tok.getKind() != tok::l_square)
+    return;
+  
+  while (1) {
+    // Read the [id] if present.
+    if (Tok.getKind() == tok::l_square) {
+      SourceLocation Loc = Tok.getLocation();
+      ConsumeBracket();
+      
+      if (Tok.getKind() != tok::identifier) {
+        Diag(Tok, diag::err_expected_ident);
+        SkipUntil(tok::r_paren);
+        return;
+      }
+      MatchRHSPunctuation(tok::r_square, Loc);
+    }
+    
+    ParseAsmStringLiteral();
+
+    if (Tok.getKind() != tok::l_paren) {
+      Diag(Tok, diag::err_expected_lparen_after, "asm operand");
+      SkipUntil(tok::r_paren);
+      return;
+    }
+    
+    // Read the parenthesized expression.
+    ParenParseOption ExprTy = SimpleExpr;
+    ExprResult Res = ParseParenExpression(ExprTy);
+    if (Res.isInvalid) {
+      SkipUntil(tok::r_paren);
+      return;
+    }
+
+    // Eat the comma and continue parsing if it exists.
+    if (Tok.getKind() != tok::comma) return;
+    ConsumeToken();
+  }
+}

Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=38929&r1=38928&r2=38929&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:25:52 2007
@@ -376,12 +376,28 @@
   ParseCompoundStatement();
 }
 
+/// ParseAsmStringLiteral - This is just a normal string-literal, but is not
+/// allowed to be a wide string, and is not subject to character translation.
+///
+/// [GNU] asm-string-literal:
+///         string-literal
+///
+void Parser::ParseAsmStringLiteral() {
+  if (Tok.getKind() != tok::string_literal) {
+    Diag(Tok, diag::err_expected_string_literal);
+    return;
+  }
+  
+  ExprResult Res = ParseStringLiteralExpression();
+  if (Res.isInvalid) return;
+  
+  // TODO: Diagnose: wide string literal in 'asm'
+}
+
 /// ParseSimpleAsm
 ///
 /// [GNU] simple-asm-expr:
 ///         'asm' '(' asm-string-literal ')'
-/// [GNU] asm-string-literal:
-///         string-literal
 ///
 void Parser::ParseSimpleAsm() {
   assert(Tok.getKind() == tok::kw_asm && "Not an asm!");
@@ -395,20 +411,7 @@
   SourceLocation Loc = Tok.getLocation();
   ConsumeParen();
   
-  if (Tok.getKind() != tok::string_literal) {
-    Diag(Tok, diag::err_expected_string_literal);
-    SkipUntil(tok::r_paren);
-    return;
-  }
-  
-  ExprResult Res = ParseStringLiteralExpression();
-  if (Res.isInvalid) {
-    Diag(Tok, diag::err_expected_string_literal);
-    SkipUntil(tok::r_paren);
-    return;
-  }
-  
-  // TODO: Diagnose: wide string literal in 'asm'
+  ParseAsmStringLiteral();
   
   MatchRHSPunctuation(tok::r_paren, Loc);
 }

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38929&r1=38928&r2=38929&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:52 2007
@@ -238,6 +238,8 @@
      "type defaults to 'int'")
 DIAG(w_no_declarators, WARNING,
      "declaration does not declare anything")
+DIAG(w_asm_qualifier_ignored, WARNING,
+     "ignored %s qualifier on asm")
 
 DIAG(ext_empty_source_file, EXTENSION,
      "ISO C forbids an empty source file")
@@ -330,6 +332,8 @@
      "expected ':'")
 DIAG(err_expected_string_literal, ERROR,
      "expected string literal")
+DIAG(err_expected_asm_operand, ERROR,
+     "expected string literal or '[' for asm operand")
 
 /// err_matching - this is used as a continuation of a previous error, e.g. to 
 /// specify the '(' when we expected a ')'.  This should probably be some

Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=38929&r1=38928&r2=38929&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:52 2007
@@ -205,6 +205,7 @@
   void ParseDeclarationOrFunctionDefinition();
   void ParseFunctionDefinition(Declarator &D);
   void ParseSimpleAsm();
+  void ParseAsmStringLiteral();
   
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.
@@ -254,6 +255,8 @@
   void ParseForStatement();
   void ParseGotoStatement();
   void ParseReturnStatement();
+  void ParseAsmStatement();
+  void ParseAsmOperandsOpt();
 
   //===--------------------------------------------------------------------===//
   // C99 6.7: Declarations.





More information about the cfe-commits mailing list