diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-09-05 11:26:19 +0000 | 
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-09-05 11:26:19 +0000 | 
| commit | 2545aeb710ef0b02c887f008fe718a2bbf8a1de8 (patch) | |
| tree | 2211a9d82fb2e080391b207b6c32104bf6fa510a /clang/lib/Parse/ParseDecl.cpp | |
| parent | 971dd236f000fac4214d2c83536892a6d9598b07 (diff) | |
| download | bcm5719-llvm-2545aeb710ef0b02c887f008fe718a2bbf8a1de8.tar.gz bcm5719-llvm-2545aeb710ef0b02c887f008fe718a2bbf8a1de8.zip | |
Support "typeof unary-expression" (GNU C++ extension).
llvm-svn: 55833
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 26 | 
1 files changed, 22 insertions, 4 deletions
| diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index cd2dda2941e..2a8ab3f8db7 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1556,9 +1556,10 @@ void Parser::ParseBracketDeclarator(Declarator &D) {                                            NumElements.Val, StartLoc));  } -/// [GNU] typeof-specifier: -///         typeof ( expressions ) -///         typeof ( type-name ) +/// [GNU]   typeof-specifier: +///           typeof ( expressions ) +///           typeof ( type-name ) +/// [GNU/C++] typeof unary-expression  ///  void Parser::ParseTypeofSpecifier(DeclSpec &DS) {    assert(Tok.is(tok::kw_typeof) && "Not a typeof specifier"); @@ -1566,9 +1567,26 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {    SourceLocation StartLoc = ConsumeToken();    if (Tok.isNot(tok::l_paren)) { -    Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName()); +    if (!getLang().CPlusPlus) { +      Diag(Tok, diag::err_expected_lparen_after, BuiltinII->getName()); +      return; +    } + +    ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/); +    if (Result.isInvalid) +      return; + +    const char *PrevSpec = 0; +    // Check for duplicate type specifiers. +    if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,  +                           Result.Val)) +      Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); + +    // FIXME: Not accurate, the range gets one token more than it should. +    DS.SetRangeEnd(Tok.getLocation());      return;    } +    SourceLocation LParenLoc = ConsumeParen(), RParenLoc;    if (isTypeSpecifierQualifier()) { | 

