summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp41
-rw-r--r--clang/lib/Sema/SemaLookup.cpp30
2 files changed, 53 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 93caad669d9..5c98e2b1db2 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2657,7 +2657,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
DeclareImplicitDefaultConstructor(ClassDecl);
if (!ClassDecl->hasUserDeclaredCopyConstructor())
- DeclareImplicitCopyConstructor(ClassDecl);
+ ++ASTContext::NumImplicitCopyConstructors;
if (!ClassDecl->hasUserDeclaredCopyAssignment()) {
++ASTContext::NumImplicitCopyAssignmentOperators;
@@ -5065,8 +5065,11 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
if (Base->isVirtual())
continue;
- const CXXRecordDecl *BaseClassDecl
+ CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (!BaseClassDecl->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(BaseClassDecl);
+
HasConstCopyConstructor
= BaseClassDecl->hasConstCopyConstructor(Context);
}
@@ -5075,8 +5078,11 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
BaseEnd = ClassDecl->vbases_end();
HasConstCopyConstructor && Base != BaseEnd;
++Base) {
- const CXXRecordDecl *BaseClassDecl
+ CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (!BaseClassDecl->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(BaseClassDecl);
+
HasConstCopyConstructor
= BaseClassDecl->hasConstCopyConstructor(Context);
}
@@ -5091,8 +5097,11 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
- const CXXRecordDecl *FieldClassDecl
+ CXXRecordDecl *FieldClassDecl
= cast<CXXRecordDecl>(FieldClassType->getDecl());
+ if (!FieldClassDecl->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(FieldClassDecl);
+
HasConstCopyConstructor
= FieldClassDecl->hasConstCopyConstructor(Context);
}
@@ -5121,8 +5130,11 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
if (Base->isVirtual())
continue;
- const CXXRecordDecl *BaseClassDecl
+ CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (!BaseClassDecl->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(BaseClassDecl);
+
if (CXXConstructorDecl *CopyConstructor
= BaseClassDecl->getCopyConstructor(Context, Quals))
ExceptSpec.CalledDecl(CopyConstructor);
@@ -5131,8 +5143,11 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
BaseEnd = ClassDecl->vbases_end();
Base != BaseEnd;
++Base) {
- const CXXRecordDecl *BaseClassDecl
+ CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (!BaseClassDecl->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(BaseClassDecl);
+
if (CXXConstructorDecl *CopyConstructor
= BaseClassDecl->getCopyConstructor(Context, Quals))
ExceptSpec.CalledDecl(CopyConstructor);
@@ -5143,8 +5158,11 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
- const CXXRecordDecl *FieldClassDecl
+ CXXRecordDecl *FieldClassDecl
= cast<CXXRecordDecl>(FieldClassType->getDecl());
+ if (!FieldClassDecl->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(FieldClassDecl);
+
if (CXXConstructorDecl *CopyConstructor
= FieldClassDecl->getCopyConstructor(Context, Quals))
ExceptSpec.CalledDecl(CopyConstructor);
@@ -5175,6 +5193,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
CopyConstructor->setImplicit();
CopyConstructor->setTrivial(ClassDecl->hasTrivialCopyConstructor());
+ // Note that we have declared this constructor.
+ ClassDecl->setDeclaredCopyConstructor(true);
+ ++ASTContext::NumImplicitCopyConstructorsDeclared;
+
// Add the parameter to the constructor.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
ClassDecl->getLocation(),
@@ -5184,9 +5206,8 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
VarDecl::None, 0);
CopyConstructor->setParams(&FromParam, 1);
if (Scope *S = getScopeForContext(ClassDecl))
- PushOnScopeChains(CopyConstructor, S, true);
- else
- ClassDecl->addDecl(CopyConstructor);
+ PushOnScopeChains(CopyConstructor, S, false);
+ ClassDecl->addDecl(CopyConstructor);
return CopyConstructor;
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6d590893bdc..b13deec19ab 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -464,14 +464,19 @@ static bool CanDeclareSpecialMemberFunction(ASTContext &Context,
}
void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class) {
+ if (!CanDeclareSpecialMemberFunction(Context, Class))
+ return;
+
+ // If the copy constructor has not yet been declared, do so now.
+ if (!Class->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(Class);
+
// If the copy assignment operator has not yet been declared, do so now.
- if (CanDeclareSpecialMemberFunction(Context, Class) &&
- !Class->hasDeclaredCopyAssignment())
+ if (!Class->hasDeclaredCopyAssignment())
DeclareImplicitCopyAssignment(Class);
// If the destructor has not yet been declared, do so now.
- if (CanDeclareSpecialMemberFunction(Context, Class) &&
- !Class->hasDeclaredDestructor())
+ if (!Class->hasDeclaredDestructor())
DeclareImplicitDestructor(Class);
}
@@ -479,6 +484,7 @@ void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class) {
/// special member function.
static bool isImplicitlyDeclaredMemberFunctionName(DeclarationName Name) {
switch (Name.getNameKind()) {
+ case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
return true;
@@ -501,12 +507,18 @@ static void DeclareImplicitMemberFunctionsWithName(Sema &S,
return;
switch (Name.getNameKind()) {
+ case DeclarationName::CXXConstructorName:
+ if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
+ if (Record->getDefinition() && !Record->hasDeclaredCopyConstructor() &&
+ CanDeclareSpecialMemberFunction(S.Context, Record))
+ S.DeclareImplicitCopyConstructor(const_cast<CXXRecordDecl *>(Record));
+ break;
+
case DeclarationName::CXXDestructorName:
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))
if (Record->getDefinition() && !Record->hasDeclaredDestructor() &&
CanDeclareSpecialMemberFunction(S.Context, Record))
S.DeclareImplicitDestructor(const_cast<CXXRecordDecl *>(Record));
-
break;
case DeclarationName::CXXOperatorName:
@@ -1992,9 +2004,11 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
/// \brief Look up the constructors for the given class.
DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {
- if (!Class->getDefinition())
- return DeclContext::lookup_result();
-
+ // If the copy constructor has not yet been declared, do so now.
+ if (CanDeclareSpecialMemberFunction(Context, Class) &&
+ !Class->hasDeclaredCopyConstructor())
+ DeclareImplicitCopyConstructor(Class);
+
CanQualType T = Context.getCanonicalType(Context.getTypeDeclType(Class));
DeclarationName Name = Context.DeclarationNames.getCXXConstructorName(T);
return Class->lookup(Name);
OpenPOWER on IntegriCloud