Simple parsing of exception specifications, with no semantic analysis yet
llvm-svn: 60005
This commit is contained in:
parent
f39268ae8c
commit
2afd0be069
|
@ -492,6 +492,7 @@ private:
|
|||
//===--------------------------------------------------------------------===//
|
||||
// C++ 15: C++ Throw Expression
|
||||
ExprResult ParseThrowExpression();
|
||||
bool ParseExceptionSpecification();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C++ 2.13.5: C++ Boolean Literals
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) { }
|
||||
};
|
Loading…
Reference in New Issue