[cfe-commits] r78700 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/CodeGen/CGCXX.cpp lib/CodeGen/CodeGenModule.cpp lib/Sema/SemaDeclCXX.cpp test/CodeGenCXX/copy-constructor-synthesis.cpp
Fariborz Jahanian
fjahanian at apple.com
Tue Aug 11 11:49:55 PDT 2009
Author: fjahanian
Date: Tue Aug 11 13:49:54 2009
New Revision: 78700
URL: http://llvm.org/viewvc/llvm-project?rev=78700&view=rev
Log:
ir-gen support for anonymous union data member
copying in copy constructors and used in
default constructor's initializer list.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CodeGenCXX/copy-constructor-synthesis.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=78700&r1=78699&r2=78700&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Aug 11 13:49:54 2009
@@ -779,9 +779,28 @@
Stmt **Args;
unsigned NumArgs;
- /// CtorToCall - For a base or member needing a constructor for their
- /// initialization, this is the constructor to call.
- CXXConstructorDecl *CtorToCall;
+ union {
+ /// CtorToCall - For a base or member needing a constructor for their
+ /// initialization, this is the constructor to call.
+ CXXConstructorDecl *CtorToCall;
+
+ /// AnonUnionMember - When 'BaseOrMember' is class's anonymous union
+ /// data member, this field holds the FieldDecl for the member of the
+ /// anonymous union being initialized.
+ /// @code
+ /// struct X {
+ /// X() : au_i1(123) {}
+ /// union {
+ /// int au_i1;
+ /// float au_f1;
+ /// };
+ /// };
+ /// @endcode
+ /// In above example, BaseOrMember holds the field decl. for anonymous union
+ /// and AnonUnionMember holds field decl for au_i1.
+ ///
+ FieldDecl *AnonUnionMember;
+ };
/// IdLoc - Location of the id in ctor-initializer list.
SourceLocation IdLoc;
@@ -854,6 +873,17 @@
return 0;
}
+ void setMember(FieldDecl * anonUnionField) {
+ BaseOrMember = reinterpret_cast<uintptr_t>(anonUnionField);
+ }
+
+ FieldDecl *getAnonUnionMember() const {
+ return AnonUnionMember;
+ }
+ void setAnonUnionMember(FieldDecl *anonMember) {
+ AnonUnionMember = anonMember;
+ }
+
const CXXConstructorDecl *getConstructor() const { return CtorToCall; }
SourceLocation getSourceLocation() const { return IdLoc; }
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=78700&r1=78699&r2=78700&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Aug 11 13:49:54 2009
@@ -643,6 +643,11 @@
for(RecordDecl::field_iterator FA = FieldClassDecl->field_begin(),
EA = FieldClassDecl->field_end(); FA != EA; FA++) {
if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*FA)) {
+ // 'Member' is the anonymous union field and 'AnonUnionMember' is
+ // set to the anonymous union data member used in the initializer
+ // list.
+ Value->setMember(*Field);
+ Value->setAnonUnionMember(*FA);
AllToInit.push_back(Value);
break;
}
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=78700&r1=78699&r2=78700&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue Aug 11 13:49:54 2009
@@ -874,8 +874,7 @@
// FIXME. How about copying arrays!
assert(!getContext().getAsArrayType(FieldType) &&
"FIXME. Copying arrays NYI");
- assert(!Field->isAnonymousStructOrUnion() &&
- "FIXME. anonymous data member NYI in copy constructor synthesis");
+
if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
CXXRecordDecl *FieldClassDecl
= cast<CXXRecordDecl>(FieldClassType->getDecl());
@@ -924,23 +923,25 @@
QualType FieldType = getContext().getCanonicalType((Field)->getType());
assert(!getContext().getAsArrayType(FieldType)
&& "FIXME. Field arrays initialization unsupported");
- DeclContext *Ctx = Field->getDeclContext();
- RecordDecl *Record = cast<RecordDecl>(Ctx);
- assert(!Record->isAnonymousStructOrUnion() &&
- "FIXME. anonymous union initializer NYI in default constructor");
- (void)Record;
LoadOfThis = LoadCXXThis();
LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
if (FieldType->getAs<RecordType>()) {
-
+ if (!Field->isAnonymousStructOrUnion()) {
assert(Member->getConstructor() &&
"EmitCtorPrologue - no constructor to initialize member");
EmitCXXConstructorCall(Member->getConstructor(),
Ctor_Complete, LHS.getAddress(),
Member->const_arg_begin(),
Member->const_arg_end());
- continue;
+ continue;
+ }
+ else {
+ // Initializing an anonymous union data member.
+ FieldDecl *anonMember = Member->getAnonUnionMember();
+ LHS = EmitLValueForField(LHS.getAddress(), anonMember, false, 0);
+ FieldType = anonMember->getType();
+ }
}
assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=78700&r1=78699&r2=78700&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Aug 11 13:49:54 2009
@@ -699,14 +699,14 @@
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
FieldEnd = ClassDecl->field_end();
Field != FieldEnd; ++Field) {
- assert(!(*Field)->isAnonymousStructOrUnion() &&
- "FIXME. Anonymous union NYI - DeferredCopyConstructorToEmit");
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ if ((*Field)->isAnonymousStructOrUnion())
+ continue;
CXXRecordDecl *FieldClassDecl
- = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
if (CXXConstructorDecl *FieldCopyCtor =
FieldClassDecl->getCopyConstructor(Context, 0))
GetAddrOfCXXConstructor(FieldCopyCtor, Ctor_Complete);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=78700&r1=78699&r2=78700&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Aug 11 13:49:54 2009
@@ -880,10 +880,16 @@
return static_cast<void *>(Field);
}
-static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member) {
+static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member,
+ bool MemberMaybeAnon=false) {
// For fields injected into the class via declaration of an anonymous union,
// use its anonymous union class declaration as the unique key.
if (FieldDecl *Field = Member->getMember()) {
+ // After BuildBaseOrMemberInitializers call, Field is the anonymous union
+ // data member of the class. Data member used in the initializer list is
+ // in AnonUnionMember field.
+ if (MemberMaybeAnon && Field->isAnonymousStructOrUnion())
+ Field = Member->getAnonUnionMember();
if (Field->getDeclContext()->isRecord()) {
RecordDecl *RD = cast<RecordDecl>(Field->getDeclContext());
if (RD->isAnonymousStructOrUnion())
@@ -973,7 +979,7 @@
for (unsigned i = 0; i < NumMemInits; i++) {
CXXBaseOrMemberInitializer *Member =
static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
- void *MemberInCtorList = GetKeyForMember(Member);
+ void *MemberInCtorList = GetKeyForMember(Member, true);
for (; curIndex < Last; curIndex++)
if (MemberInCtorList == AllBaseOrMembers[curIndex])
Modified: cfe/trunk/test/CodeGenCXX/copy-constructor-synthesis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/copy-constructor-synthesis.cpp?rev=78700&r1=78699&r2=78700&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/copy-constructor-synthesis.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/copy-constructor-synthesis.cpp Tue Aug 11 13:49:54 2009
@@ -26,12 +26,15 @@
struct X : M, N, P { // ...
- X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd) {}
+ X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd),
+ au_i1(1234), au1_4("MASKED") {}
P p0;
void pr() { printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM);
printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP);
printf("f1 = %f d1 = %f i1 = %d name(%s) \n", f1, d1, i1, name);
printf("bf1 = %x bf2 = %x\n", bf1, bf2);
+ printf("au_i2 = %d\n", au_i2);
+ printf("au1_1 = %s\n", au1_1);
}
M m1;
P p1;
@@ -41,6 +44,17 @@
const char *name;
unsigned bf1 : 8;
unsigned bf2 : 16;
+
+ union {
+ int au_i1;
+ int au_i2;
+ };
+ union {
+ const char * au1_1;
+ float au1_2;
+ int au1_3;
+ const char * au1_4;
+ };
};
int main()
More information about the cfe-commits
mailing list