<div dir="ltr">reverted by r313856</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 20, 2017 at 6:30 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">Thanks, I'll fix this tomorrow; if that's not soon enough, please go ahead and revert (or fix by adding a dummy enumerator in lib/AST/Linkage.h).</div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On 20 Sep 2017 17:39, "Vitaly Buka via cfe-commits" <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><pre style="font-family:"Courier New",courier,monotype,monospace;color:rgb(0,0,0);font-size:medium"><span class="m_-4564143017372359137m_3145013057879535093gmail-stdout"><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/8038/steps/check-clang%20ubsan/logs/stdio" target="_blank">http://lab.llvm.org:8011/build<wbr>ers/sanitizer-x86_64-linux-<wbr>fast/builds/8038/steps/check-<wbr>clang%20ubsan/logs/stdio</a></span></pre><pre style="font-family:"Courier New",courier,monotype,monospace;color:rgb(0,0,0);font-size:medium"><span class="m_-4564143017372359137m_3145013057879535093gmail-stdout">
--
/mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:1333:42: runtime error: load of value 15, which is not a valid value for type 'clang::LVComputationKind'
    #0 0x7084fd9 in clang::LinkageComputer::comput<wbr>eLVForDecl(clang::NamedDecl const*, clang::LVComputationKind) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:1333:42
    #1 0x7085874 in clang::LinkageComputer::getLVF<wbr>orClosure(clang::DeclContext const*, clang::Decl*, clang::LVComputationKind) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:1135:14
    #2 0x708224e in clang::LinkageComputer::getLVF<wbr>orDecl(clang::NamedDecl const*, clang::LVComputationKind) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:1377:20
    #3 0x7085242 in clang::NamedDecl::getLinkageIn<wbr>ternal() const /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:1036:28
    #4 0x731c021 in computeCachedProperties(clang:<wbr>:Type const*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Type.cpp:3379:22
    #5 0x7311b2d in clang::TypePropertyCache<(anon<wbr>ymous namespace)::Private>::ensure(c<wbr>lang::Type const*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Type.cpp:3330:31
    #6 0x7311bb2 in clang::TypePropertyCache<(anon<wbr>ymous namespace)::Private>::ensure(c<wbr>lang::Type const*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Type.cpp:3322:7
    #7 0x7311a8f in clang::Type::getLinkage() const /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Type.cpp:3438:3
    #8 0x7081a61 in clang::LinkageComputer::getLVF<wbr>orType(clang::Type const&, clang::LVComputationKind) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:194:26
    #9 0x70831d3 in clang::LinkageComputer::getLVF<wbr>orNamespaceScopeDecl(clang::<wbr>NamedDecl const*, clang::LVComputationKind) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:724:28
    #10 0x708224e in clang::LinkageComputer::getLVF<wbr>orDecl(clang::NamedDecl const*, clang::LVComputationKind) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:1377:20
    #11 0x7085242 in clang::NamedDecl::getLinkageIn<wbr>ternal() const /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/AST/<wbr>Decl.cpp:1036:28
    #12 0x38d3ddd in clang::NamedDecl::isExternally<wbr>Visible() const /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/include/<wbr>clang/AST/Decl.h:339:39
    #13 0x5a69da3 in clang::Sema::CheckCompleteVari<wbr>ableDeclaration(clang::<wbr>VarDecl*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Sema/<wbr>SemaDecl.cpp:11042:12
    #14 0x5a693c9 in clang::Sema::AddInitializerToD<wbr>ecl(clang::Decl*, clang::Expr*, bool) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Sema/<wbr>SemaDecl.cpp:10645:3
    #15 0x555b6d1 in clang::Parser::ParseDeclaratio<wbr>nAfterDeclaratorAndAttributes(<wbr>clang::Declarator&, clang::Parser::ParsedTemplateI<wbr>nfo const&, clang::Parser::ForRangeInit*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Parse/<wbr>ParseDecl.cpp:2276:17
    #16 0x5559ce1 in clang::Parser::ParseDeclGroup(<wbr>clang::ParsingDeclSpec&, unsigned int, clang::SourceLocation*, clang::Parser::ForRangeInit*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Parse/<wbr>ParseDecl.cpp:2013:21
    #17 0x553611a in clang::Parser::ParseDeclOrFunc<wbr>tionDefInternal(clang::Parser:<wbr>:ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Parse/<wbr>Parser.cpp:979:10
    #18 0x55359a2 in clang::Parser::ParseDeclaratio<wbr>nOrFunctionDefinition(clang::<wbr>Parser::ParsedAttributesWithRa<wbr>nge&, clang::ParsingDeclSpec*, clang::AccessSpecifier) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Parse/<wbr>Parser.cpp:995:12
    #19 0x5534fbf in clang::Parser::ParseExternalDe<wbr>claration(clang::Parser::Parse<wbr>dAttributesWithRange&, clang::ParsingDeclSpec*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Parse/<wbr>Parser.cpp:845:12
    #20 0x553431c in clang::Parser::ParseTopLevelDe<wbr>cl(clang::OpaquePtr<clang::<wbr>DeclGroupRef>&) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Parse/<wbr>Parser.cpp:613:12
    #21 0x552f0e0 in clang::ParseAST(clang::Sema&, bool, bool) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Parse/<wbr>ParseAST.cpp:147:18
    #22 0x4045c32 in clang::FrontendAction::Execute<wbr>() /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Frontend<wbr>/FrontendAction.cpp:897:8
    #23 0x3fd2d44 in clang::CompilerInstance::Execu<wbr>teAction(clang::FrontendAction<wbr>&) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Frontend<wbr>/CompilerInstance.cpp:990:11
    #24 0x41db8cc in clang::ExecuteCompilerInvocati<wbr>on(clang::CompilerInstance*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/lib/Frontend<wbr>Tool/ExecuteCompilerInvocation<wbr>.cpp:252:25
    #25 0xec2ebe in cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/tools/driver<wbr>/cc1_main.cpp:221:13
    #26 0xeb5153 in ExecuteCC1Tool(llvm::ArrayRef<<wbr>char const*>, llvm::StringRef) /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/tools/driver<wbr>/driver.cpp:309:12
    #27 0xeb447c in main /mnt/b/sanitizer-buildbot3/san<wbr>itizer-x86_64-linux-fast/build<wbr>/llvm/tools/clang/tools/driver<wbr>/driver.cpp:388:12
    #28 0x7fef65b7182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so<wbr>.6+0x2082f)
    #29 0xe8ea68 in _start (/mnt/b/sanitizer-buildbot3/sa<wbr>nitizer-x86_64-linux-fast/buil<wbr>d/llvm_build_ubsan/bin/clang-<wbr>6.0+0xe8ea68)</span></pre></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 20, 2017 at 3:17 PM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Wed Sep 20 15:17:55 2017<br>
