[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

Fariborz Jahanian fjahanian at apple.com
Mon Jun 22 16:34:40 PDT 2009


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;
 }
 
 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);
         }
         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.
+  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);
+  }
+  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);





More information about the cfe-commits mailing list