]> granicus.if.org Git - clang/commitdiff
Push overloaded function templates through the parser using a totally different
authorJohn McCall <rjmccall@apple.com>
Wed, 2 Dec 2009 08:04:21 +0000 (08:04 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 2 Dec 2009 08:04:21 +0000 (08:04 +0000)
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
include/clang/AST/TemplateName.h
lib/AST/ASTContext.cpp
lib/AST/TemplateName.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaTemplate.cpp

index 4f29e5d8a6182c32d0c51a32e6927614750853fa..6efb634a8c279ae170cd2aa2add0de5099786ca9 100644 (file)
@@ -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);
index 8ef8fb51416c8db9da9bfb42a440544626651b2f..aafe963811920b03cc2c8fc90c52088471a6e482 100644 (file)
@@ -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<TemplateDecl *, OverloadedFunctionDecl *,
+  typedef llvm::PointerUnion4<TemplateDecl *,
+                              OverloadedTemplateStorage *,
                               QualifiedTemplateName *,
                               DependentTemplateName *> 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<OverloadedTemplateStorage *>();
+  }
 
   /// \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<NamedDecl *>(Template)) { }
-
-  QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
-                        OverloadedFunctionDecl *Template)
-  : Qualifier(NNS, TemplateKeyword? 1 : 0),
-    Template(reinterpret_cast<NamedDecl *>(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);
index 6c9ecf089b986505938cdaf62d65b0adf5fa01de..a63db14a0f9b65c75006925350b8aa30de365c67 100644 (file)
@@ -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<TemplateDecl>(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<NamedDecl>(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<FunctionTemplateDecl>(D) ||
+           (isa<UsingShadowDecl>(D) &&
+            isa<FunctionTemplateDecl>(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);
index 5b4cf0ad94f660179fadb42eb2df1dda7618c836..b56c0cebfa5833bcf78e9b5fbabbe9998cc8a5c3 100644 (file)
@@ -29,25 +29,14 @@ TemplateDecl *TemplateName::getAsTemplateDecl() const {
   return 0;
 }
 
-OverloadedFunctionDecl *TemplateName::getAsOverloadedFunctionDecl() const {
-  if (OverloadedFunctionDecl *Ovl
-        = Storage.dyn_cast<OverloadedFunctionDecl *>())
-    return Ovl;
-
-  if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
-    return QTN->getOverloadedFunctionDecl();
-
-  return 0;
-}
-
 bool TemplateName::isDependent() const {
   if (TemplateDecl *Template = getAsTemplateDecl()) {
     return isa<TemplateTemplateParmDecl>(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<TemplateDecl *>())
     OS << Template->getNameAsString();
-  else if (OverloadedFunctionDecl *Ovl
-             = Storage.dyn_cast<OverloadedFunctionDecl *>())
-    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<TemplateDecl>(Template);
-}
-
-OverloadedFunctionDecl *
-QualifiedTemplateName::getOverloadedFunctionDecl() const {
-  return dyn_cast<OverloadedFunctionDecl>(Template);
-}
-
index b44d977b6a434612f2dc36d10ef0399a7c1e1ea5..c87899b7f83f533ba0d109875b43246e7a039875 100644 (file)
@@ -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);
     }
   }
   
index ae6ba321a22ef45e2bfda15459e7d8f75a7c393b..de1816c92b7eeb30c671d255b4bc2a5f3409d748 100644 (file)
@@ -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();
index 565581a138b2c507526de157b9d049646593dbd9..f5e5569f64cfe84c99d620b2c5b4003a2d665925 100644 (file)
@@ -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<NestedNameSpecifier *>(SS.getScopeRep());
-    if (OverloadedFunctionDecl *Ovl
-          = dyn_cast<OverloadedFunctionDecl>(Template))
-      TemplateResult
-        = TemplateTy::make(Context.getQualifiedTemplateName(Qualifier, false,
-                                                            Ovl));
-    else
-      TemplateResult
-        = TemplateTy::make(Context.getQualifiedTemplateName(Qualifier, false,
-                                                 cast<TemplateDecl>(Template)));
-  } else if (OverloadedFunctionDecl *Ovl
-               = dyn_cast<OverloadedFunctionDecl>(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<TemplateDecl>(Template)));
-  }
+    TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl());
 
-  if (isa<ClassTemplateDecl>(Template) ||
-      isa<TemplateTemplateParmDecl>(Template))
-    return TNK_Type_template;
+    if (SS.isSet() && !SS.isInvalid()) {
+      NestedNameSpecifier *Qualifier
+        = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+      Template = Context.getQualifiedTemplateName(Qualifier, false, TD);
+    } else {
+      Template = TemplateName(TD);
+    }
+
+    if (isa<FunctionTemplateDecl>(TD))
+      TemplateKind = TNK_Function_template;
+    else {
+      assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD));
+      TemplateKind = TNK_Type_template;
+    }
+  }
 
-  assert((isa<FunctionTemplateDecl>(Template) ||
-          isa<OverloadedFunctionDecl>(Template)) &&
-         "Unhandled template kind in Sema::isTemplateName");
-  return TNK_Function_template;  
+  TemplateResult = TemplateTy::make(Template);
+  return TemplateKind;
 }
 
 void Sema::LookupTemplateName(LookupResult &Found,