[cfe-commits] r150451 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/CodeGen/CGClass.cpp
Eli Friedman
eli.friedman at gmail.com
Mon Feb 13 18:15:49 PST 2012
Author: efriedma
Date: Mon Feb 13 20:15:49 2012
New Revision: 150451
URL: http://llvm.org/viewvc/llvm-project?rev=150451&view=rev
Log:
Refactor out new function EmitInitializerForField from EmitMemberInitializer. The new function will be used to initialize the fields of lambda expressions.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/CodeGen/CGClass.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=150451&r1=150450&r2=150451&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Feb 13 20:15:49 2012
@@ -1809,6 +1809,11 @@
assert(I < getNumArrayIndices() && "Out of bounds member array index");
reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
}
+ ArrayRef<VarDecl *> getArrayIndexes() {
+ assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
+ return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1),
+ getNumArrayIndices());
+ }
/// \brief Get the initializer. This is 0 if this is an in-class initializer
/// for a non-static data member which has not yet been parsed.
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=150451&r1=150450&r2=150451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Mon Feb 13 20:15:49 2012
@@ -412,11 +412,12 @@
static void EmitAggMemberInitializer(CodeGenFunction &CGF,
LValue LHS,
+ Expr *Init,
llvm::Value *ArrayIndexVar,
- CXXCtorInitializer *MemberInit,
QualType T,
+ ArrayRef<VarDecl *> ArrayIndexes,
unsigned Index) {
- if (Index == MemberInit->getNumArrayIndices()) {
+ if (Index == ArrayIndexes.size()) {
CodeGenFunction::RunCleanupsScope Cleanups(CGF);
LValue LV = LHS;
@@ -437,9 +438,9 @@
}
if (!CGF.hasAggregateLLVMType(T)) {
- CGF.EmitScalarInit(MemberInit->getInit(), /*decl*/ 0, LV, false);
+ CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
} else if (T->isAnyComplexType()) {
- CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LV.getAddress(),
+ CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(),
LV.isVolatileQualified());
} else {
AggValueSlot Slot =
@@ -448,7 +449,7 @@
AggValueSlot::DoesNotNeedGCBarriers,
AggValueSlot::IsNotAliased);
- CGF.EmitAggExpr(MemberInit->getInit(), Slot);
+ CGF.EmitAggExpr(Init, Slot);
}
return;
@@ -457,7 +458,7 @@
const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);
assert(Array && "Array initialization without the array type?");
llvm::Value *IndexVar
- = CGF.GetAddrOfLocalVar(MemberInit->getArrayIndex(Index));
+ = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]);
assert(IndexVar && "Array index variable not loaded");
// Initialize this index variable to zero.
@@ -493,8 +494,8 @@
// Inside the loop body recurse to emit the inner loop or, eventually, the
// constructor call.
- EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit,
- Array->getElementType(), Index + 1);
+ EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
+ Array->getElementType(), ArrayIndexes, Index + 1);
}
CGF.EmitBlock(ContinueBlock);
@@ -514,19 +515,15 @@
namespace {
struct CallMemberDtor : EHScopeStack::Cleanup {
- FieldDecl *Field;
+ llvm::Value *V;
CXXDestructorDecl *Dtor;
- CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor)
- : Field(Field), Dtor(Dtor) {}
+ CallMemberDtor(llvm::Value *V, CXXDestructorDecl *Dtor)
+ : V(V), Dtor(Dtor) {}
void Emit(CodeGenFunction &CGF, Flags flags) {
- // FIXME: Is this OK for C++0x delegating constructors?
- llvm::Value *ThisPtr = CGF.LoadCXXThis();
- LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
-
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
- LHS.getAddress());
+ V);
}
};
}
@@ -536,7 +533,11 @@
return Moving ? Record->hasTrivialMoveConstructor() :
Record->hasTrivialCopyConstructor();
}
-
+
+static void EmitInitializerForField(CodeGenFunction &CGF, FieldDecl *Field,
+ LValue LHS, Expr *Init,
+ ArrayRef<VarDecl *> ArrayIndexes);
+
static void EmitMemberInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
CXXCtorInitializer *MemberInit,
@@ -548,7 +549,7 @@
// non-static data member initializers.
FieldDecl *Field = MemberInit->getAnyMember();
- QualType FieldType = CGF.getContext().getCanonicalType(Field->getType());
+ QualType FieldType = Field->getType();
llvm::Value *ThisPtr = CGF.LoadCXXThis();
LValue LHS;
@@ -562,28 +563,63 @@
LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
}
- if (!CGF.hasAggregateLLVMType(Field->getType())) {
+ // Special case: if we are in a copy or move constructor, and we are copying
+ // an array of PODs or classes with trivial copy constructors, ignore the
+ // AST and perform the copy we know is equivalent.
+ // FIXME: This is hacky at best... if we had a bit more explicit information
+ // in the AST, we could generalize it more easily.
+ const ConstantArrayType *Array
+ = CGF.getContext().getAsConstantArrayType(FieldType);
+ if (Array && Constructor->isImplicitlyDefined() &&
+ Constructor->isCopyOrMoveConstructor()) {
+ QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
+ const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl();
+ if (BaseElementTy.isPODType(CGF.getContext()) ||
+ (Record && hasTrivialCopyOrMoveConstructor(Record,
+ Constructor->isMoveConstructor()))) {
+ // Find the source pointer. We knows it's the last argument because
+ // we know we're in a copy constructor.
+ unsigned SrcArgIndex = Args.size() - 1;
+ llvm::Value *SrcPtr
+ = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
+ LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
+
+ // Copy the aggregate.
+ CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
+ LHS.isVolatileQualified());
+ return;
+ }
+ }
+
+ ArrayRef<VarDecl *> ArrayIndexes;
+ if (MemberInit->getNumArrayIndices())
+ ArrayIndexes = MemberInit->getArrayIndexes();
+ EmitInitializerForField(CGF, Field, LHS, MemberInit->getInit(), ArrayIndexes);
+}
+
+static void EmitInitializerForField(CodeGenFunction &CGF, FieldDecl *Field,
+ LValue LHS, Expr *Init,
+ ArrayRef<VarDecl *> ArrayIndexes) {
+ QualType FieldType = Field->getType();
+ if (!CGF.hasAggregateLLVMType(FieldType)) {
if (LHS.isSimple()) {
- CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS, false);
+ CGF.EmitExprAsInit(Init, Field, LHS, false);
} else {
- RValue RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit()));
+ RValue RHS = RValue::get(CGF.EmitScalarExpr(Init));
CGF.EmitStoreThroughLValue(RHS, LHS);
}
- } else if (MemberInit->getInit()->getType()->isAnyComplexType()) {
- CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), LHS.getAddress(),
+ } else if (FieldType->isAnyComplexType()) {
+ CGF.EmitComplexExprIntoAddr(Init, LHS.getAddress(),
LHS.isVolatileQualified());
} else {
llvm::Value *ArrayIndexVar = 0;
- const ConstantArrayType *Array
- = CGF.getContext().getAsConstantArrayType(FieldType);
- if (Array && Constructor->isImplicitlyDefined() &&
- Constructor->isCopyOrMoveConstructor()) {
+ if (ArrayIndexes.size()) {
llvm::Type *SizeTy
= CGF.ConvertType(CGF.getContext().getSizeType());
// The LHS is a pointer to the first object we'll be constructing, as
// a flat array.
- QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
+ QualType BaseElementTy = CGF.getContext().getBaseElementType(FieldType);
llvm::Type *BasePtr = CGF.ConvertType(BaseElementTy);
BasePtr = llvm::PointerType::getUnqual(BasePtr);
llvm::Value *BaseAddrPtr = CGF.Builder.CreateBitCast(LHS.getAddress(),
@@ -596,31 +632,14 @@
llvm::Value *Zero = llvm::Constant::getNullValue(SizeTy);
CGF.Builder.CreateStore(Zero, ArrayIndexVar);
- // If we are copying an array of PODs or classes with trivial copy
- // constructors, perform a single aggregate copy.
- const CXXRecordDecl *Record = BaseElementTy->getAsCXXRecordDecl();
- if (BaseElementTy.isPODType(CGF.getContext()) ||
- (Record && hasTrivialCopyOrMoveConstructor(Record,
- Constructor->isMoveConstructor()))) {
- // Find the source pointer. We knows it's the last argument because
- // we know we're in a copy constructor.
- unsigned SrcArgIndex = Args.size() - 1;
- llvm::Value *SrcPtr
- = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
- LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
-
- // Copy the aggregate.
- CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
- LHS.isVolatileQualified());
- return;
- }
// Emit the block variables for the array indices, if any.
- for (unsigned I = 0, N = MemberInit->getNumArrayIndices(); I != N; ++I)
- CGF.EmitAutoVarDecl(*MemberInit->getArrayIndex(I));
+ for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I)
+ CGF.EmitAutoVarDecl(*ArrayIndexes[I]);
}
- EmitAggMemberInitializer(CGF, LHS, ArrayIndexVar, MemberInit, FieldType, 0);
+ EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, FieldType,
+ ArrayIndexes, 0);
if (!CGF.CGM.getLangOptions().Exceptions)
return;
@@ -634,7 +653,7 @@
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
if (!RD->hasTrivialDestructor())
- CGF.EHStack.pushCleanup<CallMemberDtor>(EHCleanup, Field,
+ CGF.EHStack.pushCleanup<CallMemberDtor>(EHCleanup, LHS.getAddress(),
RD->getDestructor());
}
}
More information about the cfe-commits
mailing list