[cfe-commits] r38922 - in /cfe/cfe/trunk: Parse/ParseDecl.cpp Parse/ParseExpr.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:48 PDT 2007


Author: sabre
Date: Wed Jul 11 11:25:47 2007
New Revision: 38922

URL: http://llvm.org/viewvc/llvm-project?rev=38922&view=rev
Log:
Parse asm specifiers on init declarators.  Add __builtin_va_list to the
symbol table at startup time.

Modified:
    cfe/cfe/trunk/Parse/ParseDecl.cpp
    cfe/cfe/trunk/Parse/ParseExpr.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/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=38922&r1=38921&r2=38922&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:25:47 2007
@@ -74,12 +74,19 @@
 ///       init-declarator: [C99 6.7]
 ///         declarator
 ///         declarator '=' initializer
+/// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
+/// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
 ///
 void Parser::ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
   // At this point, we know that it is not a function definition.  Parse the
   // rest of the init-declarator-list.
   while (1) {
-    // must be: decl-spec[opt] declarator init-declarator-list
+    // If a simple-asm-expr is present, parse it.
+    if (Tok.getKind() == tok::kw_asm)
+      ParseSimpleAsm();
+    
+    // TODO: parse attributes.
+    
     // Parse declarator '=' initializer.
     ExprResult Init;
     if (Tok.getKind() == tok::equal) {

Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=38922&r1=38921&r2=38922&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:47 2007
@@ -643,7 +643,7 @@
       return Res;
     }
 
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, tok::r_paren))
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprResult(true);
 
     ParseTypeName();
@@ -652,11 +652,11 @@
   case tok::kw___builtin_offsetof:
     ParseTypeName();
 
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, tok::r_paren))
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprResult(true);
     
     // We must have at least one identifier here.
-    if (ExpectAndConsume(tok::identifier, diag::err_expected_ident,
+    if (ExpectAndConsume(tok::identifier, diag::err_expected_ident, "",
                          tok::r_paren))
       return ExprResult(true);
 
@@ -665,7 +665,7 @@
         // offsetof-member-designator: offsetof-member-designator '.' identifier
         ConsumeToken();
         
-        if (ExpectAndConsume(tok::identifier, diag::err_expected_ident,
+        if (ExpectAndConsume(tok::identifier, diag::err_expected_ident, "",
                              tok::r_paren))
           return ExprResult(true);
       } else if (Tok.getKind() == tok::l_square) {
@@ -688,12 +688,12 @@
   case tok::kw___builtin_choose_expr:
     Res = ParseAssignmentExpression();
     
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, tok::r_paren))
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprResult(true);
     
     Res = ParseAssignmentExpression();
     
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, tok::r_paren))
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprResult(true);
     
     Res = ParseAssignmentExpression();
@@ -701,7 +701,7 @@
   case tok::kw___builtin_types_compatible_p:
     ParseTypeName();
     
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, tok::r_paren))
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprResult(true);
     
     ParseTypeName();

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

==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:25:47 2007
@@ -63,13 +63,13 @@
 /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
 /// returned.
 bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
-                              tok::TokenKind SkipToTok) {
+                              const char *Msg, tok::TokenKind SkipToTok) {
   if (Tok.getKind() == ExpectedTok) {
     ConsumeToken();
     return false;
   }
   
-  Diag(Tok, DiagID);
+  Diag(Tok, DiagID, Msg);
   if (SkipToTok != tok::unknown)
     SkipUntil(SkipToTok);
   return true;
@@ -200,6 +200,23 @@
   assert(CurScope == 0 && "A scope is already active?");
   EnterScope();
 
+  
+  // Install builtin types.
+  // TODO: Move this someplace more useful.
+  {
+    //__builtin_va_list
+    DeclSpec DS;
+    DS.StorageClassSpec = DeclSpec::SCS_typedef;
+    
+    // TODO: add a 'TST_builtin' type?
+    DS.TypeSpecType = DeclSpec::TST_typedef;
+
+    Declarator D(DS, Declarator::FileContext);
+    D.SetIdentifier(PP.getIdentifierInfo("__builtin_va_list"),SourceLocation());
+    Actions.ParseDeclarator(SourceLocation(), CurScope, D, 0);
+  }
+  
+  
   if (Tok.getKind() == tok::eof)  // Empty source file is an extension.
     Diag(diag::ext_empty_source_file);
   
@@ -215,7 +232,7 @@
 ///         function-definition        [TODO]
 ///         declaration                [TODO]
 /// [EXT]   ';'
-/// [GNU]   asm-definition             [TODO]
+/// [GNU]   asm-definition
 /// [GNU]   __extension__ external-declaration     [TODO]
 /// [OBJC]  objc-class-definition      [TODO]
 /// [OBJC]  objc-class-declaration     [TODO]
@@ -224,12 +241,20 @@
 /// [OBJC]  objc-method-definition     [TODO]
 /// [OBJC]  @end                       [TODO]
 ///
+/// [GNU] asm-definition:
+///         simple-asm-expr ';'
+///
 void Parser::ParseExternalDeclaration() {
   switch (Tok.getKind()) {
   case tok::semi:
     Diag(diag::ext_top_level_semi);
     ConsumeToken();
     break;
+  case tok::kw_asm:
+    ParseSimpleAsm();
+    ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
+                     "top-level asm block");
+    break;
   default:
     // We can't tell whether this is a function-definition or declaration yet.
     ParseDeclarationOrFunctionDefinition();
@@ -344,3 +369,39 @@
   ParseCompoundStatement();
 }
 
+/// 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!");
+  ConsumeToken();
+  
+  if (Tok.getKind() != tok::l_paren) {
+    Diag(Tok, diag::err_expected_lparen_after, "asm");
+    return;
+  }
+  
+  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'
+  
+  MatchRHSPunctuation(tok::r_paren, Loc, "(", diag::err_expected_rparen);
+}

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=38922&r1=38921&r2=38922&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:47 2007
@@ -328,6 +328,8 @@
      "label at end of compound statement: expected statement")
 DIAG(err_expected_colon, ERROR,
      "expected ':'")
+DIAG(err_expected_string_literal, ERROR,
+     "expected string literal")
 
 /// 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=38922&r1=38921&r2=38922&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:47 2007
@@ -166,6 +166,7 @@
   /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
   /// returned.
   bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
+                        const char *DiagMsg = "",
                         tok::TokenKind SkipToTok = tok::unknown);
 
   //===--------------------------------------------------------------------===//
@@ -204,7 +205,8 @@
   void ParseExternalDeclaration();
   void ParseDeclarationOrFunctionDefinition();
   void ParseFunctionDefinition(Declarator &D);
-
+  void ParseSimpleAsm();
+  
   //===--------------------------------------------------------------------===//
   // C99 6.5: Expressions.
   





More information about the cfe-commits mailing list