[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