[cfe-commits] r38896 - 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:34 PDT 2007
Author: sabre
Date: Wed Jul 11 11:25:34 2007
New Revision: 38896
URL: http://llvm.org/viewvc/llvm-project?rev=38896&view=rev
Log:
Implement parsing of enum-specifiers.
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=38896&r1=38895&r2=38896&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:25:34 2007
@@ -105,11 +105,11 @@
/// ParseDeclarationSpecifiers
/// declaration-specifiers: [C99 6.7]
-/// storage-class-specifier declaration-specifiers [opt]
-/// type-specifier declaration-specifiers [opt]
-/// type-qualifier declaration-specifiers [opt]
-/// [C99] function-specifier declaration-specifiers [opt]
-/// [GNU] attributes declaration-specifiers [opt] [TODO]
+/// storage-class-specifier declaration-specifiers[opt]
+/// type-specifier declaration-specifiers[opt]
+/// type-qualifier declaration-specifiers[opt]
+/// [C99] function-specifier declaration-specifiers[opt]
+/// [GNU] attributes declaration-specifiers[opt] [TODO]
///
/// storage-class-specifier: [C99 6.7.1]
/// 'typedef'
@@ -129,7 +129,7 @@
/// 'signed'
/// 'unsigned'
/// struct-or-union-specifier [TODO]
-/// enum-specifier [TODO]
+/// enum-specifier
/// typedef-name [TODO]
/// [C99] '_Bool'
/// [C99] '_Complex'
@@ -138,15 +138,15 @@
/// [GNU] '_Decimal64'
/// [GNU] '_Decimal128'
/// [GNU] typeof-specifier [TODO]
-/// [OBJC] class-name objc-protocol-refs [opt] [TODO]
+/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
/// [OBJC] typedef-name objc-protocol-refs [TODO]
/// [OBJC] objc-protocol-refs [TODO]
/// type-qualifier:
-/// const
-/// volatile
-/// [C99] restrict
+/// 'const'
+/// 'volatile'
+/// [C99] 'restrict'
/// function-specifier: [C99 6.7.4]
-/// [C99] inline
+/// [C99] 'inline'
///
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
SourceLocation StartLoc = Tok.getLocation();
@@ -159,7 +159,7 @@
// specifiers. First verify that DeclSpec's are consistent.
DS.Finish(StartLoc, Diags, getLang());
return;
- // FIXME: Handle struct/union/enum tags.
+ // FIXME: Handle struct/union tags.
// storage-class-specifier
case tok::kw_typedef:
@@ -242,7 +242,9 @@
//case tok::kw_struct:
//case tok::kw_union:
- //case tok::kw_enum:
+ case tok::kw_enum:
+ ParseEnumSpecifier(DS);
+ continue;
//case tok::identifier:
// TODO: handle typedef names.
@@ -276,6 +278,65 @@
}
}
+/// ParseEnumSpecifier
+/// enum-specifier:
+/// 'enum' identifier[opt] '{' enumerator-list '}'
+/// [C99] 'enum' identifier[opt] '{' enumerator-list ',' '}'
+/// 'enum' identifier
+/// enumerator-list:
+/// enumerator
+/// enumerator-list , enumerator
+/// enumerator:
+/// enumeration-constant
+/// enumeration-constant = constant-expression
+/// enumeration-constant:
+/// identifier
+///
+void Parser::ParseEnumSpecifier(DeclSpec &DS) {
+ assert(Tok.getKind() == tok::kw_enum && "Not an enum specifier");
+ ConsumeToken();
+
+ // Must have either 'enum name' or 'enum {...}'.
+ if (Tok.getKind() != tok::identifier &&
+ Tok.getKind() != tok::l_brace) {
+ Diag(Tok, diag::err_expected_ident_lbrace);
+ return;
+ }
+
+ if (Tok.getKind() == tok::identifier)
+ ConsumeToken();
+
+ if (Tok.getKind() == tok::l_brace) {
+ SourceLocation LBraceLoc = Tok.getLocation();
+ ConsumeBrace();
+
+ // Parse the enumerator-list.
+ while (Tok.getKind() == tok::identifier) {
+ ConsumeToken();
+
+ if (Tok.getKind() == tok::equal) {
+ ConsumeToken();
+ ExprResult Res = ParseConstantExpression();
+ if (Res.isInvalid) SkipUntil(tok::comma, true, false);
+ }
+
+ if (Tok.getKind() != tok::comma)
+ break;
+ SourceLocation CommaLoc = Tok.getLocation();
+ ConsumeToken();
+
+ if (Tok.getKind() != tok::identifier && !getLang().C99)
+ Diag(CommaLoc, diag::ext_c99_enumerator_list_comma);
+ }
+
+ // Eat the }.
+ MatchRHSPunctuation(tok::r_brace, LBraceLoc, "{",
+ diag::err_expected_rbrace);
+ }
+ // TODO: semantic analysis on the declspec for enums.
+}
+
+
/// isTypeSpecifierQualifier - Return true if the current token could be the
/// start of a specifier-qualifier-list.
bool Parser::isTypeSpecifierQualifier() const {
Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=38896&r1=38895&r2=38896&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:25:34 2007
@@ -204,6 +204,14 @@
return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
}
+Parser::ExprResult Parser::ParseConstantExpression() {
+ ExprResult LHS = ParseCastExpression(false);
+ if (LHS.isInvalid) return LHS;
+
+ // TODO: Validate that this is a constant expr!
+ return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+}
+
/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
/// in contexts where we have already consumed an identifier (which we saved in
/// 'Tok'), then discovered that the identifier was really the leading token of
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=38896&r1=38895&r2=38896&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:34 2007
@@ -258,6 +258,8 @@
"variable declaration in for loop is a C99-specific feature")
DIAG(ext_c99_compound_literal, EXTENSION,
"compound literals are a C99-specific feature")
+DIAG(ext_c99_enumerator_list_comma, EXTENSION,
+ "commas at the end of enumerator lists are a C99-specific feature")
DIAG(ext_gnu_indirect_goto, EXTENSION,
"use of GNU indirect-goto extension")
@@ -277,12 +279,14 @@
"expected identifier")
DIAG(err_expected_ident_lparen, ERROR,
"expected identifier or '('")
+DIAG(err_expected_ident_lbrace, ERROR,
+ "expected identifier or '{'")
DIAG(err_expected_rparen, ERROR,
"expected ')'")
DIAG(err_expected_rsquare, ERROR,
"expected ']'")
DIAG(err_expected_rbrace, ERROR,
- "expected '}' to end compound statement ('{}' block)")
+ "expected '}'")
DIAG(err_expected_semi_decl_list, ERROR,
"expected ';' at end of declaration list")
DIAG(err_expected_fn_body, 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=38896&r1=38895&r2=38896&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:34 2007
@@ -58,9 +58,6 @@
ExprResult(bool Invalid = false) : isInvalid(Invalid) {}
};
- ExprResult ParseExpression();
-
-
// Diagnostics.
void Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg = "");
void Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M = "") {
@@ -198,10 +195,12 @@
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
- //ExprResult ParseExpression(); // Above.
+ ExprResult ParseExpression();
+ ExprResult ParseConstantExpression();
+ ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
+
ExprResult ParseExpressionWithLeadingIdentifier(const LexerToken &Tok);
ExprResult ParseAssignmentExpressionWithLeadingStar(const LexerToken &Tok);
- ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
ExprResult ParseCastExpression(bool isUnaryExpression);
@@ -243,6 +242,8 @@
void ParseDeclaration(unsigned Context);
void ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
void ParseDeclarationSpecifiers(DeclSpec &DS);
+ void ParseEnumSpecifier(DeclSpec &DS);
+
bool isDeclarationSpecifier() const;
bool isTypeSpecifierQualifier() const;
More information about the cfe-commits
mailing list