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


Author: sabre
Date: Wed Jul 11 11:25:18 2007
New Revision: 38865

URL: http://llvm.org/viewvc/llvm-project?rev=38865&view=rev
Log:
Implement type-name parsing, and simple compound initializer parsing.

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

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:25:18 2007
@@ -20,6 +20,37 @@
 // C99 6.7: Declarations.
 //===----------------------------------------------------------------------===//
 
+/// ParseTypeName
+///       type-name: [C99 6.7.6]
+///         specifier-qualifier-list abstract-declarator[opt]
+void Parser::ParseTypeName() {
+  // Parse the common declaration-specifiers piece.
+  DeclSpec DS;
+  SourceLocation Loc = Tok.getLocation();
+  ParseDeclarationSpecifiers(DS);
+  
+  // Validate declspec for type-name.
+  unsigned Specs = DS.getParsedSpecifiers();
+  if (Specs == DeclSpec::PQ_None)
+    Diag(Tok, diag::err_typename_requires_specqual);
+  
+  if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
+    Diag(Loc, diag::err_typename_invalid_storageclass);
+    // Remove storage class.
+    DS.StorageClassSpec     = DeclSpec::SCS_unspecified;
+    DS.SCS_thread_specified = false;
+  }
+  if (Specs & DeclSpec::PQ_FunctionSpecifier) {
+    Diag(Loc, diag::err_typename_invalid_functionspec);
+    DS.FS_inline_specified = false;
+  }
+  
+  // Parse the abstract-declarator, if present.
+  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+  ParseDeclarator(DeclaratorInfo);
+}
+
+
 /// ParseDeclaration - Parse a full 'declaration', which consists of
 /// declaration-specifiers, some number of declarators, and a semicolon.
 /// 'Context' should be a Declarator::TheContext value.
@@ -244,6 +275,49 @@
   }
 }
 
+/// isTypeSpecifierQualifier - Return true if the current token could be the
+/// start of a specifier-qualifier-list.
+bool Parser::isTypeSpecifierQualifier() const {
+  switch (Tok.getKind()) {
+  default: return false;
+    // type-specifiers
+  case tok::kw_short:
+  case tok::kw_long:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw__Complex:
+  case tok::kw__Imaginary:
+  case tok::kw_void:
+  case tok::kw_char:
+  case tok::kw_int:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw__Bool:
+  case tok::kw__Decimal32:
+  case tok::kw__Decimal64:
+  case tok::kw__Decimal128:
+    
+    // struct-or-union-specifier
+  case tok::kw_struct:
+  case tok::kw_union:
+    // enum-specifier
+  case tok::kw_enum:
+    
+    // type-qualifier
+  case tok::kw_const:
+  case tok::kw_volatile:
+  case tok::kw_restrict:
+    return true;
+    
+    // typedef-name
+  case tok::identifier:
+    // FIXME: if this is a typedef return true.
+    return false;
+    
+    // TODO: Attributes.
+  }
+}
+
 /// isDeclarationSpecifier() - Return true if the current token is part of a
 /// declaration specifier.
 bool Parser::isDeclarationSpecifier() const {
@@ -279,13 +353,16 @@
   case tok::kw_union:
     // enum-specifier
   case tok::kw_enum:
+    
     // type-qualifier
   case tok::kw_const:
   case tok::kw_volatile:
   case tok::kw_restrict:
+    
     // function-specifier
   case tok::kw_inline:
     return true;
+    
     // typedef-name
   case tok::identifier:
     // FIXME: if this is a typedef return true.

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

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:18 2007
@@ -19,6 +19,15 @@
 // C99 6.7.8
 void Parser::ParseInitializer() {
   // FIXME: STUB.
+  if (Tok.getKind() == tok::l_brace) {
+    ConsumeBrace();
+    // FIXME: initializer-list
+    // Match the '}'.
+    MatchRHSPunctuation(tok::r_brace, Tok.getLocation(), "{",
+                        diag::err_expected_rbrace);
+    return;
+  }
+  
   ParseAssignmentExpression();
 }
 
@@ -44,10 +53,12 @@
   if (Tok.getKind() != tok::l_paren)
     return ParseUnaryExpression();
   
+#if 0
   // Otherwise this is either a cast, a compound literal, or a parenthesized
   // expression.
   SourceLocation LParenLoc = Tok.getLocation();
   ConsumeParen();
+#endif
   
   assert(0);
 }
@@ -319,11 +330,22 @@
       !getLang().NoExtensions) {
     Diag(Tok, diag::ext_gnu_statement_expr);
     ParseCompoundStatement();
-  } else if (!ParenExprOnly && isTypeSpecifierQualifier()) { 
-    // FIXME: Implement compound literals: C99 6.5.2.5.  Type-name: C99 6.7.6.
-    assert(0 && "IMPLEMENT THIS!");
-  } else {
+  } else if (ParenExprOnly || !isTypeSpecifierQualifier()) {
     ParseExpression();
+  } else {
+    // Otherwise, this is a compound expression.
+    ParseTypeName();
+
+    // Match the ')'.
+    MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen);
+
+    if (Tok.getKind() != tok::l_brace) {
+      Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
+      return;
+    }
+    
+    ParseInitializer();
+    return;
   }
   
   

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=38865&r1=38864&r2=38865&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:18 2007
@@ -288,6 +288,8 @@
      "expected statement")
 DIAG(err_expected_lparen_after, ERROR,
      "expected '(' after '%s'")
+DIAG(err_expected_lbrace_in_compound_literal, ERROR,
+     "expected '{' in compound literal")
 DIAG(err_expected_while, ERROR,
      "expected 'while' in do/while loop")
 DIAG(err_expected_semi_after, ERROR,
@@ -306,7 +308,12 @@
 DIAG(err_matching, ERROR,
      "to match this '%s'")
 
-     
+DIAG(err_typename_requires_specqual, ERROR,
+     "type name requires a specifier or qualifier")
+DIAG(err_typename_invalid_storageclass, ERROR,
+     "type name does not allow storage class to be specified")
+DIAG(err_typename_invalid_functionspec, ERROR,
+     "type name does not allow function specifier to be specified")
 DIAG(err_invalid_decl_spec_combination, ERROR,
      "cannot combine with previous '%s' declaration specifier")
 DIAG(err_invalid_sign_spec, 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=38865&r1=38864&r2=38865&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:18 2007
@@ -204,7 +204,9 @@
   void ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
   void ParseDeclarationSpecifiers(DeclSpec &DS);
   bool isDeclarationSpecifier() const;
-  bool isTypeSpecifierQualifier() const { return false; } // FIXME!
+  bool isTypeSpecifierQualifier() const;
+
+  void ParseTypeName();
   
   /// ParseDeclarator - Parse and verify a newly-initialized declarator.
   void ParseDeclarator(Declarator &D);





More information about the cfe-commits mailing list