[cfe-commits] r95072 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/AST/ExprCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateDeduction.cpp

John McCall rjmccall at apple.com
Mon Feb 1 22:20:04 PST 2010


Author: rjmccall
Date: Tue Feb  2 00:20:04 2010
New Revision: 95072

URL: http://llvm.org/viewvc/llvm-project?rev=95072&view=rev
Log:
Extract a common base class between UnresolvedLookupExpr and
UnresolvedMemberExpr and employ it in a few places where it's useful.


Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=95072&r1=95071&r2=95072&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Feb  2 00:20:04 2010
@@ -1129,40 +1129,123 @@
   virtual child_iterator child_end();
 };
 
-/// \brief A reference to a name which we were able to look up during
-/// parsing but could not resolve to a specific declaration.  This
-/// arises in several ways:
-///   * we might be waiting for argument-dependent lookup
-///   * the name might resolve to an overloaded function
-/// and eventually:
-///   * the lookup might have included a function template
-/// These never include UnresolvedUsingValueDecls, which are always
-/// class members and therefore appear only in
-/// UnresolvedMemberLookupExprs.
-class UnresolvedLookupExpr : public Expr {
+/// \brief A reference to an overloaded function set, either an
+/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
+class OverloadExpr : public Expr {
   /// The results.  These are undesugared, which is to say, they may
-  /// include UsingShadowDecls.
+  /// include UsingShadowDecls.  Access is relative to the naming
+  /// class.
   UnresolvedSet<4> Results;
 
-  /// The name declared.
+  /// The common name of these declarations.
   DeclarationName Name;
 
-  /// The naming class (C++ [class.access.base]p5) of the lookup, if
-  /// any.  This can generally be recalculated from the context chain,
-  /// but that can be fairly expensive for unqualified lookups.  If we
-  /// want to improve memory use here, this could go in a union
-  /// against the qualified-lookup bits.
-  CXXRecordDecl *NamingClass;
-
-  /// The qualifier given, if any.
+  /// The scope specifier, if any.
   NestedNameSpecifier *Qualifier;
-
-  /// The source range of the nested name specifier.
+  
+  /// The source range of the scope specifier.
   SourceRange QualifierRange;
 
   /// The location of the name.
   SourceLocation NameLoc;
 
+  /// True if the name was a template-id.
+  bool HasExplicitTemplateArgs;
+
+protected:
+  OverloadExpr(StmtClass K, QualType T, bool Dependent,
+               NestedNameSpecifier *Qualifier, SourceRange QRange,
+               DeclarationName Name, SourceLocation NameLoc,
+               bool HasTemplateArgs)
+    : Expr(K, T, Dependent, Dependent),
+      Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
+      NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs)
+  {}
+
+public:
+  /// Computes whether an unresolved lookup on the given declarations
+  /// and optional template arguments is type- and value-dependent.
+  static bool ComputeDependence(UnresolvedSetIterator Begin,
+                                UnresolvedSetIterator End,
+                                const TemplateArgumentListInfo *Args);
+
+  /// Finds the overloaded expression in the given expression of
+  /// OverloadTy.
+  ///
+  /// \return the expression (which must be there) and true if it is
+  /// within an address-of operator.
+  static llvm::PointerIntPair<OverloadExpr*,1> find(Expr *E) {
+    assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
+
+    bool op = false;
+    E = E->IgnoreParens();
+    if (isa<UnaryOperator>(E))
+      op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
+    return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
+  }
+
+  void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
+    Results.append(Begin, End);
+  }
+
+  typedef UnresolvedSetImpl::iterator decls_iterator;
+  decls_iterator decls_begin() const { return Results.begin(); }
+  decls_iterator decls_end() const { return Results.end(); }
+
+  /// Gets the decls as an unresolved set.
+  const UnresolvedSetImpl &getDecls() { return Results; }
+
+  /// Gets the number of declarations in the unresolved set.
+  unsigned getNumDecls() const { return Results.size(); }
+
+  /// Gets the name looked up.
+  DeclarationName getName() const { return Name; }
+  void setName(DeclarationName N) { Name = N; }
+
+  /// Gets the location of the name.
+  SourceLocation getNameLoc() const { return NameLoc; }
+  void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
+
+  /// Fetches the nested-name qualifier, if one was given.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+  /// Fetches the range of the nested-name qualifier.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief Determines whether this expression had an explicit
+  /// template argument list, e.g. f<int>.
+  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below
+
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
+  }
+
+  ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
+    if (hasExplicitTemplateArgs())
+      return &getExplicitTemplateArgs();
+    return 0;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnresolvedLookupExprClass ||
+           T->getStmtClass() == UnresolvedMemberExprClass;
+  }
+  static bool classof(const OverloadExpr *) { return true; }
+};
+
+/// \brief A reference to a name which we were able to look up during
+/// parsing but could not resolve to a specific declaration.  This
+/// arises in several ways:
+///   * we might be waiting for argument-dependent lookup
+///   * the name might resolve to an overloaded function
+/// and eventually:
+///   * the lookup might have included a function template
+/// These never include UnresolvedUsingValueDecls, which are always
+/// class members and therefore appear only in
+/// UnresolvedMemberLookupExprs.
+class UnresolvedLookupExpr : public OverloadExpr {
   /// True if these lookup results should be extended by
   /// argument-dependent lookup if this is the operand of a function
   /// call.
@@ -1172,19 +1255,20 @@
   /// trivially rederivable if we urgently need to kill this field.
   bool Overloaded;
 
-  /// True if the name looked up had explicit template arguments.
-  /// This requires all the results to be function templates.  
-  bool HasExplicitTemplateArgs;
+  /// The naming class (C++ [class.access.base]p5) of the lookup, if
+  /// any.  This can generally be recalculated from the context chain,
+  /// but that can be fairly expensive for unqualified lookups.  If we
+  /// want to improve memory use here, this could go in a union
+  /// against the qualified-lookup bits.
+  CXXRecordDecl *NamingClass;
 
   UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
                        NestedNameSpecifier *Qualifier, SourceRange QRange,
                        DeclarationName Name, SourceLocation NameLoc,
                        bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
-    : Expr(UnresolvedLookupExprClass, T, Dependent, Dependent),
-      Name(Name), NamingClass(NamingClass),
-      Qualifier(Qualifier), QualifierRange(QRange),
-      NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded),
-      HasExplicitTemplateArgs(HasTemplateArgs)
+    : OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
+                   Name, NameLoc, HasTemplateArgs),
+      RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
   {}
 
 public:
