From: Douglas Gregor Date: Mon, 27 Sep 2010 21:17:54 +0000 (+0000) Subject: Clean up the handling of the DeclaredDefaultConstructor and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c0646b98b203d105c10ad8cc11be11cc99a4218;p=clang Clean up the handling of the DeclaredDefaultConstructor and DeclaredCopyConstructor bits in CXXRecordDecl's DefinitionData structure. Rather than having Sema call addedConstructor or set the bits directly at semi-random places, move all of the logic for managing these bits into CXXRecordDecl itself and tie the addedConstructor call into DeclContext::addDecl(). This makes it easier for AST-building clients to get the right bits set in DefinitionData, and is one small part of . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114889 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 16a9a553ac..da32239b75 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -404,6 +404,16 @@ class CXXRecordDecl : public RecordDecl { void CheckConversionFunction(NamedDecl *D); #endif + friend class DeclContext; + + /// \brief Notify the class that another constructor has + /// been added. + /// + /// This routine helps maintain information about the class based on which + /// constructors have been added. It will be invoked by DeclContext::addDecl() + /// whenever a constructor is added to this record. + void addedConstructor(CXXConstructorDecl *ConDecl); + protected: CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -558,12 +568,6 @@ public: return data().DeclaredDefaultConstructor; } - /// \brief Note whether this class has already had its default constructor - /// implicitly declared or doesn't need one. - void setDeclaredDefaultConstructor(bool DDC) { - data().DeclaredDefaultConstructor = DDC; - } - /// hasConstCopyConstructor - Determines whether this class has a /// copy constructor that accepts a const-qualified argument. bool hasConstCopyConstructor(ASTContext &Context) const; @@ -584,11 +588,6 @@ public: /// a unique copy-assignment operator could not be found. CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const; - /// addedConstructor - Notify the class that another constructor has - /// been added. This routine helps maintain information about the - /// class based on which constructors have been added. - void addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl); - /// hasUserDeclaredConstructor - Whether this class has any /// user-declared constructors. When true, a default constructor /// will not be implicitly declared. @@ -611,12 +610,6 @@ public: return data().DeclaredCopyConstructor; } - /// \brief Note whether this class has already had its copy constructor - /// declared. - void setDeclaredCopyConstructor(bool DCC) { - data().DeclaredCopyConstructor = DCC; - } - /// addedAssignmentOperator - Notify the class that another assignment /// operator has been added. This routine helps maintain information about the /// class based on which operators have been added. diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index f629722793..207edde592 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -778,6 +778,14 @@ void DeclContext::addHiddenDecl(Decl *D) { } else { FirstDecl = LastDecl = D; } + + if (CXXRecordDecl *Record = dyn_cast(this)) { + Decl *InnerD = D; + if (FunctionTemplateDecl *FunTmpl = dyn_cast(D)) + InnerD = FunTmpl->getTemplatedDecl(); + if (CXXConstructorDecl *Constructor = dyn_cast(InnerD)) + Record->addedConstructor(Constructor); + } } void DeclContext::addDecl(Decl *D) { diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 88301c2d9d..ffdb98d751 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -259,9 +259,25 @@ CXXMethodDecl *CXXRecordDecl::getCopyAssignmentOperator(bool ArgIsConst) const { } void -CXXRecordDecl::addedConstructor(ASTContext &Context, - CXXConstructorDecl *ConDecl) { - assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl"); +CXXRecordDecl::addedConstructor(CXXConstructorDecl *Constructor) { + // Ignore friends. + if (Constructor->getFriendObjectKind()) + return; + + if (Constructor->isImplicit()) { + // If this is the implicit default constructor, note that we have now + // declared it. + if (Constructor->isDefaultConstructor()) + data().DeclaredDefaultConstructor = true; + // If this is the implicit copy constructor, note that we have now + // declared it. + else if (Constructor->isCopyConstructor()) + data().DeclaredCopyConstructor = true; + + // Nothing else to do for implicitly-declared constructors. + return; + } + // Note that we have a user-declared constructor. data().UserDeclaredConstructor = true; @@ -285,7 +301,8 @@ CXXRecordDecl::addedConstructor(ASTContext &Context, // Note when we have a user-declared copy constructor, which will // suppress the implicit declaration of a copy constructor. - if (ConDecl->isCopyConstructor()) { + if (!Constructor->getDescribedFunctionTemplate() && + Constructor->isCopyConstructor()) { data().UserDeclaredCopyConstructor = true; data().DeclaredCopyConstructor = true; @@ -293,7 +310,6 @@ CXXRecordDecl::addedConstructor(ASTContext &Context, // A copy constructor is trivial if it is implicitly declared. // FIXME: C++0x: don't do this for "= default" copy constructors. data().HasTrivialCopyConstructor = false; - } } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b171d85ee0..025ac3bed9 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2985,13 +2985,6 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) { Constructor->setInvalidDecl(); } } - - // Notify the class that we've added a constructor. In principle we - // don't need to do this for out-of-line declarations; in practice - // we only instantiate the most recent declaration of a method, so - // we have to call this for everything but friends. - if (!Constructor->getFriendObjectKind()) - ClassDecl->addedConstructor(Context, Constructor); } /// CheckDestructor - Checks a fully-formed destructor definition for @@ -4441,7 +4434,6 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( DefaultCon->setTrivial(ClassDecl->hasTrivialConstructor()); // Note that we have declared this constructor. - ClassDecl->setDeclaredDefaultConstructor(true); ++ASTContext::NumImplicitDefaultConstructorsDeclared; if (Scope *S = getScopeForContext(ClassDecl)) @@ -5412,7 +5404,6 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( CopyConstructor->setTrivial(ClassDecl->hasTrivialCopyConstructor()); // Note that we have declared this constructor. - ClassDecl->setDeclaredCopyConstructor(true); ++ASTContext::NumImplicitCopyConstructorsDeclared; // Add the parameter to the constructor.