aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-18 17:45:20 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-18 17:45:20 +0000
commit809070a886684cb5b92eb0e00a6581ab1fa6b17a (patch)
treec3e6242279c488480f00bd966c7c46fcd7371eb3 /lib/Parse/ParseDecl.cpp
parente53f8206ebb36a17e95e64270704e2608d1796f4 (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.cpp31
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();