diff options
author | Steve Naroff <snaroff@apple.com> | 2007-07-31 12:34:36 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-07-31 12:34:36 +0000 |
commit | d1861fd633d5096a00777c918eb8575ea7162fe7 (patch) | |
tree | cd71c78f1c513b18ab427f6036aa2debdcb7d93a /Parse/ParseDecl.cpp | |
parent | 8a2bc625e86983e250ed31040695a870a767196b (diff) |
Add parsing and AST support for GNU "typeof".
Many small changes to lot's of files.
Still some FIXME's, however the basic support is in place.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40631 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Parse/ParseDecl.cpp')
-rw-r--r-- | Parse/ParseDecl.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/Parse/ParseDecl.cpp b/Parse/ParseDecl.cpp index b05fd7898d..6b5215b90c 100644 --- a/Parse/ParseDecl.cpp +++ b/Parse/ParseDecl.cpp @@ -482,6 +482,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { ParseEnumSpecifier(DS); continue; + // GNU typeof support. + case tok::kw_typeof: + ParseTypeofSpecifier(DS); + continue; + // type-qualifier case tok::kw_const: isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, @@ -825,6 +830,9 @@ bool Parser::isTypeSpecifierQualifier() const { default: return false; // GNU attributes support. case tok::kw___attribute: + // GNU typeof support. + case tok::kw_typeof: + // type-specifiers case tok::kw_short: case tok::kw_long: @@ -902,6 +910,9 @@ bool Parser::isDeclarationSpecifier() const { case tok::kw_const: case tok::kw_volatile: case tok::kw_restrict: + + // GNU typeof support. + case tok::kw_typeof: // function-specifier case tok::kw_inline: @@ -1397,3 +1408,40 @@ void Parser::ParseBracketDeclarator(Declarator &D) { NumElements.Val, StartLoc)); } +/// [GNU] typeof-specifier: +/// typeof ( expressions ) +/// typeof ( type-name ) +/// +void Parser::ParseTypeofSpecifier(DeclSpec &DS) { + assert(Tok.getKind() == tok::kw_typeof && "Not a typeof specifier"); + SourceLocation StartLoc = ConsumeToken(); + + if (Tok.getKind() != tok::l_paren) { + // FIXME: handle error. + } + SourceLocation LParenLoc = ConsumeParen(), RParenLoc; + + if (isTypeSpecifierQualifier()) { + TypeTy *Ty = ParseTypeName(); + + const char *PrevSpec = 0; + bool isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, + PrevSpec, Ty); + // FIXME: what we have an invalid type? (or Ty is null) + } else { // we have an expression. + ExprResult Result = ParseExpression(); + if (Result.isInvalid) { + SkipUntil(tok::r_paren); + } + const char *PrevSpec = 0; + bool isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, + PrevSpec, Result.Val); + // FIXME: what we have an invalid type? (or Result.Val is null) + } + // Match the ')'. + if (Tok.getKind() == tok::r_paren) + RParenLoc = ConsumeParen(); + else + MatchRHSPunctuation(tok::r_paren, LParenLoc); +} + |