@@ -1212,23 +1296,6 @@
                                       bool ADL,
                                       const TemplateArgumentListInfo &Args);
 
-  /// Computes whether an unresolved lookup on the given declarations
-  /// and optional template arguments is type- and value-dependent.
-  static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
-                                UnresolvedSetImpl::const_iterator End,
-                                const TemplateArgumentListInfo *Args);
-
-  void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
-    Results.append(Begin, End);
-  }
-
-  typedef UnresolvedSetImpl::iterator decls_iterator;
-  decls_iterator decls_begin() const { return Results.begin(); }
-  decls_iterator decls_end() const { return Results.end(); }
-
-  /// Retrieves the decls as an unresolved set.
-  const UnresolvedSetImpl &getDecls() { return Results; }
-
   /// True if this declaration should be extended by
   /// argument-dependent lookup.
   bool requiresADL() const { return RequiresADL; }
@@ -1236,30 +1303,20 @@
   /// True if this lookup is overloaded.
   bool isOverloaded() const { return Overloaded; }
 
-  /// Fetches the name looked up.
-  DeclarationName getName() const { return Name; }
-
-  /// Gets the location of the name.
-  SourceLocation getNameLoc() const { return NameLoc; }
-
   /// Gets the 'naming class' (in the sense of C++0x
   /// [class.access.base]p5) of the lookup.  This is the scope
   /// that was looked in to find these results.
   CXXRecordDecl *getNamingClass() const { return NamingClass; }
 
