[cfe-commits] r38893 - in /cfe/cfe/trunk: Parse/ParseExpr.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:33 PDT 2007


Author: sabre
Date: Wed Jul 11 11:25:32 2007
New Revision: 38893

URL: http://llvm.org/viewvc/llvm-project?rev=38893&view=rev
Log:
Parse the GNU builtin expressions.  This implements Parser/expressions.c:test_offsetof

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

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

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:32 2007
@@ -389,11 +389,6 @@
 ///         floating-constant
 ///         enumeration-constant -> identifier
 ///         character-constant
-/// 
-/// [GNU] offsetof-member-designator:
-/// [GNU]   identifier
-/// [GNU]   offsetof-member-designator '.' identifier
-/// [GNU]   offsetof-member-designator '[' expression ']'
 ///
 Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
   ExprResult Res;
@@ -455,9 +450,7 @@
   case tok::kw___builtin_offsetof:
   case tok::kw___builtin_choose_expr:
   case tok::kw___builtin_types_compatible_p:
-    assert(0 && "FIXME: UNIMP!");
-    // This can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParseBuiltinPrimaryExpression();
   case tok::plusplus:      // unary-expression: '++' unary-expression
   case tok::minusminus:    // unary-expression: '--' unary-expression
     ConsumeToken();
@@ -594,6 +587,144 @@
   return ParseParenExpression(ExprType);
 }
 
+/// ParseBuiltinPrimaryExpression
+///
+///       primary-expression: [C99 6.5.1]
+/// [GNU]   '__builtin_va_arg' '(' assignment-expression ',' type-name ')'
+/// [GNU]   '__builtin_offsetof' '(' type-name ',' offsetof-member-designator')'
+/// [GNU]   '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
+///                                     assign-expr ')'
+/// [GNU]   '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+/// 
+/// [GNU] offsetof-member-designator:
+/// [GNU]   identifier
+/// [GNU]   offsetof-member-designator '.' identifier
+/// [GNU]   offsetof-member-designator '[' expression ']'
+///
+Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
+  ExprResult Res(false);
+  SourceLocation StartLoc = Tok.getLocation();
+  const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
+
+  tok::TokenKind T = Tok.getKind();
+  ConsumeToken();   // Eat the builtin identifier.
+
+  // All of these start with an open paren.
+  if (Tok.getKind() != tok::l_paren) {
+    Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName());
+    return ExprResult(true);
+  }
+  
+  SourceLocation LParenLoc = Tok.getLocation();
+  ConsumeParen();
+  
+  switch (T) {
+  default: assert(0 && "Not a builtin primary expression!");
+  case tok::kw___builtin_va_arg:
+    Res = ParseAssignmentExpression();
+    if (Res.isInvalid) {
+      SkipUntil(tok::r_paren);
+      return Res;
+    }
+    if (Tok.getKind() != tok::comma) {
+      Diag(Tok, diag::err_expected_comma);
+      SkipUntil(tok::r_paren);
+      return ExprResult(true);
+    }
+    ConsumeToken();
+    
+    ParseTypeName();
+    break;
+    
+  case tok::kw___builtin_offsetof:
+    ParseTypeName();
+
+    if (Tok.getKind() != tok::comma) {
+      Diag(Tok, diag::err_expected_comma);
+      SkipUntil(tok::r_paren);
+      return ExprResult(true);
+    }
+    ConsumeToken();
+    
+    // We must have at least one identifier here.
+    if (Tok.getKind() != tok::identifier) {
+      Diag(Tok, diag::err_expected_ident);
+      SkipUntil(tok::r_paren);
+      return ExprResult(true);
+    }
+    ConsumeToken();
+    
+    while (1) {
+      if (Tok.getKind() == tok::period) {
+        // offsetof-member-designator: offsetof-member-designator '.' identifier
+        ConsumeToken();
+        
+        if (Tok.getKind() != tok::identifier) {
+          Diag(Tok, diag::err_expected_ident);
+          SkipUntil(tok::r_paren);
+          return ExprResult(true);
+        }
+        ConsumeToken();
+      } else if (Tok.getKind() == tok::l_square) {
+        // offsetof-member-designator: offsetof-member-design '[' expression ']'
+        SourceLocation LSquareLoc = Tok.getLocation();
+        ConsumeBracket();
+        Res = ParseExpression();
+        if (Res.isInvalid) {
+          SkipUntil(tok::r_paren);
+          return Res;
+        }
+
+        MatchRHSPunctuation(tok::r_square, LSquareLoc, "[",
+                            diag::err_expected_rsquare);
+      } else {
+        break;
+      }
+    }
+    break;
+  case tok::kw___builtin_choose_expr:
+    Res = ParseAssignmentExpression();
+    
+    if (Tok.getKind() != tok::comma) {
+      Diag(Tok, diag::err_expected_comma);
+      SkipUntil(tok::r_paren);
+      return ExprResult(true);
+    }
+    ConsumeToken();
+    
+    Res = ParseAssignmentExpression();
+    
+    if (Tok.getKind() != tok::comma) {
+      Diag(Tok, diag::err_expected_comma);
+      SkipUntil(tok::r_paren);
+      return ExprResult(true);
+    }
+    ConsumeToken();
+    
+    Res = ParseAssignmentExpression();
+    break;
+  case tok::kw___builtin_types_compatible_p:
+    ParseTypeName();
+    
+    if (Tok.getKind() != tok::comma) {
+      Diag(Tok, diag::err_expected_comma);
+      SkipUntil(tok::r_paren);
+      return ExprResult(true);
+    }
+    ConsumeToken();
+    
+    ParseTypeName();
+    break;
+  }      
+  
+  MatchRHSPunctuation(tok::r_paren, LParenLoc, "(",
+                      diag::err_expected_rparen);
+  
+  // These can be followed by postfix-expr pieces because they are
+  // primary-expressions.
+  return ParsePostfixExpressionSuffix(Res);
+}
+
 /// ParseStringLiteralExpression - This handles the various token types that
 /// form string literals, and also handles string concatenation [C99 5.1.1.2,
 /// translation phase #6].

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=38893&r1=38892&r2=38893&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:32 2007
@@ -293,6 +293,8 @@
      "expected statement")
 DIAG(err_expected_lparen_after, ERROR,
      "expected '(' after '%s'")
+DIAG(err_expected_comma, ERROR,
+     "expected ','")
 DIAG(err_expected_lbrace_in_compound_literal, ERROR,
      "expected '{' in compound literal")
 DIAG(err_expected_while, ERROR,

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=38893&r1=38892&r2=38893&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:32 2007
@@ -186,6 +186,7 @@
   ExprResult ParseCastExpression(bool isUnaryExpression);
   ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
   ExprResult ParseSizeofAlignofExpression();
+  ExprResult ParseBuiltinPrimaryExpression();
   
   /// ParenParseOption - Control what ParseParenExpression will parse.
   enum ParenParseOption {





More information about the cfe-commits mailing list