aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-12-23 00:26:44 +0000
committerDouglas Gregor <dgregor@apple.com>2008-12-23 00:26:44 +0000
commit3fc749d899dfc194162128c1a88933148a39b68d (patch)
tree2b9fd9eaf91829aeb60dbfbca21c9a523d03bcad /lib/Sema/SemaOverload.cpp
parent5b8c7d9fb620ba3a71e996d61e7b9bdf763b5c09 (diff)
Don't explicitly represent OverloadedFunctionDecls within
DeclContext. Instead, just keep the list of currently-active declarations and only build the OverloadedFunctionDecl when we absolutely need it. This is a half-step toward eliminating the need to explicitly build OverloadedFunctionDecls that store sets of overloaded functions. This was suggested by Argiris a while back, and it's a good thing for several reasons: first, it eliminates the messy logic that currently tries to keep the OverloadedFunctionDecl in sync with the declarations that are being added. Second, it will (eventually) eliminate the need to allocate memory for overload sets, which could help performance. Finally, it helps set us up for when name lookup can return multiple (possibly ambiguous) results, as can happen with lookup of class members in C++. Next steps: make the IdentifierResolver store overloads as separate entries in its list rather than replacing them with an OverloadedFunctionDecl now, then see how far we can go toward eliminating OverloadedFunctionDecl entirely. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61357 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp86
1 files changed, 22 insertions, 64 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 8365349513..8463c5d34b 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -20,6 +20,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeOrdering.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
@@ -1106,22 +1107,10 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
DeclarationName ConstructorName
= Context.DeclarationNames.getCXXConstructorName(
Context.getCanonicalType(ToType));
- DeclContext::lookup_result Lookup
- = ToRecordDecl->lookup(Context, ConstructorName);
- if (Lookup.first == Lookup.second)
- /* No constructors. FIXME: Implicit copy constructor? */;
- else if (OverloadedFunctionDecl *Constructors
- = dyn_cast<OverloadedFunctionDecl>(*Lookup.first)) {
- for (OverloadedFunctionDecl::function_const_iterator func
- = Constructors->function_begin();
- func != Constructors->function_end(); ++func) {
- CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*func);
- if (Constructor->isConvertingConstructor())
- AddOverloadCandidate(Constructor, &From, 1, CandidateSet,
- /*SuppressUserConversions=*/true);
- }
- } else if (CXXConstructorDecl *Constructor
- = dyn_cast<CXXConstructorDecl>(*Lookup.first)) {
+ DeclContext::lookup_iterator Con, ConEnd;
+ for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(Context, ConstructorName);
+ Con != ConEnd; ++Con) {
+ CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
if (Constructor->isConvertingConstructor())
AddOverloadCandidate(Constructor, &From, 1, CandidateSet,
/*SuppressUserConversions=*/true);
@@ -2142,22 +2131,12 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
// (13.3.1.1.1); otherwise, the set of member candidates is
// empty.
if (const RecordType *T1Rec = T1->getAsRecordType()) {
- DeclContext::lookup_const_result Lookup
- = T1Rec->getDecl()->lookup(Context, OpName);
- NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first;
- if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps))
- AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet,
+ DeclContext::lookup_const_iterator Oper, OperEnd;
+ for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName);
+ Oper != OperEnd; ++Oper)
+ AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0],
+ Args+1, NumArgs - 1, CandidateSet,
/*SuppressUserConversions=*/false);
- else if (OverloadedFunctionDecl *Ovl
- = dyn_cast_or_null<OverloadedFunctionDecl>(MemberOps)) {
- for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
- FEnd = Ovl->function_end();
- F != FEnd; ++F) {
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*F))
- AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet,
- /*SuppressUserConversions=*/false);
- }
- }
}
// -- The set of non-member candidates is the result of the
@@ -3405,22 +3384,11 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// (E).operator().
OverloadCandidateSet CandidateSet;
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
- DeclContext::lookup_const_result Lookup
- = Record->getDecl()->lookup(Context, OpName);
- NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first;
- if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps))
- AddMethodCandidate(Method, Object, Args, NumArgs, CandidateSet,
- /*SuppressUserConversions=*/false);
- else if (OverloadedFunctionDecl *Ovl
- = dyn_cast_or_null<OverloadedFunctionDecl>(MemberOps)) {
- for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
- FEnd = Ovl->function_end();
- F != FEnd; ++F) {
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*F))
- AddMethodCandidate(Method, Object, Args, NumArgs, CandidateSet,
- /*SuppressUserConversions=*/false);
- }
- }
+ DeclContext::lookup_const_iterator Oper, OperEnd;
+ for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName);
+ Oper != OperEnd; ++Oper)
+ AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
+ CandidateSet, /*SuppressUserConversions=*/false);
// C++ [over.call.object]p2:
// In addition, for each conversion function declared in T of the
@@ -3585,7 +3553,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
/// (if one exists), where @c Base is an expression of class type and
/// @c Member is the name of the member we're trying to find.
Action::ExprResult
-Sema::BuildOverloadedArrowExpr(Expr *Base, SourceLocation OpLoc,
+Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
SourceLocation MemberLoc,
IdentifierInfo &Member) {
assert(Base->getType()->isRecordType() && "left-hand side must have class type");
@@ -3600,22 +3568,12 @@ Sema::BuildOverloadedArrowExpr(Expr *Base, SourceLocation OpLoc,
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow);
OverloadCandidateSet CandidateSet;
const RecordType *BaseRecord = Base->getType()->getAsRecordType();
- DeclContext::lookup_const_result Lookup
- = BaseRecord->getDecl()->lookup(Context, OpName);
- NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first;
- if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps))
- AddMethodCandidate(Method, Base, 0, 0, CandidateSet,
+
+ DeclContext::lookup_const_iterator Oper, OperEnd;
+ for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(Context, OpName);
+ Oper != OperEnd; ++Oper)
+ AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet,
/*SuppressUserConversions=*/false);
- else if (OverloadedFunctionDecl *Ovl
- = dyn_cast_or_null<OverloadedFunctionDecl>(MemberOps)) {
- for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
- FEnd = Ovl->function_end();
- F != FEnd; ++F) {
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*F))
- AddMethodCandidate(Method, Base, 0, 0, CandidateSet,
- /*SuppressUserConversions=*/false);
- }
- }
llvm::OwningPtr<Expr> BasePtr(Base);
@@ -3658,7 +3616,7 @@ Sema::BuildOverloadedArrowExpr(Expr *Base, SourceLocation OpLoc,
Base = new CXXOperatorCallExpr(FnExpr, &Base, 1,
Method->getResultType().getNonReferenceType(),
OpLoc);
- return ActOnMemberReferenceExpr(Base, OpLoc, tok::arrow, MemberLoc, Member);
+ return ActOnMemberReferenceExpr(S, Base, OpLoc, tok::arrow, MemberLoc, Member);
}
/// FixOverloadedFunctionReference - E is an expression that refers to