diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-03-05 14:45:16 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-03-05 14:45:16 +0000 |
commit | 7acafd032e145dbdbbed9274ca57ec2c86b912bc (patch) | |
tree | b73974f2c6ede1cebe101a1f5dd33ac75dacbcaa /lib/Parse/ParseDecl.cpp | |
parent | b6ab6c1ca733fda2302a1c5066bdfc6218c89e41 (diff) |
Parser support for noexcept specifications.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127086 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 50ba7054fe..5cda4e6d5c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -3127,6 +3127,10 @@ void Parser::ParseParenDeclarator(Declarator &D) { /// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]", /// C++0x "ref-qualifier[opt]" and "exception-specification[opt]". /// +/// [C++0x] exception-specification: +/// dynamic-exception-specification +/// noexcept-specification +/// void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, ParsedAttributes &attrs, bool RequiresArg) { @@ -3147,11 +3151,11 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, DeclSpec DS; SourceLocation RefQualifierLoc; bool RefQualifierIsLValueRef = true; - bool hasExceptionSpec = false; - SourceLocation ThrowLoc; - bool hasAnyExceptionSpec = false; - llvm::SmallVector<ParsedType, 2> Exceptions; - llvm::SmallVector<SourceRange, 2> ExceptionRanges; + ExceptionSpecificationType ESpecType = EST_None; + SourceRange ESpecRange; + llvm::SmallVector<ParsedType, 2> DynamicExceptions; + llvm::SmallVector<SourceRange, 2> DynamicExceptionRanges; + ExprResult NoexceptExpr; if (getLang().CPlusPlus) { MaybeParseCXX0XAttributes(attrs); @@ -3168,16 +3172,14 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, RefQualifierLoc = ConsumeToken(); EndLoc = RefQualifierLoc; } - + // Parse exception-specification[opt]. - if (Tok.is(tok::kw_throw)) { - hasExceptionSpec = true; - ThrowLoc = Tok.getLocation(); - ParseExceptionSpecification(EndLoc, Exceptions, ExceptionRanges, - hasAnyExceptionSpec); - assert(Exceptions.size() == ExceptionRanges.size() && - "Produced different number of exception types and ranges."); - } + ESpecType = MaybeParseExceptionSpecification(ESpecRange, + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr); + if (ESpecType != EST_None) + EndLoc = ESpecRange.getEnd(); // Parse trailing-return-type. if (getLang().CPlusPlus0x && Tok.is(tok::arrow)) { @@ -3195,11 +3197,13 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, DS.getTypeQualifiers(), RefQualifierIsLValueRef, RefQualifierLoc, - hasExceptionSpec, ThrowLoc, - hasAnyExceptionSpec, - Exceptions.data(), - ExceptionRanges.data(), - Exceptions.size(), + ESpecType == EST_Dynamic || + ESpecType == EST_DynamicAny, + ESpecRange.getBegin(), + ESpecType == EST_DynamicAny, + DynamicExceptions.data(), + DynamicExceptionRanges.data(), + DynamicExceptions.size(), LParenLoc, RParenLoc, D, TrailingReturnType), EndLoc); @@ -3396,11 +3400,11 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, DeclSpec DS; SourceLocation RefQualifierLoc; bool RefQualifierIsLValueRef = true; - bool hasExceptionSpec = false; - SourceLocation ThrowLoc; - bool hasAnyExceptionSpec = false; - llvm::SmallVector<ParsedType, 2> Exceptions; - llvm::SmallVector<SourceRange, 2> ExceptionRanges; + ExceptionSpecificationType ESpecType = EST_None; + SourceRange ESpecRange; + llvm::SmallVector<ParsedType, 2> DynamicExceptions; + llvm::SmallVector<SourceRange, 2> DynamicExceptionRanges; + ExprResult NoexceptExpr; if (getLang().CPlusPlus) { MaybeParseCXX0XAttributes(attrs); @@ -3420,15 +3424,17 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, EndLoc = RefQualifierLoc; } + // FIXME: We should leave the prototype scope before parsing the exception + // specification, and then reenter it when parsing the trailing return type. + // FIXMEFIXME: Why? That wouldn't be right for the noexcept clause. + // Parse exception-specification[opt]. - if (Tok.is(tok::kw_throw)) { - hasExceptionSpec = true; - ThrowLoc = Tok.getLocation(); - ParseExceptionSpecification(EndLoc, Exceptions, ExceptionRanges, - hasAnyExceptionSpec); - assert(Exceptions.size() == ExceptionRanges.size() && - "Produced different number of exception types and ranges."); - } + ESpecType = MaybeParseExceptionSpecification(ESpecRange, + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr); + if (ESpecType != EST_None) + EndLoc = ESpecRange.getEnd(); // Parse trailing-return-type. if (getLang().CPlusPlus0x && Tok.is(tok::arrow)) { @@ -3436,9 +3442,6 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, } } - // FIXME: We should leave the prototype scope before parsing the exception - // specification, and then reenter it when parsing the trailing return type. - // Leave prototype scope. PrototypeScope.Exit(); @@ -3450,11 +3453,13 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, DS.getTypeQualifiers(), RefQualifierIsLValueRef, RefQualifierLoc, - hasExceptionSpec, ThrowLoc, - hasAnyExceptionSpec, - Exceptions.data(), - ExceptionRanges.data(), - Exceptions.size(), + ESpecType == EST_Dynamic || + ESpecType == EST_DynamicAny, + ESpecRange.getBegin(), + ESpecType == EST_DynamicAny, + DynamicExceptions.data(), + DynamicExceptionRanges.data(), + DynamicExceptions.size(), LParenLoc, RParenLoc, D, TrailingReturnType), EndLoc); |