diff options
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index f84b4dae8d5..518197e17b9 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5282,8 +5282,24 @@ void Parser::ParseFunctionDeclarator(Declarator &D, // Parse exception-specification[opt]. bool Delayed = D.isFirstDeclarationOfMember() && - D.isFunctionDeclaratorAFunctionDeclaration() && - !Actions.isLibstdcxxEagerExceptionSpecHack(D); + D.isFunctionDeclaratorAFunctionDeclaration(); + if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) && + GetLookAheadToken(0).is(tok::kw_noexcept) && + GetLookAheadToken(1).is(tok::l_paren) && + GetLookAheadToken(2).is(tok::kw_noexcept) && + GetLookAheadToken(3).is(tok::l_paren) && + GetLookAheadToken(4).is(tok::identifier) && + GetLookAheadToken(4).getIdentifierInfo()->isStr("swap")) { + // HACK: We've got an exception-specification + // noexcept(noexcept(swap(...))) + // or + // noexcept(noexcept(swap(...)) && noexcept(swap(...))) + // on a 'swap' member function. This is a libstdc++ bug; the lookup + // for 'swap' will only find the function we're currently declaring, + // whereas it expects to find a non-member swap through ADL. Turn off + // delayed parsing to give it a chance to find what it expects. + Delayed = false; + } ESpecType = tryParseExceptionSpecification(Delayed, ESpecRange, DynamicExceptions, |