-  /// Fetches the nested-name qualifier, if one was given.
-  NestedNameSpecifier *getQualifier() const { return Qualifier; }
-
-  /// Fetches the range of the nested-name qualifier.
-  SourceRange getQualifierRange() const { return QualifierRange; }
-
-  /// Determines whether this lookup had explicit template arguments.
-  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
-
   // Note that, inconsistently with the explicit-template-argument AST
   // nodes, users are *forbidden* from calling these methods on objects
   // without explicit template arguments.
 
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
+  }
+
   /// Gets a reference to the explicit template argument list.
   const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
     assert(hasExplicitTemplateArgs());
@@ -1289,8 +1346,8 @@
   }
 
   virtual SourceRange getSourceRange() const {
-    SourceRange Range(NameLoc);
-    if (Qualifier) Range.setBegin(QualifierRange.getBegin());
+    SourceRange Range(getNameLoc());
+    if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
     if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
     return Range;
   }
@@ -1802,19 +1859,7 @@
 /// In the final AST, an explicit access always becomes a MemberExpr.
 /// An implicit access may become either a MemberExpr or a
 /// DeclRefExpr, depending on whether the member is static.
-class UnresolvedMemberExpr : public Expr {
-  /// The results.  These are undesugared, which is to say, they may
-  /// include UsingShadowDecls.
-  UnresolvedSet<4> Results;
-
-  /// \brief The expression for the base pointer or class reference,
-  /// e.g., the \c x in x.f.  This can be null if this is an 'unbased'
-  /// member expression
-  Stmt *Base;
-
-  /// \brief The type of the base expression;  never null.
-  QualType BaseType;
-
+class UnresolvedMemberExpr : public OverloadExpr {
   /// \brief Whether this member expression used the '->' operator or
   /// the '.' operator.
   bool IsArrow : 1;
@@ -1823,39 +1868,17 @@
   /// declaration.
   bool HasUnresolvedUsing : 1;
 
-  /// \brief Whether this member expression has explicitly-specified template
-  /// arguments.
-  bool HasExplicitTemplateArgs : 1;
+  /// \brief The expression for the base pointer or class reference,
+  /// e.g., the \c x in x.f.  This can be null if this is an 'unbased'
+  /// member expression
+  Stmt *Base;
+
+  /// \brief The type of the base expression;  never null.
+  QualType BaseType;
 
   /// \brief The location of the '->' or '.' operator.
   SourceLocation OperatorLoc;
 
-  /// \brief The nested-name-specifier that precedes the member name, if any.
-  NestedNameSpecifier *Qualifier;
-
-  /// \brief The source range covering the nested name specifier.
-  SourceRange QualifierRange;
-
-  /// \brief The member to which this member expression refers, which
-  /// can be a name or an overloaded operator.
-  DeclarationName MemberName;
-
-  /// \brief The location of the member name.
-  SourceLocation MemberLoc;
-
-  /// \brief Retrieve the explicit template argument list that followed the
-  /// member template name.
-  ExplicitTemplateArgumentList *getExplicitTemplateArgs() {
-    assert(HasExplicitTemplateArgs);
-    return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
-  }
-
-  /// \brief Retrieve the explicit template argument list that followed the
-  /// member template name, if any.
-  const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const {
-    return const_cast<UnresolvedMemberExpr*>(this)->getExplicitTemplateArgs();
-  }
-
   UnresolvedMemberExpr(QualType T, bool Dependent,
                        bool HasUnresolvedUsing,
                        Expr *Base, QualType BaseType, bool IsArrow,
@@ -1877,22 +1900,6 @@
          SourceLocation MemberLoc,
          const TemplateArgumentListInfo *TemplateArgs);
 
-  /// Adds a declaration to the unresolved set.  By assumption, all of
-  /// these happen at initialization time and properties like
-  /// 'Dependent' and 'HasUnresolvedUsing' take them into account.
-  void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
-    Results.append(Begin, End);
-  }
-
-  typedef UnresolvedSetImpl::iterator decls_iterator;
-  decls_iterator decls_begin() const { return Results.begin(); }
-  decls_iterator decls_end() const { return Results.end(); }
-
-  unsigned getNumDecls() const { return Results.size(); }
-
-  /// Retrieves the decls as an unresolved set.
-  const UnresolvedSetImpl &getDecls() { return Results; }
-
   /// \brief True if this is an implicit access, i.e. one in which the
   /// member being accessed was not written in the source.  The source
   /// location of the operator is invalid in this case.
@@ -1917,60 +1924,60 @@
   SourceLocation getOperatorLoc() const { return OperatorLoc; }
   void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
 
-  /// \brief Retrieve the nested-name-specifier that qualifies the member
-  /// name.
-  NestedNameSpecifier *getQualifier() const { return Qualifier; }
-
-  /// \brief Retrieve the source range covering the nested-name-specifier
-  /// that qualifies the member name.
-  SourceRange getQualifierRange() const { return QualifierRange; }
-
   /// \brief Retrieves the naming class of this lookup.
   CXXRecordDecl *getNamingClass() const;
 
   /// \brief Retrieve the name of the member that this expression
   /// refers to.
-  DeclarationName getMemberName() const { return MemberName; }
-  void setMemberName(DeclarationName N) { MemberName = N; }
+  DeclarationName getMemberName() const { return getName(); }
+  void setMemberName(DeclarationName N) { setName(N); }
 
   // \brief Retrieve the location of the name of the member that this
   // expression refers to.
-  SourceLocation getMemberLoc() const { return MemberLoc; }
-  void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+  SourceLocation getMemberLoc() const { return getNameLoc(); }
+  void setMemberLoc(SourceLocation L) { setNameLoc(L); }
 
-  /// \brief Determines whether this member expression actually had a C++
-  /// template argument list explicitly specified, e.g., x.f<int>.
-  bool hasExplicitTemplateArgs() const {
-    return HasExplicitTemplateArgs;
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name.
+  ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+  }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
   }
 
   /// \brief Copies the template arguments into the given structure.
   void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
