[cfe-commits] [PATCH][MS][Review request] - Direct constructor call

Douglas Gregor dgregor at apple.com
Mon Jan 17 13:49:11 PST 2011


On Dec 29, 2010, at 2:32 PM, Francois Pichet wrote:

> Hi
> 
> This patch adds support for direct constructor calls in -fms-extensions mode.
> Why? Because msvc supports it!
> 
> I found clang couldn't parse such kind of code found in msvc header files:
> 
> class CtorCall { 
> public:
>   CtorCall& CtorCall::operator=(const CtorCall& that)
>   {
>       if (this != &that) {
>           this->CtorCall::~CtorCall();
>           this->CtorCall::CtorCall(that);  // <=== direct ctor call, clang error.
>       }
>       return *this;
>   };

Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp	(revision 122624)
+++ lib/Sema/SemaOverload.cpp	(working copy)
@@ -7888,7 +7888,11 @@
       if (isa<UsingShadowDecl>(Func))
         Func = cast<UsingShadowDecl>(Func)->getTargetDecl();
 
-      if ((Method = dyn_cast<CXXMethodDecl>(Func))) {
+      
+      if (getLangOptions().Microsoft && isa<CXXConstructorDecl>(Func)) {
+        AddOverloadCandidate(cast<CXXConstructorDecl>(Func), I.getPair(), Args, NumArgs,
+                             CandidateSet);
+      } else if ((Method = dyn_cast<CXXMethodDecl>(Func))) {
         // If explicit template arguments were provided, we can't call a
         // non-template member function.
         if (TemplateArgs)

Does Microsoft also allow calls to constructor templates here? If so, you should account for those. Then, there's the question of explicitly-specified template arguments, e.g.,

	this->Foo::Foo<int*>(0);

which is likely to require more work.

Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp	(revision 122624)
+++ lib/CodeGen/CGExprCXX.cpp	(working copy)
@@ -93,6 +93,8 @@
   return false;
 }
 
+// Note: This function also emit constructor calls to support a MSVC
+// extensions allowing explicit constructor function call.
 RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
                                               ReturnValueSlot ReturnValue) {
   if (isa<BinaryOperator>(CE->getCallee()->IgnoreParens())) 
@@ -127,25 +129,40 @@
 
   if (MD->isTrivial()) {
     if (isa<CXXDestructorDecl>(MD)) return RValue::get(0);
+    if (isa<CXXConstructorDecl>(MD) && 
+        cast<CXXConstructorDecl>(MD)->isDefaultConstructor())
+      return RValue::get(0);
 
-    assert(MD->isCopyAssignmentOperator() && "unknown trivial member function");
-    // We don't like to generate the trivial copy assignment operator when
-    // it isn't necessary; just produce the proper effect here.
-    llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress();
-    EmitAggregateCopy(This, RHS, CE->getType());
-    return RValue::get(This);
+    if (MD->isCopyAssignmentOperator()) {
+      // We don't like to generate the trivial copy assignment operator when
+      // it isn't necessary; just produce the proper effect here.
+      llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress();
+      EmitAggregateCopy(This, RHS, CE->getType());
+      return RValue::get(This);
+    } else if (isa<CXXConstructorDecl>(MD) && 
+               cast<CXXConstructorDecl>(MD)->isCopyConstructor()) {
+      llvm::Value *RHS = EmitLValue(*CE->arg_begin()).getAddress();
+      EmitSynthesizedCXXCopyCtorCall(cast<CXXConstructorDecl>(MD), This, RHS,
+                                     CE->arg_begin(), CE->arg_end());
+      return RValue::get(This);
+    }
+    llvm_unreachable("unknown trivial member function");
   }
 
Please reduce nesting in this last sequence, e.g.,

if (MD->isCopyAssignmentOperator() {
  // Handle copy assign.
  return RValue::get(This);
}

if (/* is copy constructor */) {
  // Handle copy constructor
  return RValue::get(This);
}

llvm_unreachable("unknown trivial member function");

Aside: is it worth emitting an Extension diagnostic for uses of this Microsoft extension?

	- Doug



More information about the cfe-commits mailing list