[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