diff options
author | John McCall <rjmccall@apple.com> | 2009-11-21 08:51:07 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-11-21 08:51:07 +0000 |
commit | ba13543329afac4a0d01304ec2ec4924d99306a6 (patch) | |
tree | 1533ccfa9a4fd586085e95f50ba52907d89bcd69 | |
parent | bbd37c62e34db3f5a95c899723484a76c71d7757 (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.h | 46 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 146 | ||||
-rw-r--r-- | include/clang/AST/StmtNodes.def | 2 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 33 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 5 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 6 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 8 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Lookup.h | 6 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 21 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 23 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 438 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 42 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 296 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 98 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 33 | ||||
-rw-r--r-- | test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp | 4 | ||||
-rw-r--r-- | test/SemaObjC/ivar-ref-misuse.m | 2 |
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, } } |