[cfe-commits] r84265 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp lib/Sema/Sema.h lib/Sema/SemaExprCXX.cpp test/CodeGenCXX/derived-to-base-conv.cpp
Fariborz Jahanian
fjahanian at apple.com
Fri Oct 16 12:20:59 PDT 2009
Author: fjahanian
Date: Fri Oct 16 14:20:59 2009
New Revision: 84265
URL: http://llvm.org/viewvc/llvm-project?rev=84265&view=rev
Log:
Implement derived-to-base AST/code gen. There is a
FIXME in CGCXX.cpp that I would like Anders to
take a look at.
Added:
cfe/trunk/test/CodeGenCXX/derived-to-base-conv.cpp
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExprCXX.cpp
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=84265&r1=84264&r2=84265&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Oct 16 14:20:59 2009
@@ -566,6 +566,10 @@
assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
"EmitCXXConstructorCall - user declared copy constructor");
const Expr *E = (*ArgBeg);
+ // FIXME. This may not be correct. But till now, we were skipping
+ // code gen of trivial copy constructors regardless of their arguments.
+ if (isa<CXXZeroInitValueExpr>(E))
+ return;
QualType Ty = E->getType();
llvm::Value *Src = EmitLValue(E).getAddress();
EmitAggregateCopy(This, Src, Ty);
@@ -590,12 +594,15 @@
CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
const CXXConstructExpr *E) {
assert(Dest && "Must have a destination!");
-
- const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
- if (RD->hasTrivialConstructor())
+ const CXXConstructorDecl *CD = E->getConstructor();
+ // For a copy constructor, even if it is trivial, must fall thru so
+ // its argument is code-gen'ed.
+ if (!CD->isCopyConstructor(getContext())) {
+ const CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
+ if (RD->hasTrivialConstructor())
return;
-
+ }
// Code gen optimization to eliminate copy constructor and return
// its first argument instead.
if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
@@ -604,7 +611,7 @@
return;
}
// Call the constructor.
- EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest,
+ EmitCXXConstructorCall(CD, Ctor_Complete, Dest,
E->arg_begin(), E->arg_end());
}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=84265&r1=84264&r2=84265&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Oct 16 14:20:59 2009
@@ -3552,6 +3552,10 @@
bool PerformImplicitConversion(Expr *&From, QualType ToType,
const StandardConversionSequence& SCS,
const char *Flavor);
+
+ bool BuildCXXDerivedToBaseExpr(Expr *&From, CastExpr::CastKind CastKind,
+ const ImplicitConversionSequence& ICS,
+ const char *Flavor);
/// the following "Check" methods will return a valid/converted QualType
/// or a null QualType (indicating an error diagnostic was issued).
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=84265&r1=84264&r2=84265&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Oct 16 14:20:59 2009
@@ -1043,6 +1043,40 @@
return PerformImplicitConversion(From, ToType, ICS, Flavor);
}
+/// BuildCXXDerivedToBaseExpr - This routine generates the suitable AST
+/// for the derived to base conversion of the expression 'From'. All
+/// necessary information is passed in ICS.
+bool
+Sema::BuildCXXDerivedToBaseExpr(Expr *&From, CastExpr::CastKind CastKind,
+ const ImplicitConversionSequence& ICS,
+ const char *Flavor) {
+ QualType BaseType =
+ QualType::getFromOpaquePtr(ICS.UserDefined.After.ToTypePtr);
+ // Must do additional defined to base conversion.
+ QualType DerivedType =
+ QualType::getFromOpaquePtr(ICS.UserDefined.After.FromTypePtr);
+
+ From = new (Context) ImplicitCastExpr(
+ DerivedType.getNonReferenceType(),
+ CastKind,
+ From,
+ DerivedType->isLValueReferenceType());
+ From = new (Context) ImplicitCastExpr(BaseType.getNonReferenceType(),
+ CastExpr::CK_DerivedToBase, From,
+ BaseType->isLValueReferenceType());
+ ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
+ OwningExprResult FromResult =
+ BuildCXXConstructExpr(
+ ICS.UserDefined.After.CopyConstructor->getLocation(),
+ BaseType,
+ ICS.UserDefined.After.CopyConstructor,
+ MultiExprArg(*this, (void **)&From, 1));
+ if (FromResult.isInvalid())
+ return true;
+ From = FromResult.takeAs<Expr>();
+ return false;
+}
+
/// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType using the pre-computed implicit
/// conversion sequence ICS. Returns true if there was an error, false
@@ -1095,13 +1129,19 @@
if (CastArg.isInvalid())
return true;
+
+ if (ICS.UserDefined.After.Second == ICK_Derived_To_Base &&
+ ICS.UserDefined.After.CopyConstructor) {
+ From = CastArg.takeAs<Expr>();
+ return BuildCXXDerivedToBaseExpr(From, CastKind, ICS, Flavor);
+ }
From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(),
- CastKind, CastArg.takeAs<Expr>(),
+ CastKind, CastArg.takeAs<Expr>(),
ToType->isLValueReferenceType());
return false;
- }
-
+ }
+
case ImplicitConversionSequence::EllipsisConversion:
assert(false && "Cannot perform an ellipsis conversion");
return false;
Added: cfe/trunk/test/CodeGenCXX/derived-to-base-conv.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/derived-to-base-conv.cpp?rev=84265&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/derived-to-base-conv.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/derived-to-base-conv.cpp Fri Oct 16 14:20:59 2009
@@ -0,0 +1,51 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s &&
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s &&
+// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+struct A {
+ A (const A&) { printf("A::A(const A&)\n"); }
+ A() {};
+};
+
+struct B : public A {
+ B() {};
+};
+
+struct C : public B {
+ C() {};
+};
+
+struct X {
+ operator B&() {printf("X::operator B&()\n"); return b; }
+ operator C&() {printf("X::operator C&()\n"); return c; }
+ X (const X&) { printf("X::X(const X&)\n"); }
+ X () { printf("X::X()\n"); }
+ B b;
+ C c;
+};
+
+void f(A) {
+ printf("f(A)\n");
+}
+
+
+void func(X x)
+{
+ f (x);
+}
+
+int main()
+{
+ X x;
+ func(x);
+}
+
+// CHECK-LP64: call __ZN1XcvR1BEv
+// CHECK-LP64: call __ZN1AC1ERKS_
+
+// CHECK-LP32: call L__ZN1XcvR1BEv
+// CHECK-LP32: call L__ZN1AC1ERKS_
More information about the cfe-commits
mailing list