<div dir="ltr"><a href="http://build.chromium.org/p/chromium.fyi/builders/CrWinClang%28dbg%29/builds/0/steps/compile/logs/stdio">http://build.chromium.org/p/chromium.fyi/builders/CrWinClang%28dbg%29/builds/0/steps/compile/logs/stdio</a> has many `Assertion failed: Val && "isa<> used on a null pointer"` that used to not be there, and this change added an isa<>() call. Maybe it's related?<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 17, 2015 at 3:00 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:reid@kleckner.net" target="_blank">reid@kleckner.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Tue Mar 17 14:00:50 2015<br>
New Revision: 232519<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=232519&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=232519&view=rev</a><br>
Log:<br>
MS ABI: Delay default constructor closure checking until the outermost class scope ends<br>
<br>
Previously, we would error out on this code because the default argument<br>
wasn't parsed until the end of Outer:<br>
<br>
  struct __declspec(dllexport) Outer {<br>
    struct __declspec(dllexport) Inner {<br>
      Inner(void *p = 0);<br>
    };<br>
  };<br>
<br>
Now we do the checking on the closing brace of Outer instead of Inner.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/test/CodeGenCXX/dllexport.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=232519&r1=232518&r2=232519&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=232519&r1=232518&r2=232519&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Mar 17 14:00:50 2015<br>
@@ -5012,6 +5012,7 @@ public:<br>
                                          SourceLocation RBrac,<br>
                                          AttributeList *AttrList);<br>
   void ActOnFinishCXXMemberDecls();<br>
+  void ActOnFinishCXXMethodDefs(Decl *D);<br>
<br>
   void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);<br>
   unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=232519&r1=232518&r2=232519&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=232519&r1=232518&r2=232519&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Mar 17 14:00:50 2015<br>
@@ -3309,6 +3309,8 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure<br>
   QualType RecordTy = getContext().getRecordType(RD);<br>
   llvm::Function *ThunkFn = llvm::Function::Create(<br>
       ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.getModule());<br>
+  ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(<br>
+      FnInfo.getEffectiveCallingConvention()));<br>
   bool IsCopy = CT == Ctor_CopyingClosure;<br>
<br>
   // Start codegen.<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=232519&r1=232518&r2=232519&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=232519&r1=232518&r2=232519&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Mar 17 14:00:50 2015<br>
@@ -2915,6 +2915,10 @@ void Parser::ParseCXXMemberSpecification<br>
     ParseLexedMemberInitializers(getCurrentClass());<br>
     ParseLexedMethodDefs(getCurrentClass());<br>
     PrevTokLocation = SavedPrevTokLocation;<br>
+<br>
+    // We've finished parsing everything, including default argument<br>
+    // initializers.<br>
+    Actions.ActOnFinishCXXMethodDefs(TagDecl);<br>
   }<br>
<br>
   if (TagDecl)<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=232519&r1=232518&r2=232519&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=232519&r1=232518&r2=232519&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar 17 14:00:50 2015<br>
@@ -12067,24 +12067,6 @@ void Sema::ActOnStartCXXMemberDeclaratio<br>
          "Broken injected-class-name");<br>
 }<br>
<br>
-static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) {<br>
-  for (Decl *Member : Class->decls()) {<br>
-    auto *CD = dyn_cast<CXXConstructorDecl>(Member);<br>
-    if (!CD || !CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>())<br>
-      continue;<br>
-<br>
-    for (unsigned I = 0, E = CD->getNumParams(); I != E; ++I) {<br>
-      // Skip any default arguments that we've already instantiated.<br>
-      if (S.Context.getDefaultArgExprForConstructor(CD, I))<br>
-        continue;<br>
-<br>
-      Expr *DefaultArg = S.BuildCXXDefaultArgExpr(Class->getLocation(), CD,<br>
-                                                  CD->getParamDecl(I)).get();<br>
-      S.Context.addDefaultArgExprForConstructor(CD, I, DefaultArg);<br>
-    }<br>
-  }<br>
-}<br>
-<br>
 void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,<br>
                                     SourceLocation RBraceLoc) {<br>
   AdjustDeclIfTemplate(TagD);<br>
@@ -12098,17 +12080,9 @@ void Sema::ActOnTagFinishDefinition(Scop<br>
       RD->completeDefinition();<br>
   }<br>
<br>
-  if (auto *Class = dyn_cast<CXXRecordDecl>(Tag)) {<br>
+  if (isa<CXXRecordDecl>(Tag))<br>
     FieldCollector->FinishClass();<br>
<br>
-    // Default constructors that are annotated with __declspec(dllexport) which<br>
-    // have default arguments or don't use the standard calling convention are<br>
-    // wrapped with a thunk called the default constructor closure.<br>
-    if (!Class->getDescribedClassTemplate() &&<br>
-        Context.getTargetInfo().getCXXABI().isMicrosoft())<br>
-      getDefaultArgExprsForConstructors(*this, Class);<br>
-  }<br>
-<br>
   // Exit this scope of this tag's definition.<br>
   PopDeclContext();<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=232519&r1=232518&r2=232519&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=232519&r1=232518&r2=232519&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 17 14:00:50 2015<br>
@@ -9421,6 +9421,44 @@ void Sema::ActOnFinishCXXMemberDecls() {<br>
   }<br>
 }<br>
