diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-18 17:45:20 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-18 17:45:20 +0000 |
commit | 809070a886684cb5b92eb0e00a6581ab1fa6b17a (patch) | |
tree | c3e6242279c488480f00bd966c7c46fcd7371eb3 /lib/Parse/ParseDecl.cpp | |
parent | e53f8206ebb36a17e95e64270704e2608d1796f4 (diff) |
Update Parser::ParseTypeName to return a TypeResult, which also tells
us whether there was an error in trying to parse a type-name (type-id
in C++). This allows propagation of errors further in the compiler,
suppressing more bogus error messages.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64922 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 9974aea005..6e68b20fa5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -28,7 +28,7 @@ using namespace clang; /// specifier-qualifier-list abstract-declarator[opt] /// /// Called type-id in C++. -Parser::TypeTy *Parser::ParseTypeName() { +Action::TypeResult Parser::ParseTypeName() { // Parse the common declaration-specifiers piece. DeclSpec DS; ParseSpecifierQualifierList(DS); @@ -37,7 +37,10 @@ Parser::TypeTy *Parser::ParseTypeName() { Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); ParseDeclarator(DeclaratorInfo); - return Actions.ActOnTypeName(CurScope, DeclaratorInfo).get(); + if (DeclaratorInfo.getInvalidType()) + return true; + + return Actions.ActOnTypeName(CurScope, DeclaratorInfo); } /// ParseAttributes - Parse a non-empty attributes list. @@ -2383,8 +2386,10 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { } OwningExprResult Result(ParseCastExpression(true/*isUnaryExpression*/)); - if (Result.isInvalid()) + if (Result.isInvalid()) { + DS.SetTypeSpecError(); return; + } const char *PrevSpec = 0; // Check for duplicate type specifiers. @@ -2400,24 +2405,32 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { SourceLocation LParenLoc = ConsumeParen(), RParenLoc; if (isTypeIdInParens()) { - TypeTy *Ty = ParseTypeName(); + Action::TypeResult Ty = ParseTypeName(); - assert(Ty && "Parser::ParseTypeofSpecifier(): missing type"); + assert((Ty.isInvalid() || Ty.get()) && + "Parser::ParseTypeofSpecifier(): missing type"); if (Tok.isNot(tok::r_paren)) { MatchRHSPunctuation(tok::r_paren, LParenLoc); return; } RParenLoc = ConsumeParen(); - const char *PrevSpec = 0; - // Check for duplicate type specifiers (e.g. "int typeof(int)"). - if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty)) - Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; + + if (Ty.isInvalid()) + DS.SetTypeSpecError(); + else { + const char *PrevSpec = 0; + // Check for duplicate type specifiers (e.g. "int typeof(int)"). + if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, + Ty.get())) + Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; + } } else { // we have an expression. OwningExprResult Result(ParseExpression()); if (Result.isInvalid() || Tok.isNot(tok::r_paren)) { MatchRHSPunctuation(tok::r_paren, LParenLoc); + DS.SetTypeSpecError(); return; } RParenLoc = ConsumeParen(); |