From 0bd6feb9e9d40fc889fd47e899985125a43dfed8 Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 2 Dec 2009 08:04:21 +0000 Subject: [PATCH] Push overloaded function templates through the parser using a totally different leaked data structure than before. This kills off the last remaining explicit uses of OverloadedFunctionDecl in Sema. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90306 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 6 +-- include/clang/AST/TemplateName.h | 69 ++++++++++++++++++++------------ lib/AST/ASTContext.cpp | 63 +++++++++++------------------ lib/AST/TemplateName.cpp | 28 +------------ lib/Sema/SemaDecl.cpp | 9 +---- lib/Sema/SemaExpr.cpp | 6 +-- lib/Sema/SemaTemplate.cpp | 54 ++++++++++++------------- 7 files changed, 105 insertions(+), 130 deletions(-) diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 4f29e5d8a6..6efb634a8c 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -735,12 +735,12 @@ public: DeclarationName getNameForTemplate(TemplateName Name); + TemplateName getOverloadedTemplateName(NamedDecl * const *Begin, + NamedDecl * const *End); + TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateDecl *Template); - TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, - bool TemplateKeyword, - OverloadedFunctionDecl *Template); TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, const IdentifierInfo *Name); diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 8ef8fb5141..aafe963811 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -31,7 +31,34 @@ struct PrintingPolicy; class QualifiedTemplateName; class NamedDecl; class TemplateDecl; -class OverloadedFunctionDecl; + +/// \brief A structure for storing the information associated with an +/// overloaded template name. +class OverloadedTemplateStorage { + union { + unsigned Size; + NamedDecl *Storage[1]; + }; + + friend class ASTContext; + + OverloadedTemplateStorage(unsigned Size) : Size(Size) {} + + NamedDecl **getStorage() { + return &Storage[1]; + } + NamedDecl * const *getStorage() const { + return &Storage[1]; + } + +public: + typedef NamedDecl *const *iterator; + + unsigned size() const { return Size; } + + iterator begin() const { return getStorage(); } + iterator end() const { return getStorage() + size(); } +}; /// \brief Represents a C++ template name within the type system. /// @@ -61,7 +88,8 @@ class OverloadedFunctionDecl; /// specifier in the typedef. "apply" is a nested template, and can /// only be understood in the context of class TemplateName { - typedef llvm::PointerUnion4 StorageType; @@ -74,8 +102,8 @@ class TemplateName { public: TemplateName() : Storage() { } explicit TemplateName(TemplateDecl *Template) : Storage(Template) { } - explicit TemplateName(OverloadedFunctionDecl *FunctionTemplates) - : Storage(FunctionTemplates) { } + explicit TemplateName(OverloadedTemplateStorage *Storage) + : Storage(Storage) { } explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { } explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { } @@ -98,7 +126,9 @@ public: /// name refers to, if known. If the template name does not refer to a /// specific set of function templates because it is a dependent name or /// refers to a single template, returns NULL. - OverloadedFunctionDecl *getAsOverloadedFunctionDecl() const; + OverloadedTemplateStorage *getAsOverloadedTemplate() const { + return Storage.dyn_cast(); + } /// \brief Retrieve the underlying qualified template name /// structure, if any. @@ -166,19 +196,14 @@ class QualifiedTemplateName : public llvm::FoldingSetNode { /// \brief The template declaration or set of overloaded function templates /// that this qualified name refers to. - NamedDecl *Template; + TemplateDecl *Template; friend class ASTContext; QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateDecl *Template) : Qualifier(NNS, TemplateKeyword? 1 : 0), - Template(reinterpret_cast(Template)) { } - - QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, - OverloadedFunctionDecl *Template) - : Qualifier(NNS, TemplateKeyword? 1 : 0), - Template(reinterpret_cast(Template)) { } + Template(Template) { } public: /// \brief Return the nested name specifier that qualifies this name. @@ -188,26 +213,20 @@ public: /// keyword. bool hasTemplateKeyword() const { return Qualifier.getInt(); } - /// \brief The template declaration or set of overloaded functions that - /// that qualified name refers to. - NamedDecl *getDecl() const { return Template; } + /// \brief The template declaration that this qualified name refers + /// to. + TemplateDecl *getDecl() const { return Template; } /// \brief The template declaration to which this qualified name - /// refers, or NULL if this qualified name refers to a set of overloaded - /// function templates. - TemplateDecl *getTemplateDecl() const; - - /// \brief The set of overloaded function tempaltes to which this qualified - /// name refers, or NULL if this qualified name refers to a single - /// template declaration. - OverloadedFunctionDecl *getOverloadedFunctionDecl() const; + /// refers. + TemplateDecl *getTemplateDecl() const { return Template; } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getQualifier(), hasTemplateKeyword(), getDecl()); + Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl()); } static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, - bool TemplateKeyword, NamedDecl *Template) { + bool TemplateKeyword, TemplateDecl *Template) { ID.AddPointer(NNS); ID.AddBoolean(TemplateKeyword); ID.AddPointer(Template); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 6c9ecf089b..a63db14a0f 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2354,8 +2354,9 @@ DeclarationName ASTContext::getNameForTemplate(TemplateName Name) { } } - assert(Name.getAsOverloadedFunctionDecl()); - return Name.getAsOverloadedFunctionDecl()->getDeclName(); + OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate(); + assert(Storage); + return (*Storage->begin())->getDeclName(); } TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) { @@ -2364,27 +2365,7 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) { if (TemplateDecl *Template = Name.getAsTemplateDecl()) return TemplateName(cast(Template->getCanonicalDecl())); - // If this template name refers to a set of overloaded function templates, - /// the canonical template name merely stores the set of function templates. - if (OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl()) { - OverloadedFunctionDecl *CanonOvl = 0; - for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), - FEnd = Ovl->function_end(); - F != FEnd; ++F) { - Decl *Canon = F->get()->getCanonicalDecl(); - if (CanonOvl || Canon != F->get()) { - if (!CanonOvl) - CanonOvl = OverloadedFunctionDecl::Create(*this, - Ovl->getDeclContext(), - Ovl->getDeclName()); - - CanonOvl->addOverload( - AnyFunctionDecl::getFromNamedDecl(cast(Canon))); - } - } - - return TemplateName(CanonOvl? CanonOvl : Ovl); - } + assert(!Name.getAsOverloadedTemplate()); DependentTemplateName *DTN = Name.getAsDependentTemplateName(); assert(DTN && "Non-dependent template names must refer to template decls."); @@ -3690,36 +3671,40 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) { ObjCConstantStringType = getObjCInterfaceType(Decl); } -/// \brief Retrieve the template name that represents a qualified -/// template name such as \c std::vector. -TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, - bool TemplateKeyword, - TemplateDecl *Template) { - llvm::FoldingSetNodeID ID; - QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template); +/// \brief Retrieve the template name that corresponds to a non-empty +/// lookup. +TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin, + NamedDecl * const *End) { + unsigned size = End - Begin; + assert(size > 1 && "set is not overloaded!"); - void *InsertPos = 0; - QualifiedTemplateName *QTN = - QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos); - if (!QTN) { - QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template); - QualifiedTemplateNames.InsertNode(QTN, InsertPos); + void *memory = Allocate(sizeof(OverloadedTemplateStorage) + + size * sizeof(FunctionTemplateDecl*)); + OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size); + + NamedDecl **Storage = OT->getStorage(); + for (NamedDecl * const *I = Begin; I != End; ++I) { + NamedDecl *D = *I; + assert(isa(D) || + (isa(D) && + isa(D->getUnderlyingDecl()))); + *Storage++ = D; } - return TemplateName(QTN); + return TemplateName(OT); } /// \brief Retrieve the template name that represents a qualified /// template name such as \c std::vector. TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, - OverloadedFunctionDecl *Template) { + TemplateDecl *Template) { llvm::FoldingSetNodeID ID; QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template); void *InsertPos = 0; QualifiedTemplateName *QTN = - QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos); + QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos); if (!QTN) { QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template); QualifiedTemplateNames.InsertNode(QTN, InsertPos); diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp index 5b4cf0ad94..b56c0cebfa 100644 --- a/lib/AST/TemplateName.cpp +++ b/lib/AST/TemplateName.cpp @@ -29,25 +29,14 @@ TemplateDecl *TemplateName::getAsTemplateDecl() const { return 0; } -OverloadedFunctionDecl *TemplateName::getAsOverloadedFunctionDecl() const { - if (OverloadedFunctionDecl *Ovl - = Storage.dyn_cast()) - return Ovl; - - if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) - return QTN->getOverloadedFunctionDecl(); - - return 0; -} - bool TemplateName::isDependent() const { if (TemplateDecl *Template = getAsTemplateDecl()) { return isa(Template) || Template->getDeclContext()->isDependentContext(); } - if (OverloadedFunctionDecl *Ovl = getAsOverloadedFunctionDecl()) - return Ovl->getDeclContext()->isDependentContext(); + assert(!getAsOverloadedTemplate() && + "overloaded templates shouldn't survive to here"); return true; } @@ -57,9 +46,6 @@ TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS) const { if (TemplateDecl *Template = Storage.dyn_cast()) OS << Template->getNameAsString(); - else if (OverloadedFunctionDecl *Ovl - = Storage.dyn_cast()) - OS << Ovl->getNameAsString(); else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { if (!SuppressNNS) QTN->getQualifier()->print(OS, Policy); @@ -84,13 +70,3 @@ void TemplateName::dump() const { LO.Bool = true; print(llvm::errs(), PrintingPolicy(LO)); } - -TemplateDecl *QualifiedTemplateName::getTemplateDecl() const { - return dyn_cast(Template); -} - -OverloadedFunctionDecl * -QualifiedTemplateName::getOverloadedFunctionDecl() const { - return dyn_cast(Template); -} - diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index b44d977b6a..c87899b7f8 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1765,13 +1765,8 @@ DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { case UnqualifiedId::IK_TemplateId: { TemplateName TName - = TemplateName::getFromVoidPointer(Name.TemplateId->Template); - if (TemplateDecl *Template = TName.getAsTemplateDecl()) - return Template->getDeclName(); - if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl()) - return Ovl->getDeclName(); - - return DeclarationName(); + = TemplateName::getFromVoidPointer(Name.TemplateId->Template); + return Context.getNameForTemplate(TName); } } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ae6ba321a2..de1816c92b 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -665,9 +665,9 @@ static void DecomposeTemplateName(LookupResult &R, const UnqualifiedId &Id) { if (TemplateDecl *TD = TName.getAsTemplateDecl()) R.addDecl(TD); - else if (OverloadedFunctionDecl *OD - = TName.getAsOverloadedFunctionDecl()) - for (OverloadIterator I(OD), E; I != E; ++I) + else if (OverloadedTemplateStorage *OT = TName.getAsOverloadedTemplate()) + for (OverloadedTemplateStorage::iterator I = OT->begin(), E = OT->end(); + I != E; ++I) R.addDecl(*I); R.resolveKind(); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 565581a138..f5e5569f64 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -108,36 +108,36 @@ TemplateNameKind Sema::isTemplateName(Scope *S, if (R.empty()) return TNK_Non_template; - NamedDecl *Template = R.getAsSingleDecl(Context); - - if (SS.isSet() && !SS.isInvalid()) { - NestedNameSpecifier *Qualifier - = static_cast(SS.getScopeRep()); - if (OverloadedFunctionDecl *Ovl - = dyn_cast(Template)) - TemplateResult - = TemplateTy::make(Context.getQualifiedTemplateName(Qualifier, false, - Ovl)); - else - TemplateResult - = TemplateTy::make(Context.getQualifiedTemplateName(Qualifier, false, - cast(Template))); - } else if (OverloadedFunctionDecl *Ovl - = dyn_cast(Template)) { - TemplateResult = TemplateTy::make(TemplateName(Ovl)); + TemplateName Template; + TemplateNameKind TemplateKind; + + unsigned ResultCount = R.end() - R.begin(); + if (ResultCount > 1) { + // We assume that we'll preserve the qualifier from a function + // template name in other ways. + Template = Context.getOverloadedTemplateName(R.begin(), R.end()); + TemplateKind = TNK_Function_template; } else { - TemplateResult = TemplateTy::make( - TemplateName(cast(Template))); - } + TemplateDecl *TD = cast((*R.begin())->getUnderlyingDecl()); - if (isa(Template) || - isa(Template)) - return TNK_Type_template; + if (SS.isSet() && !SS.isInvalid()) { + NestedNameSpecifier *Qualifier + = static_cast(SS.getScopeRep()); + Template = Context.getQualifiedTemplateName(Qualifier, false, TD); + } else { + Template = TemplateName(TD); + } + + if (isa(TD)) + TemplateKind = TNK_Function_template; + else { + assert(isa(TD) || isa(TD)); + TemplateKind = TNK_Type_template; + } + } - assert((isa(Template) || - isa(Template)) && - "Unhandled template kind in Sema::isTemplateName"); - return TNK_Function_template; + TemplateResult = TemplateTy::make(Template); + return TemplateKind; } void Sema::LookupTemplateName(LookupResult &Found, -- 2.40.0