[cfe-commits] r63735 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/overloaded-operator.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 4 08:44:47 PST 2009
Author: dgregor
Date: Wed Feb 4 10:44:47 2009
New Revision: 63735
URL: http://llvm.org/viewvc/llvm-project?rev=63735&view=rev
Log:
Bring operator name lookup (as required for C++ operator overloading)
into the general name-lookup fold. This cleans up some ugly,
not-quite-working code in the handling of operator overloading.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/overloaded-operator.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=63735&r1=63734&r2=63735&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Feb 4 10:44:47 2009
@@ -488,9 +488,11 @@
const FunctionTypeProto *Proto,
Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet);
- void AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
+ bool AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
+ SourceLocation OpLoc,
Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet);
+ OverloadCandidateSet& CandidateSet,
+ SourceRange OpRange = SourceRange());
void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
@@ -502,10 +504,6 @@
void AddArgumentDependentLookupCandidates(DeclarationName Name,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet);
- void AddOverloadCandidates(const OverloadedFunctionDecl *Ovl,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false);
bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
const OverloadCandidate& Cand2);
OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
@@ -585,6 +583,11 @@
/// Member name lookup, which finds the names of
/// class/struct/union members.
LookupMemberName,
+ // Look up of an operator name (e.g., operator+) for use with
+ // operator overloading. This lookup is similar to ordinary name
+ // lookup, but will ignore any declarations that are class
+ // members.
+ LookupOperatorName,
/// Look up of a name that precedes the '::' scope resolution
/// operator in C++. This lookup completely ignores operator,
/// function, and enumerator names (C++ [basic.lookup.qual]p1).
@@ -839,6 +842,10 @@
case Sema::LookupMemberName:
return D->isInIdentifierNamespace(IDNS);
+ case Sema::LookupOperatorName:
+ return D->isInIdentifierNamespace(IDNS) &&
+ !D->getDeclContext()->isRecord();
+
case Sema::LookupNestedNameSpecifierName:
return isa<TypedefDecl>(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=63735&r1=63734&r2=63735&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Feb 4 10:44:47 2009
@@ -1190,7 +1190,8 @@
// Build the candidate set for overloading
OverloadCandidateSet CandidateSet;
- AddOperatorCandidates(OverOp, S, Args, 2, CandidateSet);
+ if (AddOperatorCandidates(OverOp, S, OpLoc, Args, 2, CandidateSet))
+ return ExprError();
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
@@ -1281,7 +1282,9 @@
// to the candidate set.
OverloadCandidateSet CandidateSet;
Expr *Args[2] = { LHSExp, RHSExp };
- AddOperatorCandidates(OO_Subscript, S, Args, 2, CandidateSet);
+ if (AddOperatorCandidates(OO_Subscript, S, LLoc, Args, 2, CandidateSet,
+ SourceRange(LLoc, RLoc)))
+ return ExprError();
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
@@ -3738,7 +3741,8 @@
// to the candidate set.
OverloadCandidateSet CandidateSet;
Expr *Args[2] = { lhs, rhs };
- AddOperatorCandidates(OverOp, S, Args, 2, CandidateSet);
+ if (AddOperatorCandidates(OverOp, S, TokLoc, Args, 2, CandidateSet))
+ return ExprError();
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
@@ -3840,8 +3844,9 @@
// Add the appropriate overloaded operators (C++ [over.match.oper])
// to the candidate set.
OverloadCandidateSet CandidateSet;
- if (OverOp != OO_None)
- AddOperatorCandidates(OverOp, S, &Input, 1, CandidateSet);
+ if (OverOp != OO_None &&
+ AddOperatorCandidates(OverOp, S, OpLoc, &Input, 1, CandidateSet))
+ return ExprError();
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=63735&r1=63734&r2=63735&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Feb 4 10:44:47 2009
@@ -313,6 +313,7 @@
unsigned IDNS = 0;
switch (NameKind) {
case Sema::LookupOrdinaryName:
+ case Sema::LookupOperatorName:
IDNS = Decl::IDNS_Ordinary;
if (CPlusPlus)
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member;
@@ -531,6 +532,7 @@
Decl ** I = reinterpret_cast<Decl**>(Current);
++I;
Current = reinterpret_cast<uintptr_t>(I);
+ break;
}
case OverloadedDeclFromIdResolver: {
@@ -587,7 +589,7 @@
LookupNameKind NameKind, bool RedeclarationOnly) {
assert(getLangOptions().CPlusPlus &&
"Can perform only C++ lookup");
-unsigned IDNS
+ unsigned IDNS
= getIdentifierNamespacesFromLookupNameKind(NameKind, /*CPlusPlus*/ true);
Scope *Initial = S;
IdentifierResolver::iterator
@@ -841,6 +843,7 @@
IDNS = Decl::IDNS_Member;
break;
+ case Sema::LookupOperatorName:
case Sema::LookupNestedNameSpecifierName:
case Sema::LookupNamespaceName:
assert(false && "C does not perform these kinds of name lookup");
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=63735&r1=63734&r2=63735&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Feb 4 10:44:47 2009
@@ -2258,9 +2258,11 @@
/// name lookup of the operator), Args/NumArgs provides the operator
/// arguments, and CandidateSet will store the added overload
/// candidates. (C++ [over.match.oper]).
-void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
+bool Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
+ SourceLocation OpLoc,
Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet) {
+ OverloadCandidateSet& CandidateSet,
+ SourceRange OpRange) {
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
// C++ [over.match.oper]p3:
@@ -2300,45 +2302,29 @@
// type, or (if there is a right operand) a second parameter
// of type T2 or âreference to (possibly cv-qualified) T2â,
// when T2 is an enumeration type, are candidate functions.
- {
- // FIXME: Don't use the IdentifierResolver here! We need to
- // perform proper, unqualified lookup starting with the first
- // enclosing non-class scope.
- IdentifierResolver::iterator I = IdResolver.begin(OpName),
- IEnd = IdResolver.end();
- for (; I != IEnd; ++I) {
- // We don't need to check the identifier namespace, because
- // operator names can only be ordinary identifiers.
-
- // Ignore member functions.
- if ((*I)->getDeclContext()->isRecord())
- continue;
-
- // We found something with this name. We're done.
- break;
- }
-
- if (I != IEnd) {
- Decl *FirstDecl = *I;
- for (; I != IEnd; ++I) {
- if (FirstDecl->getDeclContext() != (*I)->getDeclContext())
- break;
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I))
- if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
- AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
- /*SuppressUserConversions=*/false);
- }
+ LookupResult Operators = LookupName(S, OpName, LookupOperatorName);
+
+ if (Operators.isAmbiguous())
+ return DiagnoseAmbiguousLookup(Operators, OpName, OpLoc, OpRange);
+ else if (Operators) {
+ for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
+ Op != OpEnd; ++Op) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op))
+ if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+ /*SuppressUserConversions=*/false);
}
-
- // Since the set of non-member candidates corresponds to
- // *unqualified* lookup of the operator name, we also perform
- // argument-dependent lookup.
- AddArgumentDependentLookupCandidates(OpName, Args, NumArgs, CandidateSet);
}
+ // Since the set of non-member candidates corresponds to
+ // *unqualified* lookup of the operator name, we also perform
+ // argument-dependent lookup (C++ [basic.lookup.argdep]).
+ AddArgumentDependentLookupCandidates(OpName, Args, NumArgs, CandidateSet);
+
// Add builtin overload candidates (C++ [over.built]).
AddBuiltinOperatorCandidates(Op, Args, NumArgs, CandidateSet);
+
+ return false;
}
/// AddBuiltinCandidate - Add a candidate for a built-in
@@ -3230,21 +3216,6 @@
}
}
-/// AddOverloadCandidates - Add all of the function overloads in Ovl
-/// to the candidate set.
-void
-Sema::AddOverloadCandidates(const OverloadedFunctionDecl *Ovl,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions)
-{
- for (OverloadedFunctionDecl::function_const_iterator Func
- = Ovl->function_begin();
- Func != Ovl->function_end(); ++Func)
- AddOverloadCandidate(*Func, Args, NumArgs, CandidateSet,
- SuppressUserConversions);
-}
-
/// isBetterOverloadCandidate - Determines whether the first overload
/// candidate is a better candidate than the second (C++ 13.3.3p1).
bool
Modified: cfe/trunk/test/SemaCXX/overloaded-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-operator.cpp?rev=63735&r1=63734&r2=63735&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overloaded-operator.cpp (original)
+++ cfe/trunk/test/SemaCXX/overloaded-operator.cpp Wed Feb 4 10:44:47 2009
@@ -206,7 +206,6 @@
namespace M {
void test_X(N::X x) {
- // FIXME: this should work! See comment in Sema::AddOperatorCandidates.
- // (void)(x + x);
+ (void)(x + x);
}
}
More information about the cfe-commits
mailing list