[cfe-commits] r73922 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp

Douglas Gregor dgregor at apple.com
Tue Jun 23 13:52:51 PDT 2009


On Jun 22, 2009, at 4:34 PM, Fariborz Jahanian wrote:

> Author: fjahanian
> Date: Mon Jun 22 18:34:40 2009
> New Revision: 73922
>
> URL: http://llvm.org/viewvc/llvm-project?rev=73922&view=rev
> Log:
> patch to mark use of implicit copy constructors.
>
>
> Modified:
>    cfe/trunk/include/clang/AST/DeclCXX.h
>    cfe/trunk/lib/AST/DeclCXX.cpp
>    cfe/trunk/lib/Sema/Sema.h
>    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>    cfe/trunk/lib/Sema/SemaExpr.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=73922&r1=73921&r2=73922&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Jun 22 18:34:40 2009
> @@ -283,6 +283,10 @@
>   /// copy constructor that accepts a const-qualified argument.
>   bool hasConstCopyConstructor(ASTContext &Context) const;
>
> +  /// getCopyConstructor - Returns the copy constructor for this  
> class
> +  CXXConstructorDecl *getCopyConstructor(ASTContext &Context,
> +                                         unsigned TypeQuals) const;
> +
>   /// hasConstCopyAssignment - Determines whether this class has a
>   /// copy assignment operator that accepts a const-qualified  
> argument.
>   bool hasConstCopyAssignment(ASTContext &Context) const;
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=73922&r1=73921&r2=73922&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Jun 22 18:34:40 2009
> @@ -66,21 +66,29 @@
> }
>
> bool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context)  
> const {
> +  return getCopyConstructor(Context, QualType::Const) != 0;
> +}
> +
> +CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext  
> &Context,
> +                                                      unsigned  
> TypeQuals) const{
>   QualType ClassType
>     = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
>   DeclarationName ConstructorName
>     = Context.DeclarationNames.getCXXConstructorName(
> -                                           Context.getCanonicalType 
> (ClassType));
> -  unsigned TypeQuals;
> +                                          Context.getCanonicalType 
> (ClassType));
> +  unsigned FoundTQs;
>   DeclContext::lookup_const_iterator Con, ConEnd;
>   for (llvm::tie(Con, ConEnd) = this->lookup(Context,  
> ConstructorName);
>        Con != ConEnd; ++Con) {
> -    if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context,  
> TypeQuals) &&
> -        (TypeQuals & QualType::Const) != 0)
> -      return true;
> +    if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context,
> +                                                           
> FoundTQs)) {
> +      if (((TypeQuals & QualType::Const) == (FoundTQs &  
> QualType::Const)) ||
> +          (!(TypeQuals & QualType::Const) && (FoundTQs &  
> QualType::Const)))
> +        return cast<CXXConstructorDecl>(*Con);
> +
> +    }
>   }
> -
> -  return false;
> +  return 0;
> }

This looks like it's doing overload resolution... why not just use the  
existing overload-resolution code in Sema instead? (Or am I  
misunderstanding the role of this code?).

> bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context)  
> const {
>
> Modified: cfe/trunk/lib/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73922&r1=73921&r2=73922&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/Sema.h (original)
> +++ cfe/trunk/lib/Sema/Sema.h Mon Jun 22 18:34:40 2009
> @@ -1582,10 +1582,16 @@
>                                     QualType DeclInitType,
>                                     Expr **Exprs, unsigned NumExprs);
>
> -  /// DefineImplicitDefaultConstructor - Checks for feasibilityt of
> +  /// DefineImplicitDefaultConstructor - Checks for feasibility of
>   /// defining this constructor as the default constructor.
>   void DefineImplicitDefaultConstructor(SourceLocation  
> CurrentLocation,
>                                         CXXConstructorDecl  
> *Constructor);
> +
> +  /// DefineImplicitCopyConstructor - Checks for feasibility of
> +  /// defining this constructor as the copy constructor.
> +  void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
> +                                     CXXConstructorDecl *Constructor,
> +                                     unsigned TypeQuals);
>
>   /// MaybeBindToTemporary - If the passed in expression has a  
> record type with
>   /// a non-trivial destructor, this will return  
> CXXBindTemporaryExpr. Otherwise
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=73922&r1=73921&r2=73922&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jun 22 18:34:40 2009
> @@ -1878,7 +1878,7 @@
>
>   CXXRecordDecl *ClassDecl
>     = cast<CXXRecordDecl>(Constructor->getDeclContext());
> -  assert(ClassDecl && "InitializeVarWithConstructor - invalid  
> constructor");
> +  assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid  
> constructor");
>   // Before the implicitly-declared default constructor for a class is
>   // implicitly defined, all the implicitly-declared default  
> constructors
>   // for its base class and its non-static data members shall have  
> been
> @@ -1891,7 +1891,7 @@
>     if (!BaseClassDecl->hasTrivialConstructor()) {
>       if (CXXConstructorDecl *BaseCtor =
>             BaseClassDecl->getDefaultConstructor(Context)) {
> -        if (BaseCtor->isImplicit())
> +        if (BaseCtor->isImplicit() && !BaseCtor->isUsed())
>           MarkDeclarationReferenced(CurrentLocation, BaseCtor);
>       }
>       else {
> @@ -1916,7 +1916,7 @@
>       if (!FieldClassDecl->hasTrivialConstructor())
>         if (CXXConstructorDecl *FieldCtor =
>             FieldClassDecl->getDefaultConstructor(Context)) {
> -          if (FieldCtor->isImplicit())
> +          if (FieldCtor->isImplicit() && !FieldCtor->isUsed())
>             MarkDeclarationReferenced(CurrentLocation, FieldCtor);
>         }

We don't need the isImplicit or isUsed checks here; just call  
MarkDeclarationReferenced to note that will check that. (And, it might  
eventually be useful to know all of the uses of each declaration, for  
other tasks).

>         else {
> @@ -1945,6 +1945,48 @@
>     Constructor->setUsed();
> }
>
> +void Sema::DefineImplicitCopyConstructor(SourceLocation  
> CurrentLocation,
> +                                   CXXConstructorDecl  
> *CopyConstructor,
> +                                   unsigned TypeQuals) {
> +  assert((CopyConstructor->isImplicit() &&
> +          CopyConstructor->isCopyConstructor(Context, TypeQuals) &&
> +          !CopyConstructor->isUsed()) &&
> +         "DefineImplicitCopyConstructor - call it for implicit copy  
> ctor");
> +
> +  CXXRecordDecl *ClassDecl
> +    = cast<CXXRecordDecl>(CopyConstructor->getDeclContext());
> +  assert(ClassDecl && "DefineImplicitCopyConstructor - invalid  
> constructor");
> +  // Before the implicitly-declared copy constructor for a class is
> +  // implicitly defined, all the implicitly-declared copy  
> constructors
> +  // for its base class and its non-static data members shall have  
> been
> +  // implicitly defined.

Please add a reference to the paragraph in the standard when quoting  
it, so we know where to look for more information, e.g.,

   //  C++ [class.cdtor]p7:
   //    <quote from the standard goes here>

It's really great for

   http://t1.minormatter.com/~ddunbar/references.html


> +  for (CXXRecordDecl::base_class_iterator Base = ClassDecl- 
> >bases_begin();
> +       Base != ClassDecl->bases_end(); ++Base) {
> +    CXXRecordDecl *BaseClassDecl
> +      = cast<CXXRecordDecl>(Base->getType()->getAsRecordType()- 
> >getDecl());
> +    if (CXXConstructorDecl *BaseCopyCtor =
> +        BaseClassDecl->getCopyConstructor(Context, TypeQuals))
> +      if (BaseCopyCtor->isImplicit() && !BaseCopyCtor->isUsed())
> +        MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor);
> +  }

We don't need the isImplicit/isUsed checks here either.

> +  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin 
> (Context);
> +       Field != ClassDecl->field_end(Context);
> +       ++Field) {
> +    QualType FieldType = Context.getCanonicalType((*Field)->getType 
> ());
> +    if (const ArrayType *Array = Context.getAsArrayType(FieldType))
> +      FieldType = Array->getElementType();
> +    if (const RecordType *FieldClassType = FieldType- 
> >getAsRecordType()) {
> +      CXXRecordDecl *FieldClassDecl
> +        = cast<CXXRecordDecl>(FieldClassType->getDecl());
> +      if (CXXConstructorDecl *FieldCopyCtor =
> +          FieldClassDecl->getCopyConstructor(Context, TypeQuals))
> +          if (FieldCopyCtor->isImplicit() && !FieldCopyCtor->isUsed 
> ())
> +            MarkDeclarationReferenced(CurrentLocation,  
> FieldCopyCtor);
> +    }
> +  }
> +  CopyConstructor->setUsed();
> +}
> +
> void Sema::InitializeVarWithConstructor(VarDecl *VD,
>                                         CXXConstructorDecl  
> *Constructor,
>                                         QualType DeclInitType,
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=73922&r1=73921&r2=73922&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun 22 18:34:40 2009
> @@ -5515,10 +5515,16 @@
>
>   // Note that this declaration has been used.
>   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl> 
> (D)) {
> +    unsigned TypeQuals;
>     if (Constructor->isImplicit() && Constructor- 
> >isDefaultConstructor()) {
>         if (!Constructor->isUsed())
>           DefineImplicitDefaultConstructor(Loc, Constructor);
>     }
> +    else if (Constructor->isImplicit() &&
> +             Constructor->isCopyConstructor(Context, TypeQuals)) {
> +      if (!Constructor->isUsed())
> +        DefineImplicitCopyConstructor(Loc, Constructor, TypeQuals);
> +    }
>     // FIXME: more checking for other implicits go here.
>     else
>       Constructor->setUsed(true);


Okay.

	- Doug



More information about the cfe-commits mailing list