[cfe-commits] r107407 - in /cfe/trunk/lib/Sema: Sema.h SemaDeclCXX.cpp
Douglas Gregor
dgregor at apple.com
Thu Jul 1 10:57:27 PDT 2010
Author: dgregor
Date: Thu Jul 1 12:57:27 2010
New Revision: 107407
URL: http://llvm.org/viewvc/llvm-project?rev=107407&view=rev
Log:
Move declaration of a class's implicit copy constructor into a
separate function. Aside from making the loops infinitely faster, no
functionality change.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=107407&r1=107406&r2=107407&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Jul 1 12:57:27 2010
@@ -2230,6 +2230,18 @@
void DefineImplicitDestructor(SourceLocation CurrentLocation,
CXXDestructorDecl *Destructor);
+ /// \brief Declare the implicit copy constructor for the given class.
+ ///
+ /// \param S The scope of the class, which may be NULL if this is a
+ /// template instantiation.
+ ///
+ /// \param ClassDecl The class declaration into which the implicit
+ /// copy constructor will be added.
+ ///
+ /// \returns The implicitly-declared copy constructor.
+ CXXConstructorDecl *DeclareImplicitCopyConstructor(Scope *S,
+ CXXRecordDecl *ClassDecl);
+
/// DefineImplicitCopyConstructor - Checks for feasibility of
/// defining this constructor as the copy constructor.
void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=107407&r1=107406&r2=107407&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jul 1 12:57:27 2010
@@ -2692,92 +2692,8 @@
ClassDecl->addDecl(DefaultCon);
}
- if (!ClassDecl->hasUserDeclaredCopyConstructor()) {
- // C++ [class.copy]p4:
- // If the class definition does not explicitly declare a copy
- // constructor, one is declared implicitly.
-
- // C++ [class.copy]p5:
- // The implicitly-declared copy constructor for a class X will
- // have the form
- //
- // X::X(const X&)
- //
- // if
- bool HasConstCopyConstructor = true;
-
- // -- each direct or virtual base class B of X has a copy
- // constructor whose first parameter is of type const B& or
- // const volatile B&, and
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- HasConstCopyConstructor && Base != ClassDecl->bases_end(); ++Base) {
- const CXXRecordDecl *BaseClassDecl
- = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- HasConstCopyConstructor
- = BaseClassDecl->hasConstCopyConstructor(Context);
- }
-
- // -- for all the nonstatic data members of X that are of a
- // class type M (or array thereof), each such class type
- // has a copy constructor whose first parameter is of type
- // const M& or const volatile M&.
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin();
- HasConstCopyConstructor && Field != ClassDecl->field_end();
- ++Field) {
- QualType FieldType = (*Field)->getType();
- if (const ArrayType *Array = Context.getAsArrayType(FieldType))
- FieldType = Array->getElementType();
- if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
- const CXXRecordDecl *FieldClassDecl
- = cast<CXXRecordDecl>(FieldClassType->getDecl());
- HasConstCopyConstructor
- = FieldClassDecl->hasConstCopyConstructor(Context);
- }
- }
-
- // Otherwise, the implicitly declared copy constructor will have
- // the form
- //
- // X::X(X&)
- QualType ArgType = ClassType;
- if (HasConstCopyConstructor)
- ArgType = ArgType.withConst();
- ArgType = Context.getLValueReferenceType(ArgType);
-
- // An implicitly-declared copy constructor is an inline public
- // member of its class.
- DeclarationName Name
- = Context.DeclarationNames.getCXXConstructorName(ClassType);
- CXXConstructorDecl *CopyConstructor
- = CXXConstructorDecl::Create(Context, ClassDecl,
- ClassDecl->getLocation(), Name,
- Context.getFunctionType(Context.VoidTy,
- &ArgType, 1,
- false, 0,
- /*FIXME: hasExceptionSpec*/false,
- false, 0, 0,
- FunctionType::ExtInfo()),
- /*TInfo=*/0,
- /*isExplicit=*/false,
- /*isInline=*/true,
- /*isImplicitlyDeclared=*/true);
- CopyConstructor->setAccess(AS_public);
- CopyConstructor->setImplicit();
- CopyConstructor->setTrivial(ClassDecl->hasTrivialCopyConstructor());
-
- // Add the parameter to the constructor.
- ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
- ClassDecl->getLocation(),
- /*IdentifierInfo=*/0,
- ArgType, /*TInfo=*/0,
- VarDecl::None,
- VarDecl::None, 0);
- CopyConstructor->setParams(&FromParam, 1);
- if (S)
- PushOnScopeChains(CopyConstructor, S, true);
- else
- ClassDecl->addDecl(CopyConstructor);
- }
+ if (!ClassDecl->hasUserDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(S, ClassDecl);
if (!ClassDecl->hasUserDeclaredCopyAssignment())
DeclareImplicitCopyAssignment(S, ClassDecl);
@@ -4993,6 +4909,103 @@
CopyAssignOperator->setBody(Body.takeAs<Stmt>());
}
+CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S,
+ CXXRecordDecl *ClassDecl) {
+ // C++ [class.copy]p4:
+ // If the class definition does not explicitly declare a copy
+ // constructor, one is declared implicitly.
+
+ // FIXME: virtual bases!
+
+ // C++ [class.copy]p5:
+ // The implicitly-declared copy constructor for a class X will
+ // have the form
+ //
+ // X::X(const X&)
+ //
+ // if
+ bool HasConstCopyConstructor = true;
+
+ // -- each direct or virtual base class B of X has a copy
+ // constructor whose first parameter is of type const B& or
+ // const volatile B&, and
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ BaseEnd = ClassDecl->bases_end();
+ HasConstCopyConstructor && Base != BaseEnd;
+ ++Base) {
+ const CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ HasConstCopyConstructor
+ = BaseClassDecl->hasConstCopyConstructor(Context);
+ }
+
+ // -- for all the nonstatic data members of X that are of a
+ // class type M (or array thereof), each such class type
+ // has a copy constructor whose first parameter is of type
+ // const M& or const volatile M&.
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ HasConstCopyConstructor && Field != FieldEnd;
+ ++Field) {
+ QualType FieldType = (*Field)->getType();
+ if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+ FieldType = Array->getElementType();
+ if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ const CXXRecordDecl *FieldClassDecl
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ HasConstCopyConstructor
+ = FieldClassDecl->hasConstCopyConstructor(Context);
+ }
+ }
+
+ // Otherwise, the implicitly declared copy constructor will have
+ // the form
+ //
+ // X::X(X&)
+ QualType ClassType = Context.getTypeDeclType(ClassDecl);
+ QualType ArgType = ClassType;
+ if (HasConstCopyConstructor)
+ ArgType = ArgType.withConst();
+ ArgType = Context.getLValueReferenceType(ArgType);
+
+ // An implicitly-declared copy constructor is an inline public
+ // member of its class.
+ DeclarationName Name
+ = Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(ClassType));
+ CXXConstructorDecl *CopyConstructor
+ = CXXConstructorDecl::Create(Context, ClassDecl,
+ ClassDecl->getLocation(), Name,
+ Context.getFunctionType(Context.VoidTy,
+ &ArgType, 1,
+ false, 0,
+ /*FIXME: hasExceptionSpec*/false,
+ false, 0, 0,
+ FunctionType::ExtInfo()),
+ /*TInfo=*/0,
+ /*isExplicit=*/false,
+ /*isInline=*/true,
+ /*isImplicitlyDeclared=*/true);
+ CopyConstructor->setAccess(AS_public);
+ CopyConstructor->setImplicit();
+ CopyConstructor->setTrivial(ClassDecl->hasTrivialCopyConstructor());
+
+ // Add the parameter to the constructor.
+ ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
+ ClassDecl->getLocation(),
+ /*IdentifierInfo=*/0,
+ ArgType, /*TInfo=*/0,
+ VarDecl::None,
+ VarDecl::None, 0);
+ CopyConstructor->setParams(&FromParam, 1);
+ if (S)
+ PushOnScopeChains(CopyConstructor, S, true);
+ else
+ ClassDecl->addDecl(CopyConstructor);
+
+ return CopyConstructor;
+}
+
void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
CXXConstructorDecl *CopyConstructor,
unsigned TypeQuals) {
More information about the cfe-commits
mailing list