-    getExplicitTemplateArgs()->copyInto(List);
+    getExplicitTemplateArgs().copyInto(List);
   }
 
   /// \brief Retrieve the location of the left angle bracket following
   /// the member name ('<').
   SourceLocation getLAngleLoc() const {
-    return getExplicitTemplateArgs()->LAngleLoc;
+    return getExplicitTemplateArgs().LAngleLoc;
   }
 
   /// \brief Retrieve the template arguments provided as part of this
   /// template-id.
   const TemplateArgumentLoc *getTemplateArgs() const {
-    return getExplicitTemplateArgs()->getTemplateArgs();
+    return getExplicitTemplateArgs().getTemplateArgs();
   }
 
   /// \brief Retrieve the number of template arguments provided as
   /// part of this template-id.
   unsigned getNumTemplateArgs() const {
-    return getExplicitTemplateArgs()->NumTemplateArgs;
+    return getExplicitTemplateArgs().NumTemplateArgs;
   }
 
   /// \brief Retrieve the location of the right angle bracket
   /// following the template arguments ('>').
   SourceLocation getRAngleLoc() const {
-    return getExplicitTemplateArgs()->RAngleLoc;
+    return getExplicitTemplateArgs().RAngleLoc;
   }
 
   virtual SourceRange getSourceRange() const {
@@ -1980,12 +1987,12 @@
     else if (getQualifier())
       Range.setBegin(getQualifierRange().getBegin());
     else
-      Range.setBegin(MemberLoc);
+      Range.setBegin(getMemberLoc());
 
     if (hasExplicitTemplateArgs())
       Range.setEnd(getRAngleLoc());
     else
-      Range.setEnd(MemberLoc);
+      Range.setEnd(getMemberLoc());
     return Range;
   }
 