<br>
+static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) {<br>
+  // Don't do anything for template patterns.<br>
+  if (Class->getDescribedClassTemplate())<br>
+    return;<br>
+<br>
+  for (Decl *Member : Class->decls()) {<br>
+    auto *CD = dyn_cast<CXXConstructorDecl>(Member);<br>
+    if (!CD) {<br>
+      // Recurse on nested classes.<br>
+      if (auto *NestedRD = dyn_cast<CXXRecordDecl>(Member))<br>
+        getDefaultArgExprsForConstructors(S, NestedRD);<br>
+      continue;<br>
+    } else if (!CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>()) {<br>
+      continue;<br>
+    }<br>
+<br>
+    for (unsigned I = 0, E = CD->getNumParams(); I != E; ++I) {<br>
+      // Skip any default arguments that we've already instantiated.<br>
+      if (S.Context.getDefaultArgExprForConstructor(CD, I))<br>
+        continue;<br>
+<br>
+      Expr *DefaultArg = S.BuildCXXDefaultArgExpr(Class->getLocation(), CD,<br>
+                                                  CD->getParamDecl(I)).get();<br>
+      S.Context.addDefaultArgExprForConstructor(CD, I, DefaultArg);<br>
+    }<br>
+  }<br>
+}<br>
+<br>
+void Sema::ActOnFinishCXXMethodDefs(Decl *D) {<br>
+  auto *RD = dyn_cast<CXXRecordDecl>(D);<br>
+<br>
+  // Default constructors that are annotated with __declspec(dllexport) which<br>
+  // have default arguments or don't use the standard calling convention are<br>
+  // wrapped with a thunk called the default constructor closure.<br>
+  if (RD && Context.getTargetInfo().getCXXABI().isMicrosoft())<br>
+    getDefaultArgExprsForConstructors(*this, RD);<br>
+}<br>
+<br>
 void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,<br>
                                          CXXDestructorDecl *Destructor) {<br>
   assert(getLangOpts().CPlusPlus11 &&<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=232519&r1=232518&r2=232519&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=232519&r1=232518&r2=232519&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Tue Mar 17 14:00:50 2015<br>
@@ -486,7 +486,7 @@ struct S {<br>
<br>
 struct CtorWithClosure {<br>
   __declspec(dllexport) CtorWithClosure(...) {}<br>
-// M32-DAG: define weak_odr dllexport void @"\01??_FCtorWithClosure@@QAEXXZ"<br>
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"<br>
 // M32-DAG:   %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4<br>
 // M32-DAG:   store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4<br>
 // M32-DAG:   %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]]<br>
@@ -494,12 +494,16 @@ struct CtorWithClosure {<br>
 // M32-DAG:   ret void<br>
 };<br>
<br>
+#define DELETE_IMPLICIT_MEMBERS(ClassName) \<br>
+    ClassName(ClassName &&) = delete; \<br>
+    ClassName(ClassName &) = delete; \<br>
+    ~ClassName() = delete; \<br>
+    ClassName &operator=(ClassName &) = delete<br>
+<br>
 struct __declspec(dllexport) ClassWithClosure {<br>
-  ClassWithClosure(ClassWithClosure &&) = delete;<br>
-  ClassWithClosure(ClassWithClosure &) = delete;<br>
-  ~ClassWithClosure() = delete;<br>
+  DELETE_IMPLICIT_MEMBERS(ClassWithClosure);<br>
   ClassWithClosure(...) {}<br>
-// M32-DAG: define weak_odr dllexport void @"\01??_FClassWithClosure@@QAEXXZ"<br>
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"<br>
 // M32-DAG:   %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4<br>
 // M32-DAG:   store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4<br>
 // M32-DAG:   %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]]<br>
@@ -507,6 +511,18 @@ struct __declspec(dllexport) ClassWithCl<br>
 // M32-DAG:   ret void<br>
 };<br>
<br>
+struct __declspec(dllexport) NestedOuter {<br>
+  DELETE_IMPLICIT_MEMBERS(NestedOuter);<br>
+  NestedOuter(void *p = 0) {}<br>
+  struct __declspec(dllexport) NestedInner {<br>
+    DELETE_IMPLICIT_MEMBERS(NestedInner);<br>
+    NestedInner(void *p = 0) {}<br>
+  };<br>
+};<br>
+<br>
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"<br>
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"<br>
+<br>
 struct __declspec(dllexport) T {<br>
   // Copy assignment operator:<br>
   // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z"<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>