Simple parsing of exception specifications, with no semantic analysis yet

llvm-svn: 60005
This commit is contained in:
Douglas Gregor 2008-11-25 03:22:00 +00:00
parent f39268ae8c
commit 2afd0be069
4 changed files with 58 additions and 3 deletions

View File

@ -492,6 +492,7 @@ private:
//===--------------------------------------------------------------------===//
// C++ 15: C++ Throw Expression
ExprResult ParseThrowExpression();
bool ParseExceptionSpecification();
//===--------------------------------------------------------------------===//
// C++ 2.13.5: C++ Boolean Literals

View File

@ -1653,7 +1653,10 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
DeclSpec DS;
if (getLang().CPlusPlus) {
ParseTypeQualifierListOpt(DS);
// FIXME: Parse exception-specification[opt].
// Parse exception-specification[opt].
if (Tok.is(tok::kw_throw))
ParseExceptionSpecification();
}
// Remember that we parsed a function type, and remember the attributes.
@ -1783,11 +1786,14 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
// If we have the closing ')', eat it.
MatchRHSPunctuation(tok::r_paren, LParenLoc);
// cv-qualifier-seq[opt].
DeclSpec DS;
if (getLang().CPlusPlus) {
// Parse cv-qualifier-seq[opt].
ParseTypeQualifierListOpt(DS);
// FIXME: Parse exception-specification[opt].
// Parse exception-specification[opt].
if (Tok.is(tok::kw_throw))
ParseExceptionSpecification();
}
// Remember that we parsed a function type, and remember the attributes.

View File

@ -760,3 +760,36 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) {
LParenLoc, &ArgExprs[0], ArgExprs.size(),
&CommaLocs[0], RParenLoc);
}
/// ParseExceptionSpecification - Parse a C++ exception-specification
/// (C++ [except.spec]).
///
/// exception-specification:
/// 'throw' '(' type-id-list [opt] ')'
///
/// type-id-list:
/// type-id
/// type-id-list ',' type-id
///
bool Parser::ParseExceptionSpecification() {
assert(Tok.is(tok::kw_throw) && "expected throw");
SourceLocation ThrowLoc = ConsumeToken();
if (!Tok.is(tok::l_paren)) {
return Diag(Tok, diag::err_expected_lparen_after) << "throw";
}
SourceLocation LParenLoc = ConsumeParen();
// Parse the sequence of type-ids.
while (Tok.isNot(tok::r_paren)) {
ParseTypeName();
if (Tok.is(tok::comma))
ConsumeToken();
else
break;
}
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
return false;
}

View File

@ -0,0 +1,15 @@
// RUN: clang -fsyntax-only %s
struct X { };
struct Y { };
void f() throw() { }
void g(int) throw(X) { }
void h() throw(X, Y) { }
class Class {
void foo() throw (X, Y) { }
};