diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-04-16 18:27:27 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-04-16 18:27:27 +0000 |
commit | 433e05306fa0217598535211103641221b9021ce (patch) | |
tree | 3529a26e1b3685172e00a8aabb16dc5d4543d998 /clang/lib/Parse/ParseDecl.cpp | |
parent | 505a7c818d9686f8044ce83c6de9e8c234af9f98 (diff) | |
download | bcm5719-llvm-433e05306fa0217598535211103641221b9021ce.tar.gz bcm5719-llvm-433e05306fa0217598535211103641221b9021ce.zip |
Implement the last part of C++ [class.mem]p2, delaying the parsing of
exception specifications on member functions until after the closing
'}' for the containing class. This allows, for example, a member
function to throw an instance of its own class. Fixes PR12564 and a
fairly embarassing oversight in our C++98/03 support.
llvm-svn: 154844
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 16c90e9b719..932ffb440fd 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4197,6 +4197,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, SmallVector<ParsedType, 2> DynamicExceptions; SmallVector<SourceRange, 2> DynamicExceptionRanges; ExprResult NoexceptExpr; + CachedTokens *ExceptionSpecTokens = 0; ParsedAttributes FnAttrs(AttrFactory); ParsedType TrailingReturnType; @@ -4265,10 +4266,16 @@ void Parser::ParseFunctionDeclarator(Declarator &D, IsCXX11MemberFunction); // Parse exception-specification[opt]. - ESpecType = MaybeParseExceptionSpecification(ESpecRange, - DynamicExceptions, - DynamicExceptionRanges, - NoexceptExpr); + bool Delayed = (D.getContext() == Declarator::MemberContext && + D.getDeclSpec().getStorageClassSpec() + != DeclSpec::SCS_typedef && + !D.getDeclSpec().isFriendSpecified()); + ESpecType = tryParseExceptionSpecification(Delayed, + ESpecRange, + DynamicExceptions, + DynamicExceptionRanges, + NoexceptExpr, + ExceptionSpecTokens); if (ESpecType != EST_None) EndLoc = ESpecRange.getEnd(); @@ -4303,6 +4310,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, + ExceptionSpecTokens, Tracker.getOpenLocation(), EndLoc, D, TrailingReturnType), @@ -4504,7 +4512,6 @@ void Parser::ParseParameterDeclarationClause( // If we're inside a class definition, cache the tokens // corresponding to the default argument. We'll actually parse // them when we see the end of the class definition. - // FIXME: Templates will require something similar. // FIXME: Can we use a smart pointer for Toks? DefArgToks = new CachedTokens; |