Author: Erich Keane Date: 2022-07-22T12:37:14-07:00 New Revision: 3ff86f961094306d1a3f219a44614e9cfd1dbd6b
URL: https://github.com/llvm/llvm-project/commit/3ff86f961094306d1a3f219a44614e9cfd1dbd6b DIFF: https://github.com/llvm/llvm-project/commit/3ff86f961094306d1a3f219a44614e9cfd1dbd6b.diff LOG: [NFC] Start saving InstantiatedFromDecl in non-template functions In cases where a non-template function is defined inside a function template, we don't have information about the original uninstantiated version. In the case of concepts instantiation, we will need the ability to get back to the original template. This patch splits a piece of the deferred concepts instantaition patch off to accomplish the storage of this, with minor runtime overhead, and zero additional storage. Added: Modified: clang/include/clang/AST/Decl.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/Decl.cpp clang/lib/ExtractAPI/ExtractAPIConsumer.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTWriterDecl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 66fab94b45b8..fb87a75a1241 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1890,7 +1890,10 @@ class FunctionDecl : public DeclaratorDecl, TK_FunctionTemplateSpecialization, // A function template specialization that hasn't yet been resolved to a // particular specialized function template. - TK_DependentFunctionTemplateSpecialization + TK_DependentFunctionTemplateSpecialization, + // A non-template function which is in a dependent scope. + TK_DependentNonTemplate + }; /// Stashed information about a defaulted function definition whose body has @@ -1939,20 +1942,21 @@ class FunctionDecl : public DeclaratorDecl, /// The template or declaration that this declaration /// describes or was instantiated from, respectively. /// - /// For non-templates, this value will be NULL. For function - /// declarations that describe a function template, this will be a - /// pointer to a FunctionTemplateDecl. For member functions - /// of class template specializations, this will be a MemberSpecializationInfo + /// For non-templates this value will be NULL, unless this declaration was + /// declared directly inside of a function template, in which case it will + /// have a pointer to a FunctionDecl, stored in the NamedDecl. For function + /// declarations that describe a function template, this will be a pointer to + /// a FunctionTemplateDecl, stored in the NamedDecl. For member functions of + /// class template specializations, this will be a MemberSpecializationInfo /// pointer containing information about the specialization. /// For function template specializations, this will be a /// FunctionTemplateSpecializationInfo, which contains information about /// the template being specialized and the template arguments involved in /// that specialization. - llvm::PointerUnion<FunctionTemplateDecl *, - MemberSpecializationInfo *, + llvm::PointerUnion<NamedDecl *, MemberSpecializationInfo *, FunctionTemplateSpecializationInfo *, DependentFunctionTemplateSpecializationInfo *> - TemplateOrSpecialization; + TemplateOrSpecialization; /// Provides source/type location info for the declaration name embedded in /// the DeclaratorDecl base class. @@ -2695,6 +2699,13 @@ class FunctionDecl : public DeclaratorDecl, setInstantiationOfMemberFunction(getASTContext(), FD, TSK); } + /// Specify that this function declaration was instantiated from a + /// FunctionDecl FD. This is only used if this is a function declaration + /// declared locally inside of a function template. + void setInstantiatedFromDecl(FunctionDecl *FD); + + FunctionDecl *getInstantiatedFromDecl() const; + /// Retrieves the function template that is described by this /// function declaration. /// diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 73c3f02e67a8..f7e7b73d1218 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3109,6 +3109,11 @@ Error ASTNodeImporter::ImportTemplateInformation( case FunctionDecl::TK_FunctionTemplate: return Error::success(); + case FunctionDecl::TK_DependentNonTemplate: + if (Expected<FunctionDecl *> InstFDOrErr = + import(FromFD->getInstantiatedFromDecl())) + ToFD->setInstantiatedFromDecl(*InstFDOrErr); + return Error::success(); case FunctionDecl::TK_MemberSpecialization: { TemplateSpecializationKind TSK = FromFD->getTemplateSpecializationKind(); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 5e5101203e6c..f88a2e3fa268 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3732,8 +3732,13 @@ const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const { FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const { if (TemplateOrSpecialization.isNull()) return TK_NonTemplate; - if (TemplateOrSpecialization.is<FunctionTemplateDecl *>()) + if (const auto *ND = TemplateOrSpecialization.dyn_cast<NamedDecl *>()) { + if (isa<FunctionDecl>(ND)) + return TK_DependentNonTemplate; + assert(isa<FunctionTemplateDecl>(ND) && + "No other valid types in NamedDecl"); return TK_FunctionTemplate; + } if (TemplateOrSpecialization.is<MemberSpecializationInfo *>()) return TK_MemberSpecialization; if (TemplateOrSpecialization.is<FunctionTemplateSpecializationInfo *>()) @@ -3774,15 +3779,28 @@ FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C, } FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const { - return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl *>(); + return dyn_cast_or_null<FunctionTemplateDecl>( + TemplateOrSpecialization.dyn_cast<NamedDecl *>()); } -void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) { +void FunctionDecl::setDescribedFunctionTemplate( + FunctionTemplateDecl *Template) { assert(TemplateOrSpecialization.isNull() && "Member function is already a specialization"); TemplateOrSpecialization = Template; } +void FunctionDecl::setInstantiatedFromDecl(FunctionDecl *FD) { + assert(TemplateOrSpecialization.isNull() && + "Function is already a specialization"); + TemplateOrSpecialization = FD; +} + +FunctionDecl *FunctionDecl::getInstantiatedFromDecl() const { + return dyn_cast_or_null<FunctionDecl>( + TemplateOrSpecialization.dyn_cast<NamedDecl *>()); +} + bool FunctionDecl::isImplicitlyInstantiable() const { // If the function is invalid, it can't be implicitly instantiated. if (isInvalidDecl()) diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index bffa66c2d944..1a785182e363 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -303,6 +303,7 @@ class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> { // Skip templated functions. switch (Decl->getTemplatedKind()) { case FunctionDecl::TK_NonTemplate: + case FunctionDecl::TK_DependentNonTemplate: break; case FunctionDecl::TK_MemberSpecialization: case FunctionDecl::TK_FunctionTemplateSpecialization: diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index bd166ff6f594..9bf6ca1f8084 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2182,6 +2182,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( // definition. We don't want non-template functions to be marked as being // template instantiations. Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); + } else if (!isFriend) { + // If this is not a function template, and this is not a friend (that is, + // this is a locally declared function), save the instantiation relationship + // for the purposes of constraint instantiation. + Function->setInstantiatedFromDecl(D); } if (isFriend) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b4506da2bb2b..d70e824224df 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -953,6 +953,10 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { case FunctionDecl::TK_NonTemplate: mergeRedeclarable(FD, Redecl); break; + case FunctionDecl::TK_DependentNonTemplate: + mergeRedeclarable(FD, Redecl); + FD->setInstantiatedFromDecl(readDeclAs<FunctionDecl>()); + break; case FunctionDecl::TK_FunctionTemplate: // Merged when we merge the template. FD->setDescribedFunctionTemplate(readDeclAs<FunctionTemplateDecl>()); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 01f692c9611b..35b8db27bd0e 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -585,6 +585,9 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { switch (D->getTemplatedKind()) { case FunctionDecl::TK_NonTemplate: break; + case FunctionDecl::TK_DependentNonTemplate: + Record.AddDeclRef(D->getInstantiatedFromDecl()); + break; case FunctionDecl::TK_FunctionTemplate: Record.AddDeclRef(D->getDescribedFunctionTemplate()); break; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits