[cfe-commits] r94498 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/Sema/Lookup.h lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaOverload.cpp lib/Sema/TreeTransform.h
John McCall
rjmccall at apple.com
Mon Jan 25 19:27:55 PST 2010
Author: rjmccall
Date: Mon Jan 25 21:27:55 2010
New Revision: 94498
URL: http://llvm.org/viewvc/llvm-project?rev=94498&view=rev
Log:
Preserve access bits through overload resolution much better. Some
general refactoring in operator resolution.
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/lib/Sema/Lookup.h
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/lib/Sema/TreeTransform.h
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=94498&r1=94497&r2=94498&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Jan 25 21:27:55 2010
@@ -1137,6 +1137,10 @@
UnresolvedSetImpl::const_iterator End,
const TemplateArgumentListInfo *Args);
+ void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
+ Results.append(Begin, End);
+ }
+
void addDecl(NamedDecl *Decl) {
Results.addDecl(Decl);
}
Modified: cfe/trunk/lib/Sema/Lookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Lookup.h?rev=94498&r1=94497&r2=94498&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Lookup.h (original)
+++ cfe/trunk/lib/Sema/Lookup.h Mon Jan 25 21:27:55 2010
@@ -224,6 +224,10 @@
return Ambiguity;
}
+ const UnresolvedSetImpl &asUnresolvedSet() const {
+ return Decls;
+ }
+
iterator begin() const { return iterator(Decls.begin()); }
iterator end() const { return iterator(Decls.end()); }
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=94498&r1=94497&r2=94498&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jan 25 21:27:55 2010
@@ -950,10 +950,15 @@
// Members have to be NamespaceDecl* or TranslationUnitDecl*.
// TODO: make this is a typesafe union.
typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet;
-
- typedef llvm::SmallPtrSet<AnyFunctionDecl, 16> FunctionSet;
+ // Members have to be a function or function template.
+ typedef llvm::SmallPtrSet<NamedDecl*, 16> ADLFunctionSet;
typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
+ void AddOverloadCandidate(NamedDecl *Function,
+ AccessSpecifier Access,
+ Expr **Args, unsigned NumArgs,
+ OverloadCandidateSet &CandidateSet);
+
void AddOverloadCandidate(FunctionDecl *Function,
AccessSpecifier Access,
Expr **Args, unsigned NumArgs,
@@ -961,7 +966,7 @@
bool SuppressUserConversions = false,
bool ForceRValue = false,
bool PartialOverloading = false);
- void AddFunctionCandidates(const FunctionSet &Functions,
+ void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false);
@@ -1029,6 +1034,7 @@
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet);
void AddArgumentDependentLookupCandidates(DeclarationName Name,
+ bool Operator,
Expr **Args, unsigned NumArgs,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
@@ -1080,12 +1086,12 @@
OwningExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
unsigned Opc,
- FunctionSet &Functions,
+ const UnresolvedSetImpl &Fns,
ExprArg input);
OwningExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
unsigned Opc,
- FunctionSet &Functions,
+ const UnresolvedSetImpl &Fns,
Expr *LHS, Expr *RHS);
OwningExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
@@ -1230,11 +1236,11 @@
void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
- FunctionSet &Functions);
+ UnresolvedSetImpl &Functions);
void ArgumentDependentLookup(DeclarationName Name, bool Operator,
Expr **Args, unsigned NumArgs,
- FunctionSet &Functions);
+ ADLFunctionSet &Functions);
void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
VisibleDeclConsumer &Consumer);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=94498&r1=94497&r2=94498&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jan 25 21:27:55 2010
@@ -6337,17 +6337,11 @@
// point. We perform both an operator-name lookup from the local
// scope and an argument-dependent lookup based on the types of
// the arguments.
- FunctionSet Functions;
+ UnresolvedSet<16> Functions;
OverloadedOperatorKind OverOp = BinaryOperator::getOverloadedOperator(Opc);
- if (OverOp != OO_None) {
- if (S)
- LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
- Functions);
- Expr *Args[2] = { lhs, rhs };
- DeclarationName OpName
- = Context.DeclarationNames.getCXXOperatorName(OverOp);
- ArgumentDependentLookup(OpName, /*Operator*/true, Args, 2, Functions);
- }
+ if (S && OverOp != OO_None)
+ LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
+ Functions);
// Build the (potentially-overloaded, potentially-dependent)
// binary operation.
@@ -6456,16 +6450,11 @@
// point. We perform both an operator-name lookup from the local
// scope and an argument-dependent lookup based on the types of
// the arguments.
- FunctionSet Functions;
+ UnresolvedSet<16> Functions;
OverloadedOperatorKind OverOp = UnaryOperator::getOverloadedOperator(Opc);
- if (OverOp != OO_None) {
- if (S)
- LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
- Functions);
- DeclarationName OpName
- = Context.DeclarationNames.getCXXOperatorName(OverOp);
- ArgumentDependentLookup(OpName, /*Operator*/true, &Input, 1, Functions);
- }
+ if (S && OverOp != OO_None)
+ LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
+ Functions);
return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
}
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=94498&r1=94497&r2=94498&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Jan 25 21:27:55 2010
@@ -1693,7 +1693,7 @@
void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
QualType T1, QualType T2,
- FunctionSet &Functions) {
+ UnresolvedSetImpl &Functions) {
// C++ [over.match.oper]p3:
// -- The set of non-member candidates is the result of the
// unqualified lookup of operator@ in the context of the
@@ -1719,29 +1719,21 @@
Op != OpEnd; ++Op) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op)) {
if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
- Functions.insert(FD); // FIXME: canonical FD
+ Functions.addDecl(FD, Op.getAccess()); // FIXME: canonical FD
} else if (FunctionTemplateDecl *FunTmpl
= dyn_cast<FunctionTemplateDecl>(*Op)) {
// FIXME: friend operators?
// FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
// later?
if (!FunTmpl->getDeclContext()->isRecord())
- Functions.insert(FunTmpl);
+ Functions.addDecl(FunTmpl, Op.getAccess());
}
}
}
-static void CollectFunctionDecl(Sema::FunctionSet &Functions,
- Decl *D) {
- if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
- Functions.insert(Func);
- else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
- Functions.insert(FunTmpl);
-}
-
void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
Expr **Args, unsigned NumArgs,
- FunctionSet &Functions) {
+ ADLFunctionSet &Functions) {
// Find all of the associated namespaces and classes based on the
// arguments we have.
AssociatedNamespaceSet AssociatedNamespaces;
@@ -1784,7 +1776,7 @@
// lookup (11.4).
DeclContext::lookup_iterator I, E;
for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) {
- Decl *D = *I;
+ NamedDecl *D = *I;
// If the only declaration here is an ordinary friend, consider
// it only if it was declared in an associated classes.
if (D->getIdentifierNamespace() == Decl::IDNS_OrdinaryFriend) {
@@ -1793,10 +1785,16 @@
continue;
}
+ // FIXME: using decls? canonical decls?
+
FunctionDecl *Fn;
if (!Operator || !(Fn = dyn_cast<FunctionDecl>(D)) ||
- IsAcceptableNonMemberOperatorCandidate(Fn, T1, T2, Context))
- CollectFunctionDecl(Functions, D);
+ IsAcceptableNonMemberOperatorCandidate(Fn, T1, T2, Context)) {
+ if (isa<FunctionDecl>(D))
+ Functions.insert(D);
+ else if (isa<FunctionTemplateDecl>(D))
+ Functions.insert(D);
+ }
}
}
}
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=94498&r1=94497&r2=94498&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 25 21:27:55 2010
@@ -2475,17 +2475,15 @@
/// \brief Add all of the function declarations in the given function set to
/// the overload canddiate set.
-void Sema::AddFunctionCandidates(const FunctionSet &Functions,
+void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions) {
- for (FunctionSet::const_iterator F = Functions.begin(),
- FEnd = Functions.end();
- F != FEnd; ++F) {
+ for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
// FIXME: using declarations
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F)) {
if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
- AddMethodCandidate(cast<CXXMethodDecl>(FD), /*FIXME*/ FD->getAccess(),
+ AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getAccess(),
cast<CXXMethodDecl>(FD)->getParent(),
Args[0]->getType(), Args + 1, NumArgs - 1,
CandidateSet, SuppressUserConversions);
@@ -2496,7 +2494,7 @@
FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*F);
if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
!cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
- AddMethodTemplateCandidate(FunTmpl, /*FIXME*/ FunTmpl->getAccess(),
+ AddMethodTemplateCandidate(FunTmpl, F.getAccess(),
cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
/*FIXME: explicit args */ 0,
Args[0]->getType(), Args + 1, NumArgs - 1,
@@ -2986,7 +2984,7 @@
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
SourceRange OpRange) {
- FunctionSet Functions;
+ UnresolvedSet<16> Fns;
QualType T1 = Args[0]->getType();
QualType T2;
@@ -2995,9 +2993,10 @@
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
if (S)
- LookupOverloadedOperatorName(Op, S, T1, T2, Functions);
- ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs, Functions);
- AddFunctionCandidates(Functions, Args, NumArgs, CandidateSet);
+ LookupOverloadedOperatorName(Op, S, T1, T2, Fns);
+ AddFunctionCandidates(Fns, Args, NumArgs, CandidateSet, false);
+ AddArgumentDependentLookupCandidates(OpName, false, Args, NumArgs, 0,
+ CandidateSet);
AddMemberOperatorCandidates(Op, OpLoc, Args, NumArgs, CandidateSet, OpRange);
AddBuiltinOperatorCandidates(Op, OpLoc, Args, NumArgs, CandidateSet);
}
@@ -4127,31 +4126,19 @@
/// candidate set (C++ [basic.lookup.argdep]).
void
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
+ bool Operator,
Expr **Args, unsigned NumArgs,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
bool PartialOverloading) {
- FunctionSet Functions;
+ ADLFunctionSet Functions;
// FIXME: Should we be trafficking in canonical function decls throughout?
- // Record all of the function candidates that we've already
- // added to the overload set, so that we don't add those same
- // candidates a second time.
- for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
- CandEnd = CandidateSet.end();
- Cand != CandEnd; ++Cand)
- if (Cand->Function) {
- Functions.insert(Cand->Function);
- if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
- Functions.insert(FunTmpl);
- }
-
// FIXME: Pass in the explicit template arguments?
- ArgumentDependentLookup(Name, /*Operator*/false, Args, NumArgs, Functions);
+ ArgumentDependentLookup(Name, Operator, Args, NumArgs, Functions);
// Erase all of the candidates we already knew about.
- // FIXME: This is suboptimal. Is there a better way?
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
CandEnd = CandidateSet.end();
Cand != CandEnd; ++Cand)
@@ -4163,17 +4150,16 @@
// For each of the ADL candidates we found, add it to the overload
// set.
- for (FunctionSet::iterator Func = Functions.begin(),
- FuncEnd = Functions.end();
- Func != FuncEnd; ++Func) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) {
+ for (ADLFunctionSet::iterator I = Functions.begin(),
+ E = Functions.end(); I != E; ++I) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
if (ExplicitTemplateArgs)
continue;
AddOverloadCandidate(FD, AS_none, Args, NumArgs, CandidateSet,
false, false, PartialOverloading);
} else
- AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I),
AS_none, ExplicitTemplateArgs,
Args, NumArgs, CandidateSet);
}
@@ -5242,7 +5228,8 @@
PartialOverloading);
if (ULE->requiresADL())
- AddArgumentDependentLookupCandidates(ULE->getName(), Args, NumArgs,
+ AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false,
+ Args, NumArgs,
ExplicitTemplateArgs,
CandidateSet,
PartialOverloading);
@@ -5392,7 +5379,7 @@
return ExprError();
}
-static bool IsOverloaded(const Sema::FunctionSet &Functions) {
+static bool IsOverloaded(const UnresolvedSetImpl &Functions) {
return Functions.size() > 1 ||
(Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
}
@@ -5413,10 +5400,10 @@
/// by CreateOverloadedUnaryOp().
///
/// \param input The input argument.
-Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
- unsigned OpcIn,
- FunctionSet &Functions,
- ExprArg input) {
+Sema::OwningExprResult
+Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
+ const UnresolvedSetImpl &Fns,
+ ExprArg input) {
UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
Expr *Input = (Expr *)input.get();
@@ -5441,11 +5428,8 @@
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, /*Dependent*/ true,
0, SourceRange(), OpName, OpLoc,
- /*ADL*/ true, IsOverloaded(Functions));
- for (FunctionSet::iterator Func = Functions.begin(),
- FuncEnd = Functions.end();
- Func != FuncEnd; ++Func)
- Fn->addDecl(*Func);
+ /*ADL*/ true, IsOverloaded(Fns));
+ Fn->addDecls(Fns.begin(), Fns.end());
input.release();
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
@@ -5458,11 +5442,17 @@
OverloadCandidateSet CandidateSet;
// Add the candidates from the given function set.
- AddFunctionCandidates(Functions, &Args[0], NumArgs, CandidateSet, false);
+ AddFunctionCandidates(Fns, &Args[0], NumArgs, CandidateSet, false);
// Add operator candidates that are member functions.
AddMemberOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
+ // Add candidates from ADL.
+ AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
+ Args, 1,
+ /*ExplicitTemplateArgs*/ 0,
+ CandidateSet);
+
// Add builtin operator candidates.
AddBuiltinOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
@@ -5575,7 +5565,7 @@
Sema::OwningExprResult
Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
unsigned OpcIn,
- FunctionSet &Functions,
+ const UnresolvedSetImpl &Fns,
Expr *LHS, Expr *RHS) {
Expr *Args[2] = { LHS, RHS };
LHS=RHS=0; //Please use only Args instead of LHS/RHS couple
@@ -5587,7 +5577,7 @@
// If either side is type-dependent, create an appropriate dependent
// expression.
if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
- if (Functions.empty()) {
+ if (Fns.empty()) {
// If there are no functions to store, just build a dependent
// BinaryOperator or CompoundAssignment.
if (Opc <= BinaryOperator::Assign || Opc > BinaryOperator::OrAssign)
@@ -5600,17 +5590,14 @@
Context.DependentTy,
OpLoc));
}
-
+
+ // FIXME: save results of ADL from here?
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, /*Dependent*/ true,
0, SourceRange(), OpName, OpLoc,
- /* ADL */ true, IsOverloaded(Functions));
-
- for (FunctionSet::iterator Func = Functions.begin(),
- FuncEnd = Functions.end();
- Func != FuncEnd; ++Func)
- Fn->addDecl(*Func);
+ /*ADL*/ true, IsOverloaded(Fns));
+ Fn->addDecls(Fns.begin(), Fns.end());
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
Args, 2,
Context.DependentTy,
@@ -5635,11 +5622,17 @@
OverloadCandidateSet CandidateSet;
// Add the candidates from the given function set.
- AddFunctionCandidates(Functions, Args, 2, CandidateSet, false);
+ AddFunctionCandidates(Fns, Args, 2, CandidateSet, false);
// Add operator candidates that are member functions.
AddMemberOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
+ // Add candidates from ADL.
+ AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
+ Args, 2,
+ /*ExplicitTemplateArgs*/ 0,
+ CandidateSet);
+
// Add builtin operator candidates.
AddBuiltinOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=94498&r1=94497&r2=94498&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jan 25 21:27:55 2010
@@ -5644,28 +5644,21 @@
// Compute the transformed set of functions (and function templates) to be
// used during overload resolution.
- Sema::FunctionSet Functions;
+ UnresolvedSet<16> Functions;
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
assert(ULE->requiresADL());
// FIXME: Do we have to check
// IsAcceptableNonMemberOperatorCandidate for each of these?
- for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
- E = ULE->decls_end(); I != E; ++I)
- Functions.insert(AnyFunctionDecl::getFromNamedDecl(*I));
+ Functions.append(ULE->decls_begin(), ULE->decls_end());
} else {
- Functions.insert(AnyFunctionDecl::getFromNamedDecl(
- cast<DeclRefExpr>(CalleeExpr)->getDecl()));
+ Functions.addDecl(cast<DeclRefExpr>(CalleeExpr)->getDecl());
}
// Add any functions found via argument-dependent lookup.
Expr *Args[2] = { FirstExpr, SecondExpr };
unsigned NumArgs = 1 + (SecondExpr != 0);
- DeclarationName OpName
- = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
- SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
- Functions);
// Create the overloaded operator invocation for unary operators.
if (NumArgs == 1 || isPostIncDec) {
More information about the cfe-commits
mailing list