[cfe-commits] r132835 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaLookup.cpp
Sean Hunt
scshunt at csclub.uwaterloo.ca
Thu Jun 9 21:44:37 PDT 2011
Author: coppro
Date: Thu Jun 9 23:44:37 2011
New Revision: 132835
URL: http://llvm.org/viewvc/llvm-project?rev=132835&view=rev
Log:
Implement caching for copy constructors in similar situations.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=132835&r1=132834&r2=132835&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 9 23:44:37 2011
@@ -1669,6 +1669,9 @@
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class);
+ CXXConstructorDecl *LookupCopyConstructor(CXXRecordDecl *Class,
+ unsigned Quals,
+ bool *ConstParam = 0);
CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
void ArgumentDependentLookup(DeclarationName Name, bool Operator,
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=132835&r1=132834&r2=132835&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun 9 23:44:37 2011
@@ -3481,12 +3481,13 @@
// Do access control from the constructor
ContextRAII CtorContext(*this, CD);
- bool Union = RD->isUnion();
+ bool Union = RD->isUnion();
assert(!CD->getParamDecl(0)->getType()->getPointeeType().isNull() &&
"copy assignment arg has no pointee type");
- bool ConstArg =
- CD->getParamDecl(0)->getType()->getPointeeType().isConstQualified();
+ unsigned ArgQuals =
+ CD->getParamDecl(0)->getType()->getPointeeType().isConstQualified() ?
+ Qualifiers::Const : 0;
// We do this because we should never actually use an anonymous
// union's constructor.
@@ -3522,20 +3523,11 @@
// resolution, as applied to B's [copy] constructor, results in an
// ambiguity or a function that is deleted or inaccessible from the
// defaulted constructor
- InitializedEntity BaseEntity =
- InitializedEntity::InitializeBase(Context, BI, 0);
- InitializationKind Kind =
- InitializationKind::CreateDirect(Loc, Loc, Loc);
-
- // Construct a fake expression to perform the copy overloading.
- QualType ArgType = BaseType.getUnqualifiedType();
- if (ConstArg)
- ArgType.addConst();
- Expr *Arg = new (Context) OpaqueValueExpr(Loc, ArgType, VK_LValue);
-
- InitializationSequence InitSeq(*this, BaseEntity, Kind, &Arg, 1);
-
- if (InitSeq.Failed())
+ CXXConstructorDecl *BaseCtor = LookupCopyConstructor(BaseDecl, ArgQuals);
+ if (!BaseCtor || BaseCtor->isDeleted())
+ return true;
+ if (CheckConstructorAccess(Loc, BaseCtor, BaseCtor->getAccess(), PDiag()) !=
+ AR_accessible)
return true;
}
@@ -3559,20 +3551,11 @@
// resolution, as applied to B's [copy] constructor, results in an
// ambiguity or a function that is deleted or inaccessible from the
// defaulted constructor
- InitializedEntity BaseEntity =
- InitializedEntity::InitializeBase(Context, BI, BI);
- InitializationKind Kind =
- InitializationKind::CreateDirect(Loc, Loc, Loc);
-
- // Construct a fake expression to perform the copy overloading.
- QualType ArgType = BaseType.getUnqualifiedType();
- if (ConstArg)
- ArgType.addConst();
- Expr *Arg = new (Context) OpaqueValueExpr(Loc, ArgType, VK_LValue);
-
- InitializationSequence InitSeq(*this, BaseEntity, Kind, &Arg, 1);
-
- if (InitSeq.Failed())
+ CXXConstructorDecl *BaseCtor = LookupCopyConstructor(BaseDecl, ArgQuals);
+ if (!BaseCtor || BaseCtor->isDeleted())
+ return true;
+ if (CheckConstructorAccess(Loc, BaseCtor, BaseCtor->getAccess(), PDiag()) !=
+ AR_accessible)
return true;
}
@@ -3625,32 +3608,19 @@
AR_accessible)
return true;
}
- }
- llvm::SmallVector<InitializedEntity, 4> Entities;
- QualType CurType = FI->getType();
- Entities.push_back(InitializedEntity::InitializeMember(*FI, 0));
- while (CurType->isArrayType()) {
- Entities.push_back(InitializedEntity::InitializeElement(Context, 0,
- Entities.back()));
- CurType = Context.getAsArrayType(CurType)->getElementType();
+ // -- a [non-static data member of class type (or array thereof)] B that
+ // cannot be [copied] because overload resolution, as applied to B's
+ // [copy] constructor, results in an ambiguity or a function that is
+ // deleted or inaccessible from the defaulted constructor
+ CXXConstructorDecl *FieldCtor = LookupCopyConstructor(FieldRecord,
+ ArgQuals);
+ if (!FieldCtor || FieldCtor->isDeleted())
+ return true;
+ if (CheckConstructorAccess(Loc, FieldCtor, FieldCtor->getAccess(),
+ PDiag()) != AR_accessible)
+ return true;
}
-
- InitializationKind Kind =
- InitializationKind::CreateDirect(Loc, Loc, Loc);
-
- // Construct a fake expression to perform the copy overloading.
- QualType ArgType = FieldType;
- if (ArgType->isReferenceType())
- ArgType = ArgType->getPointeeType();
- else if (ConstArg)
- ArgType.addConst();
- Expr *Arg = new (Context) OpaqueValueExpr(Loc, ArgType, VK_LValue);
-
- InitializationSequence InitSeq(*this, Entities.back(), Kind, &Arg, 1);
-
- if (InitSeq.Failed())
- return true;
}
return false;
@@ -7043,6 +7013,7 @@
// X::X(const X&)
//
// if
+ // FIXME: It ought to be possible to store this on the record.
bool HasConstCopyConstructor = true;
// -- each direct or virtual base class B of X has a copy
@@ -7058,10 +7029,8 @@
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- if (!BaseClassDecl->hasDeclaredCopyConstructor())
- DeclareImplicitCopyConstructor(BaseClassDecl);
-
- HasConstCopyConstructor = BaseClassDecl->hasConstCopyConstructor();
+ LookupCopyConstructor(BaseClassDecl, Qualifiers::Const,
+ &HasConstCopyConstructor);
}
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
@@ -7070,10 +7039,8 @@
++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- if (!BaseClassDecl->hasDeclaredCopyConstructor())
- DeclareImplicitCopyConstructor(BaseClassDecl);
-
- HasConstCopyConstructor= BaseClassDecl->hasConstCopyConstructor();
+ LookupCopyConstructor(BaseClassDecl, Qualifiers::Const,
+ &HasConstCopyConstructor);
}
// -- for all the nonstatic data members of X that are of a
@@ -7085,13 +7052,9 @@
HasConstCopyConstructor && Field != FieldEnd;
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
- if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
- CXXRecordDecl *FieldClassDecl
- = cast<CXXRecordDecl>(FieldClassType->getDecl());
- if (!FieldClassDecl->hasDeclaredCopyConstructor())
- DeclareImplicitCopyConstructor(FieldClassDecl);
-
- HasConstCopyConstructor = FieldClassDecl->hasConstCopyConstructor();
+ if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
+ LookupCopyConstructor(FieldClassDecl, Qualifiers::Const,
+ &HasConstCopyConstructor);
}
}
// Otherwise, the implicitly declared copy constructor will have
@@ -7114,11 +7077,8 @@
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- if (!BaseClassDecl->hasDeclaredCopyConstructor())
- DeclareImplicitCopyConstructor(BaseClassDecl);
-
- if (CXXConstructorDecl *CopyConstructor
- = BaseClassDecl->getCopyConstructor(Quals))
+ if (CXXConstructorDecl *CopyConstructor =
+ LookupCopyConstructor(BaseClassDecl, Quals))
ExceptSpec.CalledDecl(CopyConstructor);
}
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
@@ -7127,11 +7087,8 @@
++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- if (!BaseClassDecl->hasDeclaredCopyConstructor())
- DeclareImplicitCopyConstructor(BaseClassDecl);
-
- if (CXXConstructorDecl *CopyConstructor
- = BaseClassDecl->getCopyConstructor(Quals))
+ if (CXXConstructorDecl *CopyConstructor =
+ LookupCopyConstructor(BaseClassDecl, Quals))
ExceptSpec.CalledDecl(CopyConstructor);
}
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
@@ -7139,15 +7096,10 @@
Field != FieldEnd;
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
- if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
- CXXRecordDecl *FieldClassDecl
- = cast<CXXRecordDecl>(FieldClassType->getDecl());
- if (!FieldClassDecl->hasDeclaredCopyConstructor())
- DeclareImplicitCopyConstructor(FieldClassDecl);
-
- if (CXXConstructorDecl *CopyConstructor
- = FieldClassDecl->getCopyConstructor(Quals))
- ExceptSpec.CalledDecl(CopyConstructor);
+ if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
+ if (CXXConstructorDecl *CopyConstructor =
+ LookupCopyConstructor(FieldClassDecl, Quals))
+ ExceptSpec.CalledDecl(CopyConstructor);
}
}
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=132835&r1=132834&r2=132835&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Jun 9 23:44:37 2011
@@ -2303,13 +2303,29 @@
/// \brief Look up the default constructor for the given class.
CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) {
- SpecialMemberOverloadResult *Result =
+ SpecialMemberOverloadResult *Result =
LookupSpecialMember(Class, CXXDefaultConstructor, false, false, false,
false, false);
return cast_or_null<CXXConstructorDecl>(Result->getMethod());
}
+/// \brief Look up the copy constructor for the given class.
+CXXConstructorDecl *Sema::LookupCopyConstructor(CXXRecordDecl *Class,
+ unsigned Quals,
+ bool *ConstParamMatch) {
+ assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
+ "non-const, non-volatile qualifiers for copy ctor arg");
+ SpecialMemberOverloadResult *Result =
+ LookupSpecialMember(Class, CXXCopyConstructor, Quals & Qualifiers::Const,
+ Quals & Qualifiers::Volatile, false, false, false);
+
+ if (ConstParamMatch)
+ *ConstParamMatch = Result->hasConstParamMatch();
+
+ return cast_or_null<CXXConstructorDecl>(Result->getMethod());
+}
+
/// \brief Look up the constructors for the given class.
DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {
// If the implicit constructors have not yet been declared, do so now.
More information about the cfe-commits
mailing list