New Revision: 313827<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=313827&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=313827&view=rev</a><br>
Log:<br>
Give external linkage and mangling to lambdas inside inline variables and variable templates.<br>
<br>
This implements the proposed approach in <a href="https://github.com/itanium-cxx-abi/cxx-abi/issues/33" rel="noreferrer" target="_blank">https://github.com/itanium-cxx<wbr>-abi/cxx-abi/issues/33</a><br>
<br>
Modified:<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/AST/ItaniumMangl<wbr>e.cpp<br>
    cfe/trunk/lib/AST/Linkage.h<br>
    cfe/trunk/lib/Parse/ParseDecl.<wbr>cpp<br>
    cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp<br>
    cfe/trunk/lib/Sema/SemaLambda.<wbr>cpp<br>
    cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp<br>
    cfe/trunk/test/CodeGenCXX/mang<wbr>le-lambdas.cpp<br>
    cfe/trunk/test/SemaCXX/vartemp<wbr>late-lambda.cpp<br>
    cfe/trunk/test/SemaTemplate/in<wbr>stantiate-static-var.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/Decl.c<wbr>pp?rev=313827&r1=313826&r2=313<wbr>827&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Wed Sep 20 15:17:55 2017<br>
@@ -676,10 +676,10 @@ LinkageComputer::getLVForNames<wbr>paceScopeD<br>
     if (!LV.isVisibilityExplicit()) {<br>
       // Use global type/value visibility as appropriate.<br>
       Visibility globalVisibility;<br>
-      if (computation == LVForValue) {<br>
+      if ((computation & ~IgnoreTypeLinkageBit) == LVForValue) {<br>
         globalVisibility = Context.getLangOpts().getValue<wbr>VisibilityMode();<br>
       } else {<br>
-        assert(computation == LVForType);<br>
+        assert((computation & ~IgnoreTypeLinkageBit) == LVForType);<br>
         globalVisibility = Context.getLangOpts().getTypeV<wbr>isibilityMode();<br>
       }<br>
       LV.mergeVisibility(globalVisi<wbr>bility, /*explicit*/ false);<br>
@@ -719,7 +719,8 @@ LinkageComputer::getLVForNames<wbr>paceScopeD<br>
     //<br>
     // Note that we don't want to make the variable non-external<br>
     // because of this, but unique-external linkage suits us.<br>
-    if (Context.getLangOpts().CPlusPl<wbr>us && !isFirstInExternCContext(Var)) {<br>
+    if (Context.getLangOpts().CPlusPl<wbr>us && !isFirstInExternCContext(Var) &&<br>
+        !(computation & IgnoreTypeLinkageBit)) {<br>
       LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);<br>
       if (!isExternallyVisible(TypeLV.g<wbr>etLinkage()))<br>
         return LinkageInfo::uniqueExternal();<br>
@@ -759,8 +760,8 @@ LinkageComputer::getLVForNames<wbr>paceScopeD<br>
     // unique-external linkage, it's not legally usable from outside<br>
     // this translation unit.  However, we should use the C linkage<br>
     // rules instead for extern "C" declarations.<br>
-    if (Context.getLangOpts().CPlusPl<wbr>us &&<br>
-        !Function->isInExternCContext(<wbr>)) {<br>
+    if (Context.getLangOpts().CPlusPl<wbr>us && !Function->isInExternCContext(<wbr>) &&<br>
+        !(computation & IgnoreTypeLinkageBit)) {<br>
       // Only look at the type-as-written. If this function has an auto-deduced<br>
       // return type, we can't compute the linkage of that type because it could<br>
       // require looking at the linkage of this function, and we don't need this<br>
@@ -1122,8 +1123,18 @@ LinkageInfo LinkageComputer::getLVForClo<br>
   // calculation determines the lambda has external linkage, it should be<br>
   // downgraded to VisibleNoLinkage.<br>
   if (ContextDecl) {<br>
+    auto *VD = dyn_cast<VarDecl>(ContextDecl)<wbr>;<br>
     if (isa<ParmVarDecl>(ContextDecl)<wbr>)<br>
       DC = ContextDecl->getDeclContext()-<wbr>>getRedeclContext();<br>
+    else if (VD && VD->getType()->getContainedDed<wbr>ucedType())<br>
+      // If the declaration has a deduced type, we need to skip querying the<br>
+      // linkage and visibility of that type, because it might involve this<br>
+      // closure type. The only effect of this is that we might give a lambda<br>
+      // VisibleNoLinkage rather than NoLinkage when we don't strictly need to,<br>
+      // which is benign.<br>
+      return computeLVForDecl(<br>
+          cast<NamedDecl>(ContextDecl),<br>
+          LVComputationKind(computation | IgnoreTypeLinkageBit));<br>
     else<br>
       return getLVForDecl(cast<NamedDecl>(C<wbr>ontextDecl), computation);<br>
   }<br>
<br>
Modified: cfe/trunk/lib/AST/ItaniumMangl<wbr>e.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/Itaniu<wbr>mMangle.cpp?rev=313827&r1=3138<wbr>26&r2=313827&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/ItaniumMangl<wbr>e.cpp (original)<br>
+++ cfe/trunk/lib/AST/ItaniumMangl<wbr>e.cpp Wed Sep 20 15:17:55 2017<br>
@@ -1691,10 +1691,16 @@ void CXXNameMangler::mangleLambda(c<wbr>onst<br>
   // to emit that last part of the prefix here.<br>
   if (Decl *Context = Lambda->getLambdaContextDecl()<wbr>) {<br>
     if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&<br>
-        Context->getDeclContext()->isR<wbr>ecord()) {<br>
+        !isa<ParmVarDecl>(Context)) {<br>
+      // FIXME: 'inline auto [a, b] = []{ return ... };' does not get a<br>
+      // reasonable mangling here.<br>
       if (const IdentifierInfo *Name<br>
             = cast<NamedDecl>(Context)->getI<wbr>dentifier()) {<br>
         mangleSourceName(Name);<br>
+        const TemplateArgumentList *TemplateArgs = nullptr;<br>
+        if (const TemplateDecl *TD =<br>
+                isTemplate(cast<NamedDecl>(Con<wbr>text), TemplateArgs))<br>
+          mangleTemplateArgs(*TemplateAr<wbr>gs);<br>
         Out << 'M';<br>
       }<br>
     }<br>
<br>
Modified: cfe/trunk/lib/AST/Linkage.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Linkage.h?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/Linkag<wbr>e.h?rev=313827&r1=313826&r2=31<wbr>3827&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/Linkage.h (original)<br>
+++ cfe/trunk/lib/AST/Linkage.h Wed Sep 20 15:17:55 2017<br>
@@ -24,7 +24,8 @@<br>
 namespace clang {<br>
 enum : unsigned {<br>
   IgnoreExplicitVisibilityBit = 2,<br>
-  IgnoreAllVisibilityBit = 4<br>
+  IgnoreAllVisibilityBit = 4,<br>
+  IgnoreTypeLinkageBit = 8,<br>
 };<br>
<br>
 /// Kinds of LV computation.  The linkage side of the computation is<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDecl.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Parse/Pars<wbr>eDecl.cpp?rev=313827&r1=313826<wbr>&r2=313827&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Parse/ParseDecl.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDecl.<wbr>cpp Wed Sep 20 15:17:55 2017<br>
@@ -2131,6 +2131,37 @@ Decl *Parser::ParseDeclarationAfter<wbr>Decla<br>
<br>
 Decl *Parser::ParseDeclarationAfter<wbr>DeclaratorAndAttributes(<br>
     Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {<br>
+  // RAII type used to track whether we're inside an initializer.<br>
+  struct InitializerScopeRAII {<br>
+    Parser &P;<br>
+    Declarator &D;<br>
+    Decl *ThisDecl;<br>
+<br>
+    InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)<br>
+        : P(P), D(D), ThisDecl(ThisDecl) {<br>
+      if (ThisDecl && P.getLangOpts().CPlusPlus) {<br>
+        Scope *S = nullptr;<br>
+        if (D.getCXXScopeSpec().isSet()) {<br>
+          P.EnterScope(0);<br>
+          S = P.getCurScope();<br>
+        }<br>
+        P.Actions.ActOnCXXEnterDeclIni<wbr>tializer(S, ThisDecl);<br>
+      }<br>
+    }<br>
+    ~InitializerScopeRAII() { pop(); }<br>
+    void pop() {<br>
+      if (ThisDecl && P.getLangOpts().CPlusPlus) {<br>
+        Scope *S = nullptr;<br>
+        if (D.getCXXScopeSpec().isSet())<br>
+          S = P.getCurScope();<br>
+        P.Actions.ActOnCXXExitDeclInit<wbr>ializer(S, ThisDecl);<br>
+        if (S)<br>
+          P.ExitScope();<br>
+      }<br>
+      ThisDecl = nullptr;<br>
+    }<br>
+  };<br>
+<br>
   // Inform the current actions module that we just parsed this declarator.<br>
   Decl *ThisDecl = nullptr;<br>
   switch (TemplateInfo.Kind) {<br>
@@ -2208,10 +2239,7 @@ Decl *Parser::ParseDeclarationAfter<wbr>Decla<br>
       else<br>
         Diag(ConsumeToken(), diag::err_default_special_memb<wbr>ers);<br>
     } else {<br>
-      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {<br>
-        EnterScope(0);<br>
-        Actions.ActOnCXXEnterDeclIniti<wbr>alizer(getCurScope(), ThisDecl);<br>
-      }<br>
+      InitializerScopeRAII InitScope(*this, D, ThisDecl);<br>
<br>
       if (Tok.is(tok::code_completion)) {<br>
         Actions.CodeCompleteInitializ<wbr>er(getCurScope(), ThisDecl);<br>
@@ -2234,10 +2262,7 @@ Decl *Parser::ParseDeclarationAfter<wbr>Decla<br>
         FRI->RangeExpr = Init;<br>
       }<br>
<br>
-      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {<br>
-        Actions.ActOnCXXExitDeclInitia<wbr>lizer(getCurScope(), ThisDecl);<br>
-        ExitScope();<br>
-      }<br>
+      InitScope.pop();<br>
<br>
       if (Init.isInvalid()) {<br>
         SmallVector<tok::TokenKind, 2> StopTokens;<br>
@@ -2259,10 +2284,7 @@ Decl *Parser::ParseDeclarationAfter<wbr>Decla<br>
     ExprVector Exprs;<br>
     CommaLocsTy CommaLocs;<br>
<br>
-    if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {<br>
-      EnterScope(0);<br>
-      Actions.ActOnCXXEnterDeclIniti<wbr>alizer(getCurScope(), ThisDecl);<br>
-    }<br>
+    InitializerScopeRAII InitScope(*this, D, ThisDecl);<br>
<br>
     llvm::function_ref<void()> ExprListCompleter;<br>
     auto ThisVarDecl = dyn_cast_or_null<VarDecl>(This<wbr>Decl);<br>
@@ -2283,11 +2305,6 @@ Decl *Parser::ParseDeclarationAfter<wbr>Decla<br>
     if (ParseExpressionList(Exprs, CommaLocs, ExprListCompleter)) {<br>
       Actions.ActOnInitializerError<wbr>(ThisDecl);<br>
       SkipUntil(tok::r_paren, StopAtSemi);<br>
-<br>
-      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {<br>
-        Actions.ActOnCXXExitDeclInitia<wbr>lizer(getCurScope(), ThisDecl);<br>
-        ExitScope();<br>
-      }<br>
     } else {<br>
       // Match the ')'.<br>
       T.consumeClose();<br>
@@ -2295,10 +2312,7 @@ Decl *Parser::ParseDeclarationAfter<wbr>Decla<br>
       assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&<br>
              "Unexpected number of commas!");<br>
<br>
-      if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {<br>
-        Actions.ActOnCXXExitDeclInitia<wbr>lizer(getCurScope(), ThisDecl);<br>
-        ExitScope();<br>
-      }<br>
+      InitScope.pop();<br>
<br>
       ExprResult Initializer = Actions.ActOnParenListExpr(T.g<wbr>etOpenLocation(),<br>
                                                           T.getCloseLocation(),<br>
@@ -2311,17 +2325,11 @@ Decl *Parser::ParseDeclarationAfter<wbr>Decla<br>
     // Parse C++0x braced-init-list.<br>
     Diag(Tok, diag::warn_cxx98_compat_genera<wbr>lized_initializer_lists);<br>
<br>
-    if (D.getCXXScopeSpec().isSet()) {<br>
-      EnterScope(0);<br>
-      Actions.ActOnCXXEnterDeclIniti<wbr>alizer(getCurScope(), ThisDecl);<br>
-    }<br>
+    InitializerScopeRAII InitScope(*this, D, ThisDecl);<br>
<br>
     ExprResult Init(ParseBraceInitializer());<br>
<br>
-    if (D.getCXXScopeSpec().isSet()) {<br>
-      Actions.ActOnCXXExitDeclInitia<wbr>lizer(getCurScope(), ThisDecl);<br>
-      ExitScope();<br>
-    }<br>
+    InitScope.pop();<br>
<br>
     if (Init.isInvalid()) {<br>
       Actions.ActOnInitializerError<wbr>(ThisDecl);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaD<wbr>eclCXX.cpp?rev=313827&r1=31382<wbr>6&r2=313827&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX<wbr>.cpp Wed Sep 20 15:17:55 2017<br>
@@ -14240,21 +14240,22 @@ void Sema::ActOnPureSpecifier(Decl *D, S<br>
     Diag(D->getLocation(), diag::err_illegal_initializer)<wbr>;<br>
 }<br>
<br>
-/// \brief Determine whether the given declaration is a static data member.<br>
-static bool isStaticDataMember(const Decl *D) {<br>
+/// \brief Determine whether the given declaration is a global variable or<br>
+/// static data member.<br>
+static bool isNonlocalVariable(const Decl *D) {<br>
   if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D))<br>
-    return Var->isStaticDataMember();<br>
+    return Var->hasGlobalStorage();<br>
<br>
   return false;<br>
 }<br>
<br>
-/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse<br>
-/// an initializer for the out-of-line declaration 'Dcl'.  The scope<br>
-/// is a fresh scope pushed for just this purpose.<br>
+/// Invoked when we are about to parse an initializer for the declaration<br>
+/// 'Dcl'.<br>
 ///<br>
 /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a<br>
 /// static data member of class X, names should be looked up in the scope of<br>
-/// class X.<br>
+/// class X. If the declaration had a scope specifier, a scope will have<br>
+/// been created and passed in for this purpose. Otherwise, S will be null.<br>
 void Sema::ActOnCXXEnterDeclInitial<wbr>izer(Scope *S, Decl *D) {<br>
   // If there is no declaration, there was an error parsing it.<br>
   if (!D || D->isInvalidDecl())<br>
@@ -14264,28 +14265,27 @@ void Sema::ActOnCXXEnterDeclInitial<wbr>izer(<br>
   // might not be out of line if the specifier names the current namespace:<br>
   //   extern int n;<br>
   //   int ::n = 0;<br>
-  if (D->isOutOfLine())<br>
+  if (S && D->isOutOfLine())<br>
     EnterDeclaratorContext(S, D->getDeclContext());<br>
<br>
   // If we are parsing the initializer for a static data member, push a<br>
   // new expression evaluation context that is associated with this static<br>
   // data member.<br>
-  if (isStaticDataMember(D))<br>
+  if (isNonlocalVariable(D))<br>
     PushExpressionEvaluationConte<wbr>xt(<br>
         ExpressionEvaluationContext::<wbr>PotentiallyEvaluated, D);<br>
 }<br>
<br>
-/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an<br>
-/// initializer for the out-of-line declaration 'D'.<br>
+/// Invoked after we are finished parsing an initializer for the declaration D.<br>
 void Sema::ActOnCXXExitDeclInitiali<wbr>zer(Scope *S, Decl *D) {<br>
   // If there is no declaration, there was an error parsing it.<br>
   if (!D || D->isInvalidDecl())<br>
     return;<br>
<br>
-  if (isStaticDataMember(D))<br>
+  if (isNonlocalVariable(D))<br>
     PopExpressionEvaluationContex<wbr>t();<br>
<br>
-  if (D->isOutOfLine())<br>
+  if (S && D->isOutOfLine())<br>
     ExitDeclaratorContext(S);<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaLambda.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaL<wbr>ambda.cpp?rev=313827&r1=313826<wbr>&r2=313827&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaLambda.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaLambda.<wbr>cpp Wed Sep 20 15:17:55 2017<br>
@@ -288,7 +288,9 @@ Sema::getCurrentMangleNumberCo<wbr>ntext(cons<br>
     Normal,<br>
     DefaultArgument,<br>
     DataMember,<br>
-    StaticDataMember<br>
+    StaticDataMember,<br>
+    InlineVariable,<br>
+    VariableTemplate<br>
   } Kind = Normal;<br>
<br>
   // Default arguments of member function parameters that appear in a class<br>
@@ -303,6 +305,14 @@ Sema::getCurrentMangleNumberCo<wbr>ntext(cons<br>
     } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingCont<wbr>extDecl)) {<br>
       if (Var->getDeclContext()->isReco<wbr>rd())<br>
         Kind = StaticDataMember;<br>
+      else if (Var->getMostRecentDecl()->isI<wbr>nline())<br>
+        Kind = InlineVariable;<br>
+      else if (Var->getDescribedVarTemplate(<wbr>))<br>
+        Kind = VariableTemplate;<br>
+      else if (auto *VTS = dyn_cast<VarTemplateSpecializa<wbr>tionDecl>(Var)) {<br>
+        if (!VTS->isExplicitSpecializatio<wbr>n())<br>
+          Kind = VariableTemplate;<br>
+      }<br>
     } else if (isa<FieldDecl>(ManglingContex<wbr>tDecl)) {<br>
       Kind = DataMember;<br>
     }<br>
@@ -343,6 +353,10 @@ Sema::getCurrentMangleNumberCo<wbr>ntext(cons<br>
     //  -- the in-class initializers of class members<br>
   case DefaultArgument:<br>
     //  -- default arguments appearing in class definitions<br>
+  case InlineVariable:<br>
+    //  -- the initializers of inline variables<br>
+  case VariableTemplate:<br>
+    //  -- the initializers of templated variables<br>
     return &ExprEvalContexts.back().getMa<wbr>ngleNumberingContext(Context);<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaT<wbr>emplateInstantiateDecl.cpp?rev<wbr>=313827&r1=313826&r2=313827&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplat<wbr>eInstantiateDecl.cpp Wed Sep 20 15:17:55 2017<br>
@@ -4140,12 +4140,8 @@ void Sema::InstantiateVariableIniti<wbr>alize<br>
     Var->setImplicitlyInline();<br>
<br>
   if (OldVar->getInit()) {<br>
-    if (Var->isStaticDataMember() && !OldVar->isOutOfLine())<br>
-      PushExpressionEvaluationContex<wbr>t(<br>
-          Sema::ExpressionEvaluationCont<wbr>ext::ConstantEvaluated, OldVar);<br>
-    else<br>
-      PushExpressionEvaluationContex<wbr>t(<br>
-          Sema::ExpressionEvaluationCont<wbr>ext::PotentiallyEvaluated, OldVar);<br>
+    EnterExpressionEvaluationConte<wbr>xt Evaluated(<br>
+        *this, Sema::ExpressionEvaluationCont<wbr>ext::PotentiallyEvaluated, Var);<br>
<br>
     // Instantiate the initializer.<br>
     ExprResult Init;<br>
@@ -4173,8 +4169,6 @@ void Sema::InstantiateVariableIniti<wbr>alize<br>
       // because of a bogus initializer.<br>
       Var->setInvalidDecl();<br>
     }<br>
-<br>
-    PopExpressionEvaluationContext<wbr>();<br>
   } else {<br>
     if (Var->isStaticDataMember()) {<br>
       if (!Var->isOutOfLine())<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/mang<wbr>le-lambdas.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/CodeGenCX<wbr>X/mangle-lambdas.cpp?rev=31382<wbr>7&r1=313826&r2=313827&view=<wbr>diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CodeGenCXX/mang<wbr>le-lambdas.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/mang<wbr>le-lambdas.cpp Wed Sep 20 15:17:55 2017<br>
@@ -26,6 +26,24 @@ void call_inline_func() {<br>
   inline_func(17);<br>
 }<br>
<br>
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK10inline_varMUlvE_clEv(<br>
+// CHECK: @_ZZNK10inline_varMUlvE_clEvE1<wbr>n<br>
+inline auto inline_var = [] {<br>
+  static int n = 5;<br>
+  return &n;<br>
+};<br>
+<br>
+int *use_inline_var = inline_var();<br>
+<br>
+// CHECK-LABEL: define linkonce_odr i32* @_ZNK12var_templateIiEMUlvE_cl<wbr>Ev(<br>
+// CHECK: @_ZZNK12var_templateIiEMUlvE_c<wbr>lEvE1n<br>
+template<typename T> auto var_template = [] {<br>
+  static int n = 9;<br>
+  return &n;<br>
+};<br>
+<br>
+int *use_var_template = var_template<int>();<br>
+<br>
 struct S {<br>
   void f(int = []{return 1;}()<br>
              + []{return 2;}(),<br>
@@ -118,7 +136,7 @@ T StaticMembers<T>::z = accept_lambda([]<br>
 template<typename T><br>
 int (*StaticMembers<T>::f)() = []{return 5;};<br>
<br>
-// CHECK-LABEL: define internal void @__cxx_global_var_init()<br>
+// CHECK-LABEL: define internal void @__cxx_global_var_init<br>
 // CHECK: call i32 @_ZNK13StaticMembersIfE1xMUlvE<wbr>_clEv<br>
 // CHECK-NEXT: call i32 @_ZNK13StaticMembersIfE1xMUlvE<wbr>0_clEv<br>
 // CHECK-NEXT: add nsw<br>
@@ -128,23 +146,23 @@ int (*StaticMembers<T>::f)() = []{return<br>
 // CHECK: ret i32 2<br>
 template float StaticMembers<float>::x;<br>
<br>
-// CHECK-LABEL: define internal void @__cxx_global_var_init.1()<br>
+// CHECK-LABEL: define internal void @__cxx_global_var_init<br>
 // CHECK: call i32 @_ZNK13StaticMembersIfE1yMUlvE<wbr>_clEv<br>
 // CHECK-LABEL: define linkonce_odr i32 @_ZNK13StaticMembersIfE1yMUlvE<wbr>_clEv<br>
 // CHECK: ret i32 3<br>
 template float StaticMembers<float>::y;<br>
<br>
-// CHECK-LABEL: define internal void @__cxx_global_var_init.2()<br>
+// CHECK-LABEL: define internal void @__cxx_global_var_init<br>
 // CHECK: call i32 @_Z13accept_lambdaIN13StaticMe<wbr>mbersIfE1zMUlvE_EEiT_<br>
 // CHECK: declare i32 @_Z13accept_lambdaIN13StaticMe<wbr>mbersIfE1zMUlvE_EEiT_()<br>
 template float StaticMembers<float>::z;<br>
<br>
-// CHECK-LABEL: define internal void @__cxx_global_var_init.3()<br>
+// CHECK-LABEL: define internal void @__cxx_global_var_init<br>
 // CHECK: call {{.*}} @_ZNK13StaticMembersIfE1fMUlvE<wbr>_cvPFivEEv<br>
 // CHECK-LABEL: define linkonce_odr i32 ()* @_ZNK13StaticMembersIfE1fMUlvE<wbr>_cvPFivEEv<br>
 template int (*StaticMembers<float>::f)();<br>
<br>
-// CHECK-LABEL: define internal void @__cxx_global_var_init.4<br>
+// CHECK-LABEL: define internal void @__cxx_global_var_init<br>
 // CHECK: call i32 @"_ZNK13StaticMembersIdE3$_2cl<wbr>Ev"<br>
 // CHECK-LABEL: define internal i32 @"_ZNK13StaticMembersIdE3$_2cl<wbr>Ev"<br>
 // CHECK: ret i32 42<br>
<br>
Modified: cfe/trunk/test/SemaCXX/vartemp<wbr>late-lambda.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaCXX/v<wbr>artemplate-lambda.cpp?rev=3138<wbr>27&r1=313826&r2=313827&view=<wbr>diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/vartemp<wbr>late-lambda.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/vartemp<wbr>late-lambda.cpp Wed Sep 20 15:17:55 2017<br>
@@ -8,7 +8,7 @@ template<typename T> auto v1 = [](int a<br>
<br>
 struct S {<br>
   template<class T><br>
-  static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-error{{a lambda expression may not appear inside of a constant expression}} expected-note{{cannot be used in a constant expression}}<br>
+  static constexpr T t = [](int f = T(7)){return f;}(); // expected-error{{constexpr variable 't<int>' must be initialized by a constant expression}} expected-note{{cannot be used in a constant expression}}<br>
 };<br>
<br>
 template <typename X><br>
<br>
Modified: cfe/trunk/test/SemaTemplate/in<wbr>stantiate-static-var.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp?rev=313827&r1=313826&r2=313827&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaTempl<wbr>ate/instantiate-static-var.cpp<wbr>?rev=313827&r1=313826&r2=31382<wbr>7&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaTemplate/in<wbr>stantiate-static-var.cpp (original)<br>
+++ cfe/trunk/test/SemaTemplate/in<wbr>stantiate-static-var.cpp Wed Sep 20 15:17:55 2017<br>
@@ -5,7 +5,7 @@<br>
 template<typename T, T Divisor><br>
 class X {<br>
 public:<br>
-  static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}}<br>
+  static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}} expected-warning {{division by zero}}<br>
 };<br>
<br>
 int array1[X<int, 2>::value == 5? 1 : -1];<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>
<br>______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div></div>
</div></div></blockquote></div><br></div>