diff options
author | Steve Naroff <snaroff@apple.com> | 2007-07-31 23:56:32 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-07-31 23:56:32 +0000 |
commit | 872da803b25c620ab7b837ad3321dd12bfac5f2c (patch) | |
tree | c3da11091e899b925ee277ed7abf48c90293cfc8 | |
parent | 10ffa860d80b302de2ec974999e8dea704601bbc (diff) | |
download | bcm5719-llvm-872da803b25c620ab7b837ad3321dd12bfac5f2c.tar.gz bcm5719-llvm-872da803b25c620ab7b837ad3321dd12bfac5f2c.zip |
Tighten up Parser::ParseTypeofSpecifier().
Add some more tests to typeof.c. Also added a couple of missing "expect" attributes that caused the test to fail.
llvm-svn: 40656
-rw-r--r-- | clang/Parse/ParseDecl.cpp | 40 | ||||
-rw-r--r-- | clang/test/Parser/typeof.c | 7 |
2 files changed, 29 insertions, 18 deletions
diff --git a/clang/Parse/ParseDecl.cpp b/clang/Parse/ParseDecl.cpp index 6b5215b90c5..843c6eb1a76 100644 --- a/clang/Parse/ParseDecl.cpp +++ b/clang/Parse/ParseDecl.cpp @@ -354,7 +354,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) { /// [GNU] '_Decimal32' /// [GNU] '_Decimal64' /// [GNU] '_Decimal128' -/// [GNU] typeof-specifier [TODO] +/// [GNU] typeof-specifier /// [OBJC] class-name objc-protocol-refs[opt] [TODO] /// [OBJC] typedef-name objc-protocol-refs [TODO] /// [OBJC] objc-protocol-refs [TODO] @@ -1424,24 +1424,30 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { 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) + assert(Ty && "Parser::ParseTypeofSpecifier(): missing type"); + + // Match the ')'. + if (Tok.getKind() == tok::r_paren) { + RParenLoc = ConsumeParen(); + const char *PrevSpec = 0; + if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty)) + // Duplicate type specifiers (e.g. "int typeof(int)). + Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); + } else // error + MatchRHSPunctuation(tok::r_paren, LParenLoc); } 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 (!Result.isInvalid && Tok.getKind() == tok::r_paren) { + RParenLoc = ConsumeParen(); + const char *PrevSpec = 0; + if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, + Result.Val)) + // Duplicate type specifiers (e.g. "int typeof(int)). + Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); + } else // error + MatchRHSPunctuation(tok::r_paren, LParenLoc); } - // Match the ')'. - if (Tok.getKind() == tok::r_paren) - RParenLoc = ConsumeParen(); - else - MatchRHSPunctuation(tok::r_paren, LParenLoc); } diff --git a/clang/test/Parser/typeof.c b/clang/test/Parser/typeof.c index 4829713b272..8556687123c 100644 --- a/clang/test/Parser/typeof.c +++ b/clang/test/Parser/typeof.c @@ -5,11 +5,16 @@ typedef int TInt; static void test() { int *pi; + int typeof (int) aIntInt; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{extension used}} + short typeof (int) aShortInt; // expected-error{{'short typeof' is invalid}} expected-warning{{extension used}} + int int ttt; // expected-error{{cannot combine with previous 'int' declaration specifier}} typeof(TInt) anInt; // expected-warning{{extension used}} + short TInt eee; // expected-error{{parse error}} + void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{parse error}} + typeof(void ary[7]) anIntError; // expected-warning{{extension used}} expected-error{{expected ')'}} expected-error{{to match this '('}} typeof(const int) aci; // expected-warning{{extension used}} const typeof (*pi) aConstInt; // expected-warning{{extension used}} int xx; - short typeof (*pi) aShortInt; // expected-error{{'short typeof' is invalid}} int *i; i = aci; // expected-warning{{incompatible types assigning 'typeof(int const)' to 'int *'}} i = anInt; // expected-warning{{incompatible types assigning 'typeof(TInt)' to 'int *'}} |