diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-07-01 17:57:27 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-07-01 17:57:27 +0000 | 
| commit | 54be33925ab9ff0d3428f462789b2c80c9f826ef (patch) | |
| tree | 9b3bba24cc717ac4d39aac59c073781d74dfb4ee /clang/lib/Sema/SemaDeclCXX.cpp | |
| parent | 68e1136585a4ffc2187c68f3a9a88115bd0ce0ae (diff) | |
| download | bcm5719-llvm-54be33925ab9ff0d3428f462789b2c80c9f826ef.tar.gz bcm5719-llvm-54be33925ab9ff0d3428f462789b2c80c9f826ef.zip | |
Move declaration of a class's implicit copy constructor into a
separate function. Aside from making the loops infinitely faster, no
functionality change.
llvm-svn: 107407
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 185 | 
1 files changed, 99 insertions, 86 deletions
| diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 9d18e177fd5..4b7015caec5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2692,92 +2692,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(Scope *S,        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 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,    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) { | 

