summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2007-07-31 23:56:32 +0000
committerSteve Naroff <snaroff@apple.com>2007-07-31 23:56:32 +0000
commit872da803b25c620ab7b837ad3321dd12bfac5f2c (patch)
treec3da11091e899b925ee277ed7abf48c90293cfc8
parent10ffa860d80b302de2ec974999e8dea704601bbc (diff)
downloadbcm5719-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.cpp40
-rw-r--r--clang/test/Parser/typeof.c7
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 *'}}
OpenPOWER on IntegriCloud