patch to mark use of implicit copy constructors.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73922 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 9628074..c9c6626 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -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,