diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-09-20 22:17:55 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-09-20 22:17:55 +0000 |
commit | 56afb73f73ff1813807622911408aa59e86a0417 (patch) | |
tree | e1a5279fc60cbec6348cd7ae13579c95d773314a /lib/Parse/ParseDecl.cpp | |
parent | 50547958abf4f6142a8e9eb645a8f2af8127df8a (diff) |
Give external linkage and mangling to lambdas inside inline variables and variable templates.
This implements the proposed approach in https://github.com/itanium-cxx-abi/cxx-abi/issues/33
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313827 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index ad16d2c5bb..8bca7badea 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2131,6 +2131,37 @@ Decl *Parser::ParseDeclarationAfterDeclarator( Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) { + // RAII type used to track whether we're inside an initializer. + struct InitializerScopeRAII { + Parser &P; + Declarator &D; + Decl *ThisDecl; + + InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl) + : P(P), D(D), ThisDecl(ThisDecl) { + if (ThisDecl && P.getLangOpts().CPlusPlus) { + Scope *S = nullptr; + if (D.getCXXScopeSpec().isSet()) { + P.EnterScope(0); + S = P.getCurScope(); + } + P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl); + } + } + ~InitializerScopeRAII() { pop(); } + void pop() { + if (ThisDecl && P.getLangOpts().CPlusPlus) { + Scope *S = nullptr; + if (D.getCXXScopeSpec().isSet()) + S = P.getCurScope(); + P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl); + if (S) + P.ExitScope(); + } + ThisDecl = nullptr; + } + }; + // Inform the current actions module that we just parsed this declarator. Decl *ThisDecl = nullptr; switch (TemplateInfo.Kind) { @@ -2208,10 +2239,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( else Diag(ConsumeToken(), diag::err_default_special_members); } else { - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - EnterScope(0); - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); - } + InitializerScopeRAII InitScope(*this, D, ThisDecl); if (Tok.is(tok::code_completion)) { Actions.CodeCompleteInitializer(getCurScope(), ThisDecl); @@ -2234,10 +2262,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( FRI->RangeExpr = Init; } - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } + InitScope.pop(); if (Init.isInvalid()) { SmallVector<tok::TokenKind, 2> StopTokens; @@ -2259,10 +2284,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( ExprVector Exprs; CommaLocsTy CommaLocs; - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - EnterScope(0); - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); - } + InitializerScopeRAII InitScope(*this, D, ThisDecl); llvm::function_ref<void()> ExprListCompleter; auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl); @@ -2283,11 +2305,6 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( if (ParseExpressionList(Exprs, CommaLocs, ExprListCompleter)) { Actions.ActOnInitializerError(ThisDecl); SkipUntil(tok::r_paren, StopAtSemi); - - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } } else { // Match the ')'. T.consumeClose(); @@ -2295,10 +2312,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && "Unexpected number of commas!"); - if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } + InitScope.pop(); ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(), T.getCloseLocation(), @@ -2311,17 +2325,11 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( // Parse C++0x braced-init-list. Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); - if (D.getCXXScopeSpec().isSet()) { - EnterScope(0); - Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl); - } + InitializerScopeRAII InitScope(*this, D, ThisDecl); ExprResult Init(ParseBraceInitializer()); - if (D.getCXXScopeSpec().isSet()) { - Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); - ExitScope(); - } + InitScope.pop(); if (Init.isInvalid()) { Actions.ActOnInitializerError(ThisDecl); |