@@ -1999,6 +2006,13 @@
   virtual child_iterator child_end();
 };
 
+inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() {
+  if (isa<UnresolvedLookupExpr>(this))
+    return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs();
+  else
+    return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs();
+}
+
 }  // end namespace clang
 
 #endif

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=95072&r1=95071&r2=95072&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Feb  2 00:20:04 2010
@@ -137,10 +137,9 @@
   return ULE;
 }
 
-bool UnresolvedLookupExpr::
-  ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
-                    UnresolvedSetImpl::const_iterator End,
-                    const TemplateArgumentListInfo *Args) {
+bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
+                                     UnresolvedSetIterator End,
+                                     const TemplateArgumentListInfo *Args) {
   for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
     if ((*I)->getDeclContext()->isDependentContext())
       return true;
@@ -646,15 +645,13 @@
                                            DeclarationName MemberName,
                                            SourceLocation MemberLoc,
                                    const TemplateArgumentListInfo *TemplateArgs)
-  : Expr(UnresolvedMemberExprClass, T, Dependent, Dependent),
-    Base(Base), BaseType(BaseType), IsArrow(IsArrow),
-    HasUnresolvedUsing(HasUnresolvedUsing),
-    HasExplicitTemplateArgs(TemplateArgs != 0),
-    OperatorLoc(OperatorLoc),
-    Qualifier(Qualifier), QualifierRange(QualifierRange),
-    MemberName(MemberName), MemberLoc(MemberLoc) {
+  : OverloadExpr(UnresolvedMemberExprClass, T, Dependent,
+                 Qualifier, QualifierRange, MemberName, MemberLoc,
+                 TemplateArgs != 0),
+    IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
+    Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
   if (TemplateArgs)
-    getExplicitTemplateArgs()->initializeFrom(*TemplateArgs);
+    getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
 }
 
 UnresolvedMemberExpr *
@@ -686,8 +683,8 @@
   // It can't be dependent: after all, we were actually able to do the
   // lookup.
   const RecordType *RT;
-  if (Qualifier) {
-    Type *T = Qualifier->getAsType();
+  if (getQualifier()) {
+    Type *T = getQualifier()->getAsType();
     assert(T && "qualifier in member expression does not name type");
     RT = T->getAs<RecordType>();
     assert(RT && "qualifier in member expression does not name record");

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=95072&r1=95071&r2=95072&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Feb  2 00:20:04 2010
@@ -2546,7 +2546,7 @@
     bool Dependent =
       BaseExprType->isDependentType() ||
       R.isUnresolvableResult() ||
-      UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs);
+      OverloadExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs);
 
     // Suppress any lookup-related diagnostics; we'll do these when we
     // pick a member.

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=95072&r1=95071&r2=95072&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Feb  2 00:20:04 2010
@@ -4455,11 +4455,7 @@
     Expr *E = FromExpr->IgnoreParens();
     if (isa<UnaryOperator>(E))
       E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
-    DeclarationName Name;
-    if (isa<UnresolvedLookupExpr>(E))
-      Name = cast<UnresolvedLookupExpr>(E)->getName();
-    else
-      Name = cast<UnresolvedMemberExpr>(E)->getMemberName();
+    DeclarationName Name = cast<OverloadExpr>(E)->getName();
 
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_overload)
       << (unsigned) FnKind << FnDesc
@@ -4950,7 +4946,7 @@
   }
 }
 
-static bool CheckUnresolvedAccess(Sema &S, Expr *E, NamedDecl *D,
+static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, NamedDecl *D,
                                   AccessSpecifier AS) {
   if (isa<UnresolvedLookupExpr>(E))
     return S.CheckUnresolvedLookupAccess(cast<UnresolvedLookupExpr>(E), D, AS);
@@ -4994,50 +4990,28 @@
     return 0;
 
   // Find the actual overloaded function declaration.
+  if (From->getType() != Context.OverloadTy)
+    return 0;
 
   // C++ [over.over]p1:
   //   [...] [Note: any redundant set of parentheses surrounding the
   //   overloaded function name is ignored (5.1). ]
-  Expr *OvlExpr = From->IgnoreParens();
-
   // C++ [over.over]p1:
   //   [...] The overloaded function name can be preceded by the &
   //   operator.
-  if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(OvlExpr)) {
-    if (UnOp->getOpcode() == UnaryOperator::AddrOf)
-      OvlExpr = UnOp->getSubExpr()->IgnoreParens();
+  OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
+  TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
+  if (OvlExpr->hasExplicitTemplateArgs()) {
+    OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
+    ExplicitTemplateArgs = &ETABuffer;
   }
 
-  bool HasExplicitTemplateArgs = false;
-  TemplateArgumentListInfo ExplicitTemplateArgs;
-  const UnresolvedSetImpl *Fns;
-  
-  // Look into the overloaded expression.
-  if (UnresolvedLookupExpr *UL
-               = dyn_cast<UnresolvedLookupExpr>(OvlExpr)) {
-    Fns = &UL->getDecls();
-    if (UL->hasExplicitTemplateArgs()) {
-      HasExplicitTemplateArgs = true;
-      UL->copyTemplateArgumentsInto(ExplicitTemplateArgs);
-    }
-  } else if (UnresolvedMemberExpr *ME
-               = dyn_cast<UnresolvedMemberExpr>(OvlExpr)) {
-    Fns = &ME->getDecls();
-    if (ME->hasExplicitTemplateArgs()) {
-      HasExplicitTemplateArgs = true;
-      ME->copyTemplateArgumentsInto(ExplicitTemplateArgs);
-    }
-  } else return 0;
-
-  // If we didn't actually find anything, we're done.
-  if (Fns->empty())
-    return 0;
-
   // Look through all of the overloaded functions, searching for one
   // whose type matches exactly.
   UnresolvedSet<4> Matches;  // contains only FunctionDecls
   bool FoundNonTemplateFunction = false;
-  for (UnresolvedSetIterator I = Fns->begin(), E = Fns->end(); I != E; ++I) {
+  for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+         E = OvlExpr->decls_end(); I != E; ++I) {
     // Look through any using declarations to find the underlying function.
     NamedDecl *Fn = (*I)->getUnderlyingDecl();
 
@@ -5069,8 +5043,7 @@
       FunctionDecl *Specialization = 0;
       TemplateDeductionInfo Info(Context);
       if (TemplateDeductionResult Result
-            = DeduceTemplateArguments(FunctionTemplate,
-                       (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
+            = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
                                       FunctionType, Specialization, Info)) {
         // FIXME: make a note of the failed deduction for diagnostics.
         (void)Result;
@@ -5093,7 +5066,7 @@
         continue;
       
       // If we have explicit template arguments, skip non-templates.
-      if (HasExplicitTemplateArgs)
+      if (OvlExpr->hasExplicitTemplateArgs())
         continue;
     } else if (IsMember)
       continue;
@@ -5192,45 +5165,27 @@
   // C++ [over.over]p1:
   //   [...] [Note: any redundant set of parentheses surrounding the
   //   overloaded function name is ignored (5.1). ]
-  Expr *OvlExpr = From->IgnoreParens();
-  
   // C++ [over.over]p1:
   //   [...] The overloaded function name can be preceded by the &
   //   operator.
-  if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(OvlExpr)) {
-    if (UnOp->getOpcode() == UnaryOperator::AddrOf)
-      OvlExpr = UnOp->getSubExpr()->IgnoreParens();
-  }
-  
-  bool HasExplicitTemplateArgs = false;
-  TemplateArgumentListInfo ExplicitTemplateArgs;
-  const UnresolvedSetImpl *Fns;
-  
-  // Look into the overloaded expression.
-  if (UnresolvedLookupExpr *UL
-      = dyn_cast<UnresolvedLookupExpr>(OvlExpr)) {
-    Fns = &UL->getDecls();
-    if (UL->hasExplicitTemplateArgs()) {
-      HasExplicitTemplateArgs = true;
-      UL->copyTemplateArgumentsInto(ExplicitTemplateArgs);
-    }
-  } else if (UnresolvedMemberExpr *ME
-             = dyn_cast<UnresolvedMemberExpr>(OvlExpr)) {
-    Fns = &ME->getDecls();
-    if (ME->hasExplicitTemplateArgs()) {
-      HasExplicitTemplateArgs = true;
-      ME->copyTemplateArgumentsInto(ExplicitTemplateArgs);
-    }
-  } else return 0;
+
+  if (From->getType() != Context.OverloadTy)
+    return 0;
+
+  OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
   
   // If we didn't actually find any template-ids, we're done.
-  if (Fns->empty() || !HasExplicitTemplateArgs)
+  if (!OvlExpr->hasExplicitTemplateArgs())
     return 0;
+
+  TemplateArgumentListInfo ExplicitTemplateArgs;
+  OvlExpr->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs);
   
   // Look through all of the overloaded functions, searching for one
   // whose type matches exactly.
   FunctionDecl *Matched = 0;
-  for (UnresolvedSetIterator I = Fns->begin(), E = Fns->end(); I != E; ++I) {
+  for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+         E = OvlExpr->decls_end(); I != E; ++I) {
     // C++0x [temp.arg.explicit]p3:
     //   [...] In contexts where deduction is done and fails, or in contexts
     //   where deduction is not done, if a template argument list is 

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=95072&r1=95071&r2=95072&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Tue Feb  2 00:20:04 2010
@@ -1324,34 +1324,19 @@
 static QualType
 ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
                             Expr *Arg, QualType ParamType) {
-  bool isAddressOfOperand = false;
+  llvm::PointerIntPair<OverloadExpr*,1> R = OverloadExpr::find(Arg);
 
-  Arg = Arg->IgnoreParens();
-  if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
-    assert(UnOp->getOpcode() == UnaryOperator::AddrOf);
-    isAddressOfOperand = true;
-    Arg = UnOp->getSubExpr()->IgnoreParens();
-  }
-
-  const UnresolvedSetImpl *Decls;
-  bool HasExplicitArgs;
-  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg)) {
-    Decls = &ULE->getDecls();
-    HasExplicitArgs = ULE->hasExplicitTemplateArgs();
-  } else {
-    UnresolvedMemberExpr *UME = cast<UnresolvedMemberExpr>(Arg);
-    Decls = &UME->getDecls();
-    HasExplicitArgs = ULE->hasExplicitTemplateArgs();
-  }
+  bool isAddressOfOperand = bool(R.getInt());
+  OverloadExpr *Ovl = R.getPointer();
 
   // If there were explicit template arguments, we can only find
   // something via C++ [temp.arg.explicit]p3, i.e. if the arguments
   // unambiguously name a full specialization.
-  if (HasExplicitArgs) {
+  if (Ovl->hasExplicitTemplateArgs()) {
     // But we can still look for an explicit specialization.
     if (FunctionDecl *ExplicitSpec
-          = S.ResolveSingleFunctionTemplateSpecialization(Arg))
-      return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);        
+          = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
+      return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);
     return QualType();
   }
 
@@ -1365,8 +1350,8 @@
     return QualType();
 
   QualType Match;
-  for (UnresolvedSetIterator I = Decls->begin(),
-         E = Decls->end(); I != E; ++I) {
+  for (UnresolvedSetIterator I = Ovl->decls_begin(),
+         E = Ovl->decls_end(); I != E; ++I) {
     NamedDecl *D = (*I)->getUnderlyingDecl();
 
     //   - If the argument is an overload set containing one or more





More information about the cfe-commits mailing list