aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-11-21 08:51:07 +0000
committerJohn McCall <rjmccall@apple.com>2009-11-21 08:51:07 +0000
commitba13543329afac4a0d01304ec2ec4924d99306a6 (patch)
tree1533ccfa9a4fd586085e95f50ba52907d89bcd69
parentbbd37c62e34db3f5a95c899723484a76c71d7757 (diff)
"Incremental" progress on using expressions, by which I mean totally ripping
into pretty much everything about overload resolution in order to wean BuildDeclarationNameExpr off LookupResult::getAsSingleDecl(). Replace UnresolvedFunctionNameExpr with UnresolvedLookupExpr, which generalizes the idea of a non-member lookup that we haven't totally resolved yet, whether by overloading, argument-dependent lookup, or (eventually) the presence of a function template in the lookup results. Incidentally fixes a problem with argument-dependent lookup where we were still performing ADL even when the lookup results contained something from a block scope. Incidentally improves a diagnostic when using an ObjC ivar from a class method. This just fell out from rewriting BuildDeclarationNameExpr's interaction with lookup, and I'm too apathetic to break it out. The only remaining uses of OverloadedFunctionDecl that I know of are in TemplateName and MemberExpr. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89544 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclCXX.h46
-rw-r--r--include/clang/AST/ExprCXX.h146
-rw-r--r--include/clang/AST/StmtNodes.def2
-rw-r--r--lib/AST/DeclCXX.cpp33
-rw-r--r--lib/AST/Expr.cpp5
-rw-r--r--lib/AST/ExprCXX.cpp6
-rw-r--r--lib/AST/StmtPrinter.cpp8
-rw-r--r--lib/AST/StmtProfile.cpp2
-rw-r--r--lib/Sema/Lookup.h6
-rw-r--r--lib/Sema/Sema.h21
-rw-r--r--lib/Sema/SemaCodeComplete.cpp7
-rw-r--r--lib/Sema/SemaDeclCXX.cpp23
-rw-r--r--lib/Sema/SemaExpr.cpp438
-rw-r--r--lib/Sema/SemaExprCXX.cpp16
-rw-r--r--lib/Sema/SemaLookup.cpp42
-rw-r--r--lib/Sema/SemaOverload.cpp296
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp98
-rw-r--r--lib/Sema/TreeTransform.h33
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp4
-rw-r--r--test/SemaObjC/ivar-ref-misuse.m2
20 files changed, 723 insertions, 511 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index e5bf78cd10..66c8174bba 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -88,6 +88,28 @@ namespace llvm {
namespace clang {
+/// UnresolvedSet - A set of unresolved declarations.
+class UnresolvedSet {
+ typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
+ DeclsTy Decls;
+
+public:
+ void addDecl(NamedDecl *D) {
+ Decls.push_back(D);
+ }
+
+ bool replace(const NamedDecl* Old, NamedDecl *New) {
+ for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
+ if (*I == Old)
+ return (*I = New, true);
+ return false;
+ }
+
+ typedef DeclsTy::const_iterator iterator;
+ iterator begin() const { return Decls.begin(); }
+ iterator end() const { return Decls.end(); }
+};
+
/// OverloadedFunctionDecl - An instance of this class represents a
/// set of overloaded functions. All of the functions have the same
/// name and occur within the same scope.
@@ -376,13 +398,13 @@ class CXXRecordDecl : public RecordDecl {
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
/// CXXConversionDecl.
- OverloadedFunctionDecl Conversions;
+ UnresolvedSet Conversions;
/// VisibleConversions - Overload set containing the conversion functions
/// of this C++ class and all those inherited conversion functions that
/// are visible in this class. Each of the entries in this overload set is
/// a CXXConversionDecl or a FunctionTemplateDecl.
- OverloadedFunctionDecl VisibleConversions;
+ UnresolvedSet VisibleConversions;
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
@@ -400,7 +422,7 @@ class CXXRecordDecl : public RecordDecl {
const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet,
const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes);
void collectConversionFunctions(
- llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet);
+ llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const;
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
@@ -581,22 +603,34 @@ public:
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
- OverloadedFunctionDecl *getConversionFunctions() {
+ UnresolvedSet *getConversionFunctions() {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
- const OverloadedFunctionDecl *getConversionFunctions() const {
+ const UnresolvedSet *getConversionFunctions() const {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
+ typedef UnresolvedSet::iterator conversion_iterator;
+ conversion_iterator conversion_begin() const { return Conversions.begin(); }
+ conversion_iterator conversion_end() const { return Conversions.end(); }
+
+ /// Replaces a conversion function with a new declaration.
+ ///
+ /// Returns true if the old conversion was found.
+ bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
+ return Conversions.replace(Old, New);
+ }
+
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
- OverloadedFunctionDecl *getVisibleConversionFunctions();
+ const UnresolvedSet *getVisibleConversionFunctions();
+
/// addVisibleConversionFunction - Add a new conversion function to the
/// list of visible conversion functions.
void addVisibleConversionFunction(CXXConversionDecl *ConvDecl);
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 2e43c5fec9..85a99c0b73 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -17,6 +17,7 @@
#include "clang/Basic/TypeTraits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
namespace clang {
@@ -975,52 +976,6 @@ public:
virtual child_iterator child_end();
};
-/// \brief Represents the name of a function that has not been
-/// resolved to any declaration.
-///
-/// Unresolved function names occur when a function name is
-/// encountered prior to an open parentheses ('(') in a C++ function
-/// call, and the function name itself did not resolve to a
-/// declaration. These function names can only be resolved when they
-/// form the postfix-expression of a function call, so that
-/// argument-dependent lookup finds declarations corresponding to
-/// these functions.
-
-/// @code
-/// template<typename T> void f(T x) {
-/// g(x); // g is an unresolved function name (that is also a dependent name)
-/// }
-/// @endcode
-class UnresolvedFunctionNameExpr : public Expr {
- /// The name that was present in the source
- DeclarationName Name;
-
- /// The location of this name in the source code
- SourceLocation Loc;
-
-public:
- UnresolvedFunctionNameExpr(DeclarationName N, QualType T, SourceLocation L)
- : Expr(UnresolvedFunctionNameExprClass, T, false, false), Name(N), Loc(L) { }
-
- /// \brief Retrieves the name that occurred in the source code.
- DeclarationName getName() const { return Name; }
-
- /// getLocation - Retrieves the location in the source code where
- /// the name occurred.
- SourceLocation getLocation() const { return Loc; }
-
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedFunctionNameExprClass;
- }
- static bool classof(const UnresolvedFunctionNameExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
/// UnaryTypeTraitExpr - A GCC or MS unary type trait, as used in the
/// implementation of TR1/C++0x type trait templates.
/// Example:
@@ -1063,10 +1018,101 @@ public:
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 {
+ /// The results. These are undesugared, which is to say, they may
+ /// include UsingShadowDecls.
+ UnresolvedSet Results;
+
+ /// The name declared.
+ DeclarationName Name;
+
+ /// The qualifier given, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// The source range of the nested name specifier.
+ SourceRange QualifierRange;
+
+ /// The location of the name.
+ SourceLocation NameLoc;
+
+ /// True if these lookup results should be extended by
+ /// argument-dependent lookup if this is the operand of a function
+ /// call.
+ bool RequiresADL;
+
+ UnresolvedLookupExpr(QualType T,
+ NestedNameSpecifier *Qualifier, SourceRange QRange,
+ DeclarationName Name, SourceLocation NameLoc,
+ bool RequiresADL)
+ : Expr(UnresolvedLookupExprClass, T, false, false),
+ Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
+ NameLoc(NameLoc), RequiresADL(RequiresADL)
+ {}
+
+public:
+ static UnresolvedLookupExpr *Create(ASTContext &C,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool ADL) {
+ return new(C) UnresolvedLookupExpr(C.OverloadTy, Qualifier, QualifierRange,
+ Name, NameLoc, ADL);
+ }
+
+ void addDecl(NamedDecl *Decl) {
+ Results.addDecl(Decl);
+ }
+
+ typedef UnresolvedSet::iterator decls_iterator;
+ decls_iterator decls_begin() const { return Results.begin(); }
+ decls_iterator decls_end() const { return Results.end(); }
+
+ /// True if this declaration should be extended by
+ /// argument-dependent lookup.
+ bool requiresADL() const { return RequiresADL; }
+
+ /// Fetches the name looked up.
+ DeclarationName getName() const { return Name; }
+
+ /// Gets the location of the name.
+ SourceLocation getNameLoc() const { return NameLoc; }
+
+ /// 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; }
+
+
+ virtual SourceRange getSourceRange() const {
+ if (Qualifier) return SourceRange(QualifierRange.getBegin(), NameLoc);
+ return SourceRange(NameLoc, NameLoc);
+ }
+
+ virtual StmtIterator child_begin();
+ virtual StmtIterator child_end();
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedLookupExprClass;
+ }
+ static bool classof(const UnresolvedLookupExpr *) { return true; }
+};
+
/// \brief A qualified reference to a name whose declaration cannot
/// yet be resolved.
///
-/// DependentScopeDeclRefExpr is similar to eclRefExpr in that
+/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
/// it expresses a reference to a declaration such as
/// X<T>::value. The difference, however, is that an
/// DependentScopeDeclRefExpr node is used only within C++ templates when
@@ -1377,9 +1423,9 @@ public:
virtual child_iterator child_end();
};
-/// \brief Represents a C++ member access expression where the actual member
-/// referenced could not be resolved, e.g., because the base expression or the
-/// member name was dependent.
+/// \brief Represents a C++ member access expression where the actual
+/// member referenced could not be resolved because the base
+/// expression or the member name was dependent.
class CXXDependentScopeMemberExpr : public Expr {
/// \brief The expression for the base pointer or class reference,
/// e.g., the \c x in x.f.
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 2001fed87c..31fbae17e3 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -125,7 +125,7 @@ EXPR(CXXConditionDeclExpr , DeclRefExpr)
EXPR(CXXNewExpr , Expr)
EXPR(CXXDeleteExpr , Expr)
EXPR(CXXPseudoDestructorExpr, Expr)
-EXPR(UnresolvedFunctionNameExpr , Expr)
+EXPR(UnresolvedLookupExpr , Expr)
EXPR(UnaryTypeTraitExpr , Expr)
EXPR(DependentScopeDeclRefExpr , Expr)
EXPR(TemplateIdRefExpr , Expr)
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index a21c93ffcd..94621aa1f6 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -36,8 +36,6 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
HasTrivialDestructor(true), ComputedVisibleConversions(false),
Bases(0), NumBases(0), VBases(0), NumVBases(0),
- Conversions(DC, DeclarationName()),
- VisibleConversions(DC, DeclarationName()),
TemplateOrInstantiation() { }
CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
@@ -299,14 +297,11 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
void
CXXRecordDecl::collectConversionFunctions(
- llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet)
+ llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const
{
- OverloadedFunctionDecl *TopConversions = getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator
- TFunc = TopConversions->function_begin(),
- TFuncEnd = TopConversions->function_end();
- TFunc != TFuncEnd; ++TFunc) {
- NamedDecl *TopConv = TFunc->get();
+ const UnresolvedSet *Cs = getConversionFunctions();
+ for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ NamedDecl *TopConv = *I;
CanQualType TConvType;
if (FunctionTemplateDecl *TConversionTemplate =
dyn_cast<FunctionTemplateDecl>(TopConv))
@@ -336,14 +331,11 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
bool inTopClass = (RD == this);
QualType ClassType = getASTContext().getTypeDeclType(this);
if (const RecordType *Record = ClassType->getAs<RecordType>()) {
- OverloadedFunctionDecl *Conversions
+ const UnresolvedSet *Cs
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator
- Func = Conversions->function_begin(),
- FuncEnd = Conversions->function_end();
- Func != FuncEnd; ++Func) {
- NamedDecl *Conv = Func->get();
+ for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ NamedDecl *Conv = *I;
// Only those conversions not exact match of conversions in current
// class are candidateconversion routines.
CanQualType ConvType;
@@ -405,8 +397,7 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
-OverloadedFunctionDecl *
-CXXRecordDecl::getVisibleConversionFunctions() {
+const UnresolvedSet *CXXRecordDecl::getVisibleConversionFunctions() {
// If root class, all conversions are visible.
if (bases_begin() == bases_end())
return &Conversions;
@@ -425,26 +416,26 @@ void CXXRecordDecl::addVisibleConversionFunction(
CXXConversionDecl *ConvDecl) {
assert(!ConvDecl->getDescribedFunctionTemplate() &&
"Conversion function templates should cast to FunctionTemplateDecl.");
- VisibleConversions.addOverload(ConvDecl);
+ VisibleConversions.addDecl(ConvDecl);
}
void CXXRecordDecl::addVisibleConversionFunction(
FunctionTemplateDecl *ConvDecl) {
assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
"Function template is not a conversion function template");
- VisibleConversions.addOverload(ConvDecl);
+ VisibleConversions.addDecl(ConvDecl);
}
void CXXRecordDecl::addConversionFunction(CXXConversionDecl *ConvDecl) {
assert(!ConvDecl->getDescribedFunctionTemplate() &&
"Conversion function templates should cast to FunctionTemplateDecl.");
- Conversions.addOverload(ConvDecl);
+ Conversions.addDecl(ConvDecl);
}
void CXXRecordDecl::addConversionFunction(FunctionTemplateDecl *ConvDecl) {
assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
"Function template is not a conversion function template");
- Conversions.addOverload(ConvDecl);
+ Conversions.addDecl(ConvDecl);
}
CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 12bfee7a91..be613dc823 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -46,6 +46,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
(HasExplicitTemplateArgumentList?
HasExplicitTemplateArgumentListFlag : 0)),
Loc(NameLoc) {
+ assert(!isa<OverloadedFunctionDecl>(D));
if (Qualifier) {
NameQualifier *NQ = getNameQualifier();
NQ->NNS = Qualifier;
@@ -1096,6 +1097,8 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
return LV_Valid;
case PredefinedExprClass:
return LV_Valid;
+ case UnresolvedLookupExprClass:
+ return LV_Valid;
case CXXDefaultArgExprClass:
return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx);
case CXXConditionDeclExprClass:
@@ -1500,7 +1503,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
case Expr::CXXNewExprClass:
case Expr::CXXDeleteExprClass:
case Expr::CXXPseudoDestructorExprClass:
- case Expr::UnresolvedFunctionNameExprClass:
+ case Expr::UnresolvedLookupExprClass:
case Expr::DependentScopeDeclRefExprClass:
case Expr::TemplateIdRefExprClass:
case Expr::CXXConstructExprClass:
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 06f2a29b2d..cf75838692 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -121,11 +121,11 @@ Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
return &Base + 1;
}
-// UnresolvedFunctionNameExpr
-Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() {
+// UnresolvedLookupExpr
+Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
return child_iterator();
}
-Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() {
+Stmt::child_iterator UnresolvedLookupExpr::child_end() {
return child_iterator();
}
// UnaryTypeTraitExpr
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0bf6b32564..34ca798579 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -489,6 +489,10 @@ void StmtPrinter::VisitDependentScopeDeclRefExpr(
OS << Node->getDeclName().getAsString();
}
+void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
+ OS << Node->getName().getAsString();
+}
+
void StmtPrinter::VisitTemplateIdRefExpr(TemplateIdRefExpr *Node) {
if (Node->getQualifier())
Node->getQualifier()->print(OS, Policy);
@@ -1119,10 +1123,6 @@ void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
OS << TypeS;
}
-void StmtPrinter::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *E) {
- OS << E->getName().getAsString();
-}
-
void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
// Nothing to print.
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index e9f6cee115..f238451465 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -515,7 +515,7 @@ void StmtProfiler::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *S) {
}
void
-StmtProfiler::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *S) {
+StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
VisitExpr(S);
VisitName(S->getName());
}
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
index 10cc818b8b..6366a4c854 100644
--- a/lib/Sema/Lookup.h
+++ b/lib/Sema/Lookup.h
@@ -280,6 +280,12 @@ public:
/// ambiguous and overloaded lookups.
NamedDecl *getAsSingleDecl(ASTContext &Context) const;
+ template <class DeclClass>
+ DeclClass *getAsSingle() const {
+ if (getResultKind() != Found) return 0;
+ return dyn_cast<DeclClass>(getFoundDecl());
+ }
+
/// \brief Fetch the unique decl found by this lookup. Asserts
/// that one was found.
///
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index e0c3f13576..e26df119fa 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -959,7 +959,7 @@ public:
bool Complain);
Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
- void AddOverloadedCallCandidates(NamedDecl *Callee,
+ void AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*>& Callees,
DeclarationName &UnqualifiedName,
bool &ArgumentDependentLookup,
bool HasExplicitTemplateArgs,
@@ -969,7 +969,8 @@ public:
OverloadCandidateSet &CandidateSet,
bool PartialOverloading = false);
- FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
+ FunctionDecl *ResolveOverloadedCallFn(Expr *Fn,
+ llvm::SmallVectorImpl<NamedDecl*> &Fns,
DeclarationName UnqualifiedName,
bool HasExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
@@ -1415,10 +1416,18 @@ public:
bool HasTrailingLParen,
const CXXScopeSpec *SS,
bool isAddressOfOperand = false);
- OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
- bool HasTrailingLParen,
- const CXXScopeSpec *SS,
+ OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+ LookupResult &R, bool ADL,
bool isAddressOfOperand);
+ OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+ SourceLocation Loc,
+ DeclarationName Name,
+ bool NeedsADL,
+ NamedDecl * const *Decls,
+ unsigned NumDecls);
+ OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+ SourceLocation Loc,
+ NamedDecl *D);
virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind);
@@ -1517,7 +1526,7 @@ public:
SourceLocation RParenLoc);
void DeconstructCallFunction(Expr *FnExpr,
- NamedDecl *&Function,
+ llvm::SmallVectorImpl<NamedDecl*>& Fns,
DeclarationName &Name,
NestedNameSpecifier *&Qualifier,
SourceRange &QualifierRange,
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 6dbb4426c2..203b421c91 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1467,7 +1467,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
Expr::hasAnyTypeDependentArguments(Args, NumArgs))
return;
- NamedDecl *Function;
+ llvm::SmallVector<NamedDecl*,8> Fns;
DeclarationName UnqualifiedName;
NestedNameSpecifier *Qualifier;
SourceRange QualifierRange;
@@ -1476,8 +1476,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
const TemplateArgumentLoc *ExplicitTemplateArgs;
unsigned NumExplicitTemplateArgs;
- DeconstructCallFunction(Fn,
- Function, UnqualifiedName, Qualifier, QualifierRange,
+ DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
ArgumentDependentLookup, HasExplicitTemplateArgs,
ExplicitTemplateArgs, NumExplicitTemplateArgs);
@@ -1488,7 +1487,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
// Build an overload candidate set based on the functions we find.
OverloadCandidateSet CandidateSet;
- AddOverloadedCallCandidates(Function, UnqualifiedName,
+ AddOverloadedCallCandidates(Fns, UnqualifiedName,
ArgumentDependentLookup, HasExplicitTemplateArgs,
ExplicitTemplateArgs, NumExplicitTemplateArgs,
Args, NumArgs,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 45870a19e4..95a57436e1 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2601,16 +2601,8 @@ Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
if (FunctionTemplateDecl *ConversionTemplate
= Conversion->getDescribedFunctionTemplate())
ExpectedPrevDecl = ConversionTemplate->getPreviousDeclaration();
- OverloadedFunctionDecl *Conversions = ClassDecl->getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator
- Conv = Conversions->function_begin(),
- ConvEnd = Conversions->function_end();
- Conv != ConvEnd; ++Conv) {
- if (*Conv == ExpectedPrevDecl) {
- *Conv = Conversion;
- return DeclPtrTy::make(Conversion);
- }
- }
+ if (ClassDecl->replaceConversion(ExpectedPrevDecl, Conversion))
+ return DeclPtrTy::make(Conversion);
assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
} else if (FunctionTemplateDecl *ConversionTemplate
= Conversion->getDescribedFunctionTemplate())
@@ -3895,18 +3887,17 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
OverloadCandidateSet CandidateSet;
- OverloadedFunctionDecl *Conversions
+ const UnresolvedSet *Conversions
= T2RecordDecl->getVisibleConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator Func
- = Conversions->function_begin();
- Func != Conversions->function_end(); ++Func) {
+ for (UnresolvedSet::iterator I = Conversions->begin(),
+ E = Conversions->end(); I != E; ++I) {
FunctionTemplateDecl *ConvTemplate
- = dyn_cast<FunctionTemplateDecl>(*Func);
+ = dyn_cast<FunctionTemplateDecl>(*I);
CXXConversionDecl *Conv;
if (ConvTemplate)
Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
else
- Conv = cast<CXXConversionDecl>(*Func);
+ Conv = cast<CXXConversionDecl>(*I);
// If the conversion function doesn't return a reference type,
// it can't be considered for this conversion.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 789519368b..12e0c592e0 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -417,6 +417,8 @@ Sema::OwningExprResult
Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
bool TypeDependent, bool ValueDependent,
const CXXScopeSpec *SS) {
+ assert(!isa<OverloadedFunctionDecl>(D));
+
if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
Diag(Loc,
diag::err_auto_variable_cannot_appear_in_own_initializer)
@@ -688,8 +690,6 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
if (Lookup.isAmbiguous())
return ExprError();
- NamedDecl *D = Lookup.getAsSingleDecl(Context);
-
// If this reference is in an Objective-C method, then ivar lookup happens as
// well.
IdentifierInfo *II = Name.getAsIdentifierInfo();
@@ -699,44 +699,58 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// found a decl, but that decl is outside the current instance method (i.e.
// a global variable). In these two cases, we do a lookup for an ivar with
// this name, if the lookup sucedes, we replace it our current decl.
- if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
+
+ // FIXME: we should change lookup to do this.
+
+ // If we're in a class method, we don't normally want to look for
+ // ivars. But if we don't find anything else, and there's an
+ // ivar, that's an error.
+ bool IsClassMethod = getCurMethodDecl()->isClassMethod();
+
+ bool LookForIvars;
+ if (Lookup.empty())
+ LookForIvars = true;
+ else if (IsClassMethod)
+ LookForIvars = false;
+ else
+ LookForIvars = (Lookup.isSingleResult() &&
+ Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
+
+ if (LookForIvars) {
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
ObjCInterfaceDecl *ClassDeclared;
if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
- // Check if referencing a field with __attribute__((deprecated)).
- if (DiagnoseUseOfDecl(IV, Loc))
- return ExprError();
+ // Diagnose using an ivar in a class method.
+ if (IsClassMethod)
+ return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
+ << IV->getDeclName());
// If we're referencing an invalid decl, just return this as a silent
// error node. The error diagnostic was already emitted on the decl.
if (IV->isInvalidDecl())
return ExprError();
- bool IsClsMethod = getCurMethodDecl()->isClassMethod();
- // If a class method attemps to use a free standing ivar, this is
- // an error.
- if (IsClsMethod && D && !D->isDefinedOutsideFunctionOrMethod())
- return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
- << IV->getDeclName());
- // If a class method uses a global variable, even if an ivar with
- // same name exists, use the global.
- if (!IsClsMethod) {
- if (IV->getAccessControl() == ObjCIvarDecl::Private &&
- ClassDeclared != IFace)
- Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName();
- // FIXME: This should use a new expr for a direct reference, don't
- // turn this into Self->ivar, just return a BareIVarExpr or something.
- IdentifierInfo &II = Context.Idents.get("self");
- UnqualifiedId SelfName;
- SelfName.setIdentifier(&II, SourceLocation());
- CXXScopeSpec SelfScopeSpec;
- OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
- SelfName, false, false);
- MarkDeclarationReferenced(Loc, IV);
- return Owned(new (Context)
- ObjCIvarRefExpr(IV, IV->getType(), Loc,
- SelfExpr.takeAs<Expr>(), true, true));
- }
+ // Check if referencing a field with __attribute__((deprecated)).
+ if (DiagnoseUseOfDecl(IV, Loc))
+ return ExprError();
+
+ // Diagnose the use of an ivar outside of the declaring class.
+ if (IV->getAccessControl() == ObjCIvarDecl::Private &&
+ ClassDeclared != IFace)
+ Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName();
+
+ // FIXME: This should use a new expr for a direct reference, don't
+ // turn this into Self->ivar, just return a BareIVarExpr or something.
+ IdentifierInfo &II = Context.Idents.get("self");
+ UnqualifiedId SelfName;
+ SelfName.setIdentifier(&II, SourceLocation());
+ CXXScopeSpec SelfScopeSpec;
+ OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+ SelfName, false, false);
+ MarkDeclarationReferenced(Loc, IV);
+ return Owned(new (Context)
+ ObjCIvarRefExpr(IV, IV->getType(), Loc,
+ SelfExpr.takeAs<Expr>(), true, true));
}
} else if (getCurMethodDecl()->isInstanceMethod()) {
// We should warn if a local variable hides an ivar.
@@ -749,7 +763,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
}
}