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 | d14a86427f9cd8e5bc1a114b703f21cf21eefa9c (patch) | |
tree | 314e55fa377fd7a883e71b581792dc4d2f5cd424 /clang/lib | |
parent | 96d5c76498b26bdf6e6ded4f166085a11c1738a4 (diff) | |
download | bcm5719-llvm-d14a86427f9cd8e5bc1a114b703f21cf21eefa9c.tar.gz bcm5719-llvm-d14a86427f9cd8e5bc1a114b703f21cf21eefa9c.zip |
"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.
llvm-svn: 89544
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 33 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/Lookup.h | 6 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 21 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 23 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 438 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 42 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 296 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 98 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 33 |
15 files changed, 583 insertions, 451 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index a21c93ffcdc..94621aa1f69 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/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/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 12bfee7a91d..be613dc8230 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/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/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 06f2a29b2d4..cf758386927 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/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/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 0bf6b32564a..34ca7985798 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/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/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index e9f6cee1156..f238451465b 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/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/clang/lib/Sema/Lookup.h b/clang/lib/Sema/Lookup.h index 10cc818b8ba..6366a4c8546 100644 --- a/clang/lib/Sema/Lookup.h +++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index e0c3f135766..e26df119fa5 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 6dbb4426c20..203b421c913 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 45870a19e4c..95a57436e1f 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 789519368b1..12e0c592e05 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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, } } // Needed to implement property "super.method" notation. - if (D == 0 && II->isStr("super")) { + if (Lookup.empty() && II->isStr("super")) { QualType T; if (getCurMethodDecl()->isInstanceMethod()) @@ -766,26 +780,14 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) && HasTrailingLParen; - if (ADL && D == 0) { - // We've seen something of the form - // - // identifier( - // - // and we did not find any entity by the name - // "identifier". However, this identifier is still subject to - // argument-dependent lookup, so keep track of the name. - return Owned(new (Context) UnresolvedFunctionNameExpr(Name, - Context.OverloadTy, - Loc)); - } - - if (D == 0) { + if (Lookup.empty() && !ADL) { // Otherwise, this could be an implicitly declared function reference (legal // in C90, extension in C99). if (HasTrailingLParen && II && - !getLangOptions().CPlusPlus) // Not in C++. - D = ImplicitlyDefineFunction(Loc, *II, S); - else { + !getLangOptions().CPlusPlus) { // Not in C++. + NamedDecl *D = ImplicitlyDefineFunction(Loc, *II, S); + if (D) Lookup.addDecl(D); + } else { // If this name wasn't predeclared and if this is not a function call, // diagnose the problem. if (SS && !SS->isEmpty()) @@ -801,7 +803,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, } } - if (VarDecl *Var = dyn_cast<VarDecl>(D)) { + if (VarDecl *Var = Lookup.getAsSingle<VarDecl>()) { // Warn about constructs like: // if (void *X = foo()) { ... } else { X }. // In the else block, the pointer is always false. @@ -824,7 +826,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, CheckS = CheckS->getParent(); } } - } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) { + } else if (FunctionDecl *Func = Lookup.getAsSingle<FunctionDecl>()) { if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) { // C99 DR 316 says that, if a function type comes from a // function definition (without a prototype), that type is only @@ -842,8 +844,10 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, } } - return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand); + return BuildDeclarationNameExpr(SS, Lookup, HasTrailingLParen, + isAddressOfOperand); } + /// \brief Cast member's object to its own class if necessary. bool Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) { @@ -887,53 +891,28 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty); } -/// \brief Complete semantic analysis for a reference to the given declaration. -Sema::OwningExprResult -Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D, - bool HasTrailingLParen, - const CXXScopeSpec *SS, - bool isAddressOfOperand) { - assert(D && "Cannot refer to a NULL declaration"); - DeclarationName Name = D->getDeclName(); - - // If this is an expression of the form &Class::member, don't build an - // implicit member ref, because we want a pointer to the member in general, - // not any specific instance's member. - if (isAddressOfOperand && SS && !SS->isEmpty() && !HasTrailingLParen) { - DeclContext *DC = computeDeclContext(*SS); - if (D && isa<CXXRecordDecl>(DC)) { - QualType DType; - if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { - DType = FD->getType().getNonReferenceType(); - } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { - DType = Method->getType(); - } else if (isa<OverloadedFunctionDecl>(D)) { - DType = Context.OverloadTy; - } - // Could be an inner type. That's diagnosed below, so ignore it here. - if (!DType.isNull()) { - // The pointer is type- and value-dependent if it points into something - // dependent. - bool Dependent = DC->isDependentContext(); - return BuildDeclRefExpr(D, DType, Loc, Dependent, Dependent, SS); - } - } - } +/// Builds an implicit member access expression from the given +/// unqualified lookup set, which is known to contain only class +/// members. +Sema::OwningExprResult BuildImplicitMemberExpr(Sema &S, LookupResult &R, + const CXXScopeSpec *SS) { + NamedDecl *D = R.getAsSingleDecl(S.Context); + SourceLocation Loc = R.getNameLoc(); // We may have found a field within an anonymous union or struct // (C++ [class.union]). // FIXME: This needs to happen post-isImplicitMemberReference? if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion()) - return BuildAnonymousStructUnionMemberReference(Loc, FD); - - // Cope with an implicit member access in a C++ non-static member function. - QualType ThisType, MemberType; - if (isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) { - Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType); - MarkDeclarationReferenced(Loc, D); - if (PerformObjectMemberConversion(This, D)) - return ExprError(); + return S.BuildAnonymousStructUnionMemberReference(Loc, FD); + + QualType ThisType; + QualType MemberType; + if (S.isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) { + Expr *This = new (S.Context) CXXThisExpr(SourceLocation(), ThisType); + S.MarkDeclarationReferenced(Loc, D); + if (S.PerformObjectMemberConversion(This, D)) + return S.ExprError(); bool ShouldCheckUse = true; if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { @@ -943,45 +922,196 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D, ShouldCheckUse = false; } - if (ShouldCheckUse && DiagnoseUseOfDecl(D, Loc)) - return ExprError(); - return Owned(BuildMemberExpr(Context, This, true, SS, D, - Loc, MemberType)); + if (ShouldCheckUse && S.DiagnoseUseOfDecl(D, Loc)) + return S.ExprError(); + return S.Owned(BuildMemberExpr(S.Context, This, true, SS, D, + Loc, MemberType)); } - if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) { - if (MD->isStatic()) + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { + if (!Method->isStatic()) { + S.Diag(Loc, diag::err_member_call_without_object); + return S.ExprError(); + } + } + + if (isa<FieldDecl>(D)) { + if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S.CurContext)) { + if (MD->isStatic()) { // "invalid use of member 'x' in static member function" - return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method) - << FD->getDeclName()); + S.Diag(Loc,diag::err_invalid_member_use_in_static_method) + << D->getDeclName(); + return S.ExprError(); + } } // Any other ways we could have found the field in a well-formed // program would have been turned into implicit member expressions // above. - return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use) - << FD->getDeclName()); + S.Diag(Loc, diag::err_invalid_non_static_member_use) + << D->getDeclName(); + return S.ExprError(); + } + + return S.BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(), + /*ADL*/ false, + R.begin(), R.end() - R.begin()); +} + +static bool UseArgumentDependentLookup(Sema &SemaRef, + const CXXScopeSpec *SS, + bool HasTrailingLParen, + const LookupResult &R) { + // Only when used directly as the postfix-expression of a call. + if (!HasTrailingLParen) + return false; + + // Never if a scope specifier was provided. + if (SS && SS->isSet()) + return false; + + // Only in C++ or ObjC++. + if (!SemaRef.getLangOptions().CPlusPlus) + return false; + + // Turn off ADL when we find certain kinds of declarations during + // normal lookup: + for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { + NamedDecl *D = *I; + + // C++0x [basic.lookup.argdep]p3: + // -- a declaration of a class member + // Since using decls preserve this property, we check this on the + // original decl. + if (D->getDeclContext()->isRecord()) + return false; + + // C++0x [basic.lookup.argdep]p3: + // -- a block-scope function declaration that is not a + // using-declaration + // NOTE: we also trigger this for function templates (in fact, we + // don't check the decl type at all, since all other decl types + // turn off ADL anyway). + if (isa<UsingShadowDecl>(D)) + D = cast<UsingShadowDecl>(D)->getTargetDecl(); + else if (D->getDeclContext()->isFunctionOrMethod()) + return false; + + // C++0x [basic.lookup.argdep]p3: + // -- a declaration that is neither a function or a function + // template + // And also for builtin functions. + if (isa<FunctionDecl>(D)) { + FunctionDecl *FDecl = cast<FunctionDecl>(D); + + // But also builtin functions. + if (FDecl->getBuiltinID() && FDecl->isImplicit()) + return false; + } else if (!isa<FunctionTemplateDecl>(D)) + return false; + } + + return true; +} + + +/// \brief Complete semantic analysis for a reference to the given +/// lookup results. +Sema::OwningExprResult +Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS, + LookupResult &R, + bool HasTrailingLParen, + bool isAddressOfOperand) { + assert(!R.isAmbiguous() && "results are ambiguous"); + + // &SomeClass::foo is an abstract member reference, regardless of + // the nature of foo, but &SomeClass::foo(...) is not. + bool isAbstractMemberPointer = + (isAddressOfOperand && !HasTrailingLParen && SS && !SS->isEmpty()); + + // If we're *not* an abstract member reference, and any of the + // results are class members (i.e. they're all class members), then + // we make an implicit member reference instead. + if (!isAbstractMemberPointer && !R.empty() && + isa<CXXRecordDecl>((*R.begin())->getDeclContext())) { + return BuildImplicitMemberExpr(*this, R, SS); + } + + assert(R.getResultKind() != LookupResult::FoundUnresolvedValue && + "found UnresolvedUsingValueDecl in non-class scope"); + + bool ADL = UseArgumentDependentLookup(*this, SS, HasTrailingLParen, R); + + return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(), ADL, + R.begin(), R.end() - R.begin()); +} + +/// Diagnoses obvious problems with the use of the given declaration +/// as an expression. This is only actually called for lookups that +/// were not overloaded, and it doesn't promise that the declaration +/// will in fact be used. +static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) { + if (isa<TypedefDecl>(D)) { + S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName(); + return true; + } + + if (isa<ObjCInterfaceDecl>(D)) { + S.Diag(Loc, diag::err_unexpected_interface) << D->getDeclName(); + return true; } - if (isa<TypedefDecl>(D)) - return ExprError(Diag(Loc, diag::err_unexpected_typedef) << Name); - if (isa<ObjCInterfaceDecl>(D)) - return ExprError(Diag(Loc, diag::err_unexpected_interface) << Name); - if (isa<NamespaceDecl>(D)) - return ExprError(Diag(Loc, diag::err_unexpected_namespace) << Name); + if (isa<NamespaceDecl>(D)) { + S.Diag(Loc, diag::err_unexpected_namespace) << D->getDeclName(); + return true; + } + + return false; +} + +Sema::OwningExprResult +Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS, + SourceLocation Loc, + DeclarationName Name, + bool NeedsADL, + NamedDecl * const *Decls, + unsigned NumDecls) { + if (!NeedsADL && NumDecls == 1) + return BuildDeclarationNameExpr(SS, Loc, Decls[0]->getUnderlyingDecl()); + + // We only need to check the declaration if there's exactly one + // result, because in the overloaded case the results can only be + // functions and function templates. + if (NumDecls == 1 && + CheckDeclInExpr(*this, Loc, Decls[0]->getUnderlyingDecl())) + return ExprError(); + + UnresolvedLookupExpr *ULE + = UnresolvedLookupExpr::Create(Context, + SS ? (NestedNameSpecifier *)SS->getScopeRep() : 0, + SS ? SS->getRange() : SourceRange(), + Name, Loc, NeedsADL); + for (unsigned I = 0; I != NumDecls; ++I) + ULE->addDecl(Decls[I]); + + return Owned(ULE); +} + + +/// \brief Complete semantic analysis for a reference to the given declaration. +Sema::OwningExprResult +Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS, + SourceLocation Loc, NamedDecl *D) { + assert(D && "Cannot refer to a NULL declaration"); + DeclarationName Name = D->getDeclName(); + + if (CheckDeclInExpr(*this, Loc, D)) + return ExprError(); // Make the DeclRefExpr or BlockDeclRefExpr for the decl. - if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) - return BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc, - false, false, SS); - else if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) + if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) return BuildDeclRefExpr(Template, Context.OverloadTy, Loc, false, false, SS); - else if (UnresolvedUsingValueDecl *UD = dyn_cast<UnresolvedUsingValueDecl>(D)) - return BuildDeclRefExpr(UD, Context.DependentTy, Loc, - /*TypeDependent=*/true, - /*ValueDependent=*/true, SS); ValueDecl *VD = cast<ValueDecl>(D); @@ -989,9 +1119,7 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D, // this check when we're going to perform argument-dependent lookup // on this function name, because this might not be the function // that overload resolution actually selects. - bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) && - HasTrailingLParen; - if (!(ADL && isa<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc)) + if (DiagnoseUseOfDecl(VD, Loc)) return ExprError(); // Only create DeclRefExpr's for valid Decl's. @@ -1038,9 +1166,8 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D, TypeDependent = true; // - a nested-name-specifier that contains a class-name that // names a dependent type. - else if (SS && !SS->isEmpty()) { - for (DeclContext *DC = computeDeclContext(*SS); - DC; DC = DC->getParent()) { + else { + for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) { // FIXME: could stop early at namespace scope. if (DC->isRecord()) { CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); @@ -2557,7 +2684,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, /// whether argument-dependent lookup is available, whether it has explicit /// template arguments, etc. void Sema::DeconstructCallFunction(Expr *FnExpr, - NamedDecl *&Function, + llvm::SmallVectorImpl<NamedDecl*> &Fns, DeclarationName &Name, NestedNameSpecifier *&Qualifier, SourceRange &QualifierRange, @@ -2566,7 +2693,6 @@ void Sema::DeconstructCallFunction(Expr *FnExpr, const TemplateArgumentLoc *&ExplicitTemplateArgs, unsigned &NumExplicitTemplateArgs) { // Set defaults for all of the output parameters. - Function = 0; Name = DeclarationName(); Qualifier = 0; QualifierRange = SourceRange(); @@ -2589,21 +2715,29 @@ void Sema::DeconstructCallFunction(Expr *FnExpr, == UnaryOperator::AddrOf) { FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr(); } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) { - Function = dyn_cast<NamedDecl>(DRExpr->getDecl()); - if ((Qualifier = DRExpr->getQualifier())) { - ArgumentDependentLookup = false; + Fns.push_back(cast<NamedDecl>(DRExpr->getDecl())); + ArgumentDependentLookup = false; + if ((Qualifier = DRExpr->getQualifier())) QualifierRange = DRExpr->getQualifierRange(); - } break; - } else if (UnresolvedFunctionNameExpr *DepName - = dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) { - Name = DepName->getName(); + } else if (UnresolvedLookupExpr *UnresLookup + = dyn_cast<UnresolvedLookupExpr>(FnExpr)) { + Name = UnresLookup->getName(); + Fns.append(UnresLookup->decls_begin(), UnresLookup->decls_end()); + ArgumentDependentLookup = UnresLookup->requiresADL(); + if ((Qualifier = UnresLookup->getQualifier())) + QualifierRange = UnresLookup->getQualifierRange(); break; } else if (TemplateIdRefExpr *TemplateIdRef = dyn_cast<TemplateIdRefExpr>(FnExpr)) { - Function = TemplateIdRef->getTemplateName().getAsTemplateDecl(); - if (!Function) - Function = TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl(); + if (NamedDecl *Function + = TemplateIdRef->getTemplateName().getAsTemplateDecl()) + Fns.push_back(Function); + else { + OverloadedFunctionDecl *Overload + = TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl(); + Fns.append(Overload->function_begin(), Overload->function_end()); + } HasExplicitTemplateArguments = true; ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs(); NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs(); @@ -2653,9 +2787,6 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, Expr *Fn = fn.takeAs<Expr>(); Expr **Args = reinterpret_cast<Expr**>(args.release()); assert(Fn && "no function call expression"); - FunctionDecl *FDecl = NULL; - NamedDecl *NDecl = NULL; - DeclarationName UnqualifiedName; if (getLangOptions().CPlusPlus) { // If this is a pseudo-destructor expression, build the call immediately. @@ -2742,39 +2873,43 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, // If we're directly calling a function, get the appropriate declaration. // Also, in C++, keep track of whether we should perform argument-dependent // lookup and whether there were any explicitly-specified template arguments. + llvm::SmallVector<NamedDecl*,8> Fns; + DeclarationName UnqualifiedName; bool ADL = true; bool HasExplicitTemplateArgs = 0; const TemplateArgumentLoc *ExplicitTemplateArgs = 0; unsigned NumExplicitTemplateArgs = 0; NestedNameSpecifier *Qualifier = 0; SourceRange QualifierRange; - DeconstructCallFunction(Fn, NDecl, UnqualifiedName, Qualifier, QualifierRange, + DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange, ADL,HasExplicitTemplateArgs, ExplicitTemplateArgs, NumExplicitTemplateArgs); - OverloadedFunctionDecl *Ovl = 0; + NamedDecl *NDecl = 0; // the specific declaration we're calling, if applicable + FunctionDecl *FDecl = 0; // same, if it's a function or function template FunctionTemplateDecl *FunctionTemplate = 0; - if (NDecl) { + + if (Fns.size() == 1) { + NDecl = Fns[0]; FDecl = dyn_cast<FunctionDecl>(NDecl); if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(NDecl))) FDecl = FunctionTemplate->getTemplatedDecl(); else FDecl = dyn_cast<FunctionDecl>(NDecl); - Ovl = dyn_cast<OverloadedFunctionDecl>(NDecl); } - if (Ovl || FunctionTemplate || + if (Fns.size() > 1 || FunctionTemplate || (getLangOptions().CPlusPlus && (FDecl || UnqualifiedName))) { // We don't perform ADL for implicit declarations of builtins. if (FDecl && FDecl->getBuiltinID() && FDecl->isImplicit()) - ADL = false; + assert(!ADL); // this should be guaranteed earlier // We don't perform ADL in C. if (!getLangOptions().CPlusPlus) - ADL = false; + assert(!ADL); // ditto - if (Ovl || FunctionTemplate || ADL) { - FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName, + if (Fns.size() > 1 || FunctionTemplate || ADL) { + FDecl = ResolveOverloadedCallFn(Fn, Fns, UnqualifiedName, HasExplicitTemplateArgs, ExplicitTemplateArgs, NumExplicitTemplateArgs, @@ -2784,6 +2919,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, return ExprError(); Fn = FixOverloadedFunctionReference(Fn, FDecl); + + NDecl = FDecl; } } @@ -5123,6 +5260,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { // FIXME: Can LHS ever be null here? if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull()) return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc); + } else if (isa<UnresolvedLookupExpr>(op)) { + return Context.OverloadTy; } else if (dcl) { // C99 6.5.3.2p1 // We have an lvalue with a decl. Make sure the decl is not declared // with the register storage-class specifier. @@ -5132,8 +5271,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) { << "register variable" << op->getSourceRange(); return QualType(); } - } else if (isa<OverloadedFunctionDecl>(dcl) || - isa<FunctionTemplateDecl>(dcl)) { + } else if (isa<FunctionTemplateDecl>(dcl)) { return Context.OverloadTy; } else if (FieldDecl *FD = dyn_cast<FieldDecl>(dcl)) { // Okay: we can take the address of a field. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index be9375c495b..790c849b93f 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -855,18 +855,15 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, if (const RecordType *Record = Type->getAs<RecordType>()) { llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions; CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); - OverloadedFunctionDecl *Conversions = - RD->getVisibleConversionFunctions(); + const UnresolvedSet *Conversions = RD->getVisibleConversionFunctions(); - for (OverloadedFunctionDecl::function_iterator - Func = Conversions->function_begin(), - FuncEnd = Conversions->function_end(); - Func != FuncEnd; ++Func) { + for (UnresolvedSet::iterator I = Conversions->begin(), + E = Conversions->end(); I != E; ++I) { // Skip over templated conversion functions; they aren't considered. - if (isa<FunctionTemplateDecl>(*Func)) + if (isa<FunctionTemplateDecl>(*I)) continue; - CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func); + CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I); QualType ConvType = Conv->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) @@ -2310,6 +2307,9 @@ bool Sema::isImplicitMemberReference(const CXXScopeSpec *SS, NamedDecl *D, MemberType = Context.getQualifiedType(MemberType, Qualifiers::fromCVRMask(MD->getTypeQualifiers())); + } else if (isa<UnresolvedUsingValueDecl>(D)) { + Ctx = D->getDeclContext(); + MemberType = Context.DependentTy; } else { for (OverloadIterator Ovl(D), OvlEnd; Ovl != OvlEnd; ++Ovl) { CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Ovl); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 1957d7ff11b..99f9f55249e 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1525,33 +1525,29 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs, // in which the function or function template is defined and the // classes and namespaces associated with its (non-dependent) // parameter types and return type. - DeclRefExpr *DRE = 0; - TemplateIdRefExpr *TIRE = 0; Arg = Arg->IgnoreParens(); - if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg)) { - if (unaryOp->getOpcode() == UnaryOperator::AddrOf) { - DRE = dyn_cast<DeclRefExpr>(unaryOp->getSubExpr()); - TIRE = dyn_cast<TemplateIdRefExpr>(unaryOp->getSubExpr()); - } - } else { - DRE = dyn_cast<DeclRefExpr>(Arg); - TIRE = dyn_cast<TemplateIdRefExpr>(Arg); - } - - OverloadedFunctionDecl *Ovl = 0; - if (DRE) - Ovl = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl()); - else if (TIRE) - Ovl = TIRE->getTemplateName().getAsOverloadedFunctionDecl(); - if (!Ovl) + if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg)) + if (unaryOp->getOpcode() == UnaryOperator::AddrOf) + Arg = unaryOp->getSubExpr(); + + // TODO: avoid the copies. This should be easy when the cases + // share a storage implementation. + llvm::SmallVector<NamedDecl*, 8> Functions; + + if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg)) + Functions.append(ULE->decls_begin(), ULE->decls_end()); + else if (TemplateIdRefExpr *TIRE = dyn_cast<TemplateIdRefExpr>(Arg)) { + TemplateName TName = TIRE->getTemplateName(); + OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl(); + Functions.append(Ovl->function_begin(), Ovl->function_end()); + } else continue; - for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(), - FuncEnd = Ovl->function_end(); - Func != FuncEnd; ++Func) { - FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*Func); + for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Functions.begin(), + E = Functions.end(); I != E; ++I) { + FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I); if (!FDecl) - FDecl = cast<FunctionTemplateDecl>(*Func)->getTemplatedDecl(); + FDecl = cast<FunctionTemplateDecl>(*I)->getTemplatedDecl(); // Add the namespace in which this function was defined. Note // that, if this is a member function, we do *not* consider the diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8d479606aa7..45729116c3e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1353,18 +1353,6 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) { return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType); } -/// \brief Given a function template or function, extract the function template -/// declaration (if any) and the underlying function declaration. -template<typename T> -static void GetFunctionAndTemplate(AnyFunctionDecl Orig, T *&Function, - FunctionTemplateDecl *&FunctionTemplate) { - FunctionTemplate = dyn_cast<FunctionTemplateDecl>(Orig); - if (FunctionTemplate) - Function = cast<T>(FunctionTemplate->getTemplatedDecl()); - else - Function = cast<T>(Orig); -} - /// Determines whether there is a user-defined conversion sequence /// (C++ [over.ics.user]) that converts expression From to the type /// ToType. If such a conversion exists, User will contain the @@ -1455,18 +1443,16 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion( if (CXXRecordDecl *FromRecordDecl = dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) { // Add all of the conversion functions as candidates. - OverloadedFunctionDecl *Conversions + const UnresolvedSet *Conversions = FromRecordDecl->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) { CXXConversionDecl *Conv; FunctionTemplateDecl *ConvTemplate; - GetFunctionAndTemplate(*Func, Conv, ConvTemplate); - if (ConvTemplate) + if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(*I))) Conv = dyn_cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl()); else - Conv = dyn_cast<CXXConversionDecl>(*Func); + Conv = dyn_cast<CXXConversionDecl>(*I); if (AllowExplicit || !Conv->isExplicit()) { if (ConvTemplate) @@ -3144,20 +3130,17 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, } CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl()); - OverloadedFunctionDecl *Conversions + const UnresolvedSet *Conversions = ClassDecl->getVisibleConversionFunctions(); - for (OverloadedFunctionDecl::function_iterator Func - = Conversions->function_begin(); - Func != Conversions->function_end(); ++Func) { - CXXConversionDecl *Conv; - FunctionTemplateDecl *ConvTemplate; - GetFunctionAndTemplate(*Func, Conv, ConvTemplate); + for (UnresolvedSet::iterator I = Conversions->begin(), + E = Conversions->end(); I != E; ++I) { // Skip conversion function templates; they don't tell us anything // about which builtin types we can convert to. - if (ConvTemplate) + if (isa<FunctionTemplateDecl>(*I)) continue; + CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I); if (AllowExplicitConversions || !Conv->isExplicit()) { AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false, VisibleQuals); @@ -3211,13 +3194,12 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) { } CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl()); - OverloadedFunctionDecl *Conversions = + const UnresolvedSet *Conversions = ClassDecl->getVisibleConversionFunctions(); - for (OverloadedFunctionDecl::function_iterator Func - = Conversions->function_begin(); - Func != Conversions->function_end(); ++Func) { - if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*Func)) { + for (UnresolvedSet::iterator I = Conversions->begin(), + E = Conversions->end(); I != E; ++I) { + if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*I)) { QualType CanTy = Context.getCanonicalType(Conv->getConversionType()); if (const ReferenceType *ResTypeRef = CanTy->getAs<ReferenceType>()) CanTy = ResTypeRef->getPointeeType(); @@ -4336,7 +4318,6 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, return 0; // Find the actual overloaded function declaration. - OverloadedFunctionDecl *Ovl = 0; // C++ [over.over]p1: // [...] [Note: any redundant set of parentheses surrounding the @@ -4354,15 +4335,21 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, bool HasExplicitTemplateArgs = false; const TemplateArgumentLoc *ExplicitTemplateArgs = 0; unsigned NumExplicitTemplateArgs = 0; + + llvm::SmallVector<NamedDecl*,8> Fns; // Try to dig out the overloaded function. + OverloadedFunctionDecl *Ovl = 0; FunctionTemplateDecl *FunctionTemplate = 0; if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OvlExpr)) { - Ovl = dyn_cast<OverloadedFunctionDecl>(DR->getDecl()); + assert(!isa<OverloadedFunctionDecl>(DR->getDecl())); FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DR->getDecl()); HasExplicitTemplateArgs = DR->hasExplicitTemplateArgumentList(); ExplicitTemplateArgs = DR->getTemplateArgs(); NumExplicitTemplateArgs = DR->getNumTemplateArgs(); + } else if (UnresolvedLookupExpr *UL + = dyn_cast<UnresolvedLookupExpr>(OvlExpr)) { + Fns.append(UL->decls_begin(), UL->decls_end()); } else if (MemberExpr *ME = dyn_cast<MemberExpr>(OvlExpr)) { Ovl = dyn_cast<OverloadedFunctionDecl>(ME->getMemberDecl()); FunctionTemplate = dyn_cast<FunctionTemplateDecl>(ME->getMemberDecl()); @@ -4379,23 +4366,20 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, ExplicitTemplateArgs = TIRE->getTemplateArgs(); NumExplicitTemplateArgs = TIRE->getNumTemplateArgs(); } - - // If there's no overloaded function declaration or function template, - // we're done. - if (!Ovl && !FunctionTemplate) - return 0; - OverloadIterator Fun; - if (Ovl) - Fun = Ovl; - else - Fun = FunctionTemplate; + if (Ovl) Fns.append(Ovl->function_begin(), Ovl->function_end()); + if (FunctionTemplate) Fns.push_back(FunctionTemplate); + + // If we didn't actually find anything, we're done. + if (Fns.empty()) + return 0; // Look through all of the overloaded functions, searching for one // whose type matches exactly. llvm::SmallPtrSet<FunctionDecl *, 4> Matches; bool FoundNonTemplateFunction = false; - for (OverloadIterator FunEnd; Fun != FunEnd; ++Fun) { + for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(), + E = Fns.end(); I != E; ++I) { // C++ [over.over]p3: // Non-member functions and static member functions match // targets of type "pointer-to-function" or "reference-to-function." @@ -4404,7 +4388,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, // Note that according to DR 247, the containing class does not matter. if (FunctionTemplateDecl *FunctionTemplate - = dyn_cast<FunctionTemplateDecl>(*Fun)) { + = dyn_cast<FunctionTemplateDecl>(*I)) { if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) { // Skip non-static function templates when converting to pointer, and @@ -4438,9 +4422,11 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, Matches.insert( cast<FunctionDecl>(Specialization->getCanonicalDecl())); } + + continue; } - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Fun)) { + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) { // Skip non-static functions when converting to pointer, and static // when converting to member pointer. if (Method->isStatic() == IsMember) @@ -4452,9 +4438,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, } else if (IsMember) continue; - if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Fun)) { + if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*I)) { if (FunctionType == Context.getCanonicalType(FunDecl->getType())) { - Matches.insert(cast<FunctionDecl>(Fun->getCanonicalDecl())); + Matches.insert(cast<FunctionDecl>(FunDecl->getCanonicalDecl())); FoundNonTemplateFunction = true; } } @@ -4522,7 +4508,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, /// \brief Add a single candidate to the overload set. static void AddOverloadedCallCandidate(Sema &S, - AnyFunctionDecl Callee, + NamedDecl *Callee, bool &ArgumentDependentLookup, bool HasExplicitTemplateArgs, const TemplateArgumentLoc *ExplicitTemplateArgs, @@ -4530,6 +4516,9 @@ static void AddOverloadedCallCandidate(Sema &S, Expr **Args, unsigned NumArgs, OverloadCandidateSet &CandidateSet, bool PartialOverloading) { + if (isa<UsingShadowDecl>(Callee)) + Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl(); + if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) { assert(!HasExplicitTemplateArgs && "Explicit template arguments?"); S.AddOverloadCandidate(Func, Args, NumArgs, CandidateSet, false, false, @@ -4539,21 +4528,28 @@ static void AddOverloadedCallCandidate(Sema &S, Func->getDeclContext()->isFunctionOrMethod()) ArgumentDependentLookup = false; return; - } - - FunctionTemplateDecl *FuncTemplate = cast<FunctionTemplateDecl>(Callee); - S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs, - ExplicitTemplateArgs, - NumExplicitTemplateArgs, - Args, NumArgs, CandidateSet); - - if (FuncTemplate->getDeclContext()->isRecord()) - ArgumentDependentLookup = false; + } + + if (FunctionTemplateDecl *FuncTemplate + = dyn_cast<FunctionTemplateDecl>(Callee)) { + S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs, + ExplicitTemplateArgs, + NumExplicitTemplateArgs, + Args, NumArgs, CandidateSet); + + if (FuncTemplate->getDeclContext()->isRecord()) + ArgumentDependentLookup = false; + return; + } + + assert(false && "unhandled case in overloaded call candidate"); + + // do nothing? } /// \brief Add the overload candidates named by callee and/or found by argument /// dependent lookup to the given overload set. -void Sema::AddOverloadedCallCandidates(NamedDecl *Callee, +void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns, DeclarationName &UnqualifiedName, bool &ArgumentDependentLookup, bool HasExplicitTemplateArgs, @@ -4562,11 +4558,11 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee, Expr **Args, unsigned NumArgs, OverloadCandidateSet &CandidateSet, bool PartialOverloading) { - // Add the functions denoted by Callee to the set of candidate - // functions. While we're doing so, track whether argument-dependent - // lookup still applies, per: + +#ifndef NDEBUG + // Verify that ArgumentDependentLookup is consistent with the rules + // in C++0x [basic.lookup.argdep]p3: // - // C++0x [basic.lookup.argdep]p3: // Let X be the lookup set produced by unqualified lookup (3.4.1) // and let Y be the lookup set produced by argument dependent // lookup (defined as follows). If X contains @@ -4574,38 +4570,31 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee, // -- a declaration of a class member, or // // -- a block-scope function declaration that is not a - // using-declaration (FIXME: check for using declaration), or + // using-declaration, or // // -- a declaration that is neither a function or a function // template // // then Y is empty. - if (!Callee) { - // Nothing to do. - } else if (OverloadedFunctionDecl *Ovl - = dyn_cast<OverloadedFunctionDecl>(Callee)) { - for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(), - FuncEnd = Ovl->function_end(); - Func != FuncEnd; ++Func) - AddOverloadedCallCandidate(*this, *Func, ArgumentDependentLookup, - HasExplicitTemplateArgs, - ExplicitTemplateArgs, NumExplicitTemplateArgs, - Args, NumArgs, CandidateSet, - PartialOverloading); - } else if (isa<FunctionDecl>(Callee) || isa<FunctionTemplateDecl>(Callee)) - AddOverloadedCallCandidate(*this, - AnyFunctionDecl::getFromNamedDecl(Callee), - ArgumentDependentLookup, + + if (ArgumentDependentLookup) { + for (unsigned I = 0; I < Fns.size(); ++I) { + assert(!Fns[I]->getDeclContext()->isRecord()); + assert(isa<UsingShadowDecl>(Fns[I]) || + !Fns[I]->getDeclContext()->isFunctionOrMethod()); + assert(Fns[I]->getUnderlyingDecl()->isFunctionOrFunctionTemplate()); + } + } +#endif + + for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(), + E = Fns.end(); I != E; ++I) + AddOverloadedCallCandidate(*this, *I, ArgumentDependentLookup, HasExplicitTemplateArgs, ExplicitTemplateArgs, NumExplicitTemplateArgs, - Args, NumArgs, CandidateSet, + Args, NumArgs, CandidateSet, PartialOverloading); - // FIXME: assert isa<FunctionDecl> || isa<FunctionTemplateDecl> rather than - // checking dynamically. - - if (Callee) - UnqualifiedName = Callee->getDeclName(); - + if (ArgumentDependentLookup) AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs, HasExplicitTemplateArgs, @@ -4622,7 +4611,8 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee, /// the function declaration produced by overload /// resolution. Otherwise, emits diagnostics, deletes all of the /// arguments and Fn, and returns NULL. -FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, +FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, + llvm::SmallVectorImpl<NamedDecl*> &Fns, DeclarationName UnqualifiedName, bool HasExplicitTemplateArgs, const TemplateArgumentLoc *ExplicitTemplateArgs, @@ -4636,7 +4626,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, // Add the functions denoted by Callee to the set of candidate // functions. - AddOverloadedCallCandidates(Callee, UnqualifiedName, ArgumentDependentLookup, + AddOverloadedCallCandidates(Fns, UnqualifiedName, ArgumentDependentLookup, HasExplicitTemplateArgs, ExplicitTemplateArgs, NumExplicitTemplateArgs, Args, NumArgs, CandidateSet); @@ -4716,15 +4706,13 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, } if (Input->isTypeDependent()) { - OverloadedFunctionDecl *Overloads - = OverloadedFunctionDecl::Create(Context, CurContext, OpName); + UnresolvedLookupExpr *Fn + = UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc, + /*ADL*/ true); for (FunctionSet::iterator Func = Functions.begin(), FuncEnd = Functions.end(); Func != FuncEnd; ++Func) - Overloads->addOverload(*Func); - - DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy, - OpLoc, false, false); + Fn->addDecl(*Func); input.release(); return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, @@ -4874,15 +4862,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, OpLoc)); } - OverloadedFunctionDecl *Overloads - = OverloadedFunctionDecl::Create(Context, CurContext, OpName); + UnresolvedLookupExpr *Fn + = UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc, + /* ADL */ true); + for (FunctionSet::iterator Func = Functions.begin(), FuncEnd = Functions.end(); Func != FuncEnd; ++Func) - Overloads->addOverload(*Func); - - DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy, - OpLoc, false, false); + Fn->addDecl(*Func); return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args, 2, @@ -5040,11 +5027,10 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, // expression. if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) { - OverloadedFunctionDecl *Overloads - = OverloadedFunctionDecl::Create(Context, CurContext, OpName); - - DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy, - LLoc, false, false); + UnresolvedLookupExpr *Fn + = UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, LLoc, + /*ADL*/ true); + // Can't add an actual overloads yet Base.release(); Idx.release(); @@ -5334,21 +5320,17 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // accessible base class provided the function is not hidden // within T by another intervening declaration. // FIXME: Look in base classes for more conversion operators! - OverloadedFunctionDecl *Conversions + const UnresolvedSet *Conversions = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions(); - for (OverloadedFunctionDecl::function_iterator - Func = Conversions->function_begin(), - FuncEnd = Conversions->function_end(); - Func != FuncEnd; ++Func) { - CXXConversionDecl *Conv; - FunctionTemplateDecl *ConvTemplate; - GetFunctionAndTemplate(*Func, Conv, ConvTemplate); - + for (UnresolvedSet::iterator I = Conversions->begin(), + E = Conversions->end(); I != E; ++I) { // Skip over templated conversion functions; they aren't // surrogates. - if (ConvTemplate) + if (isa<FunctionTemplateDecl>(*I)) continue; + CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I); + // Strip the reference type (if any) and then the pointer type (if // any) to get down to what might be a function type. QualType ConvType = Conv->getConversionType().getNonReferenceType(); @@ -5637,38 +5619,32 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { if (Method->isStatic()) { // Do nothing: static member functions aren't any different // from non-member functions. - } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr())) { - if (DRE->getQualifier()) { - // We have taken the address of a pointer to member - // function. Perform the computation here so that we get the - // appropriate pointer to member type. - QualType ClassType - = Context.getTypeDeclType( - cast<RecordDecl>(Method->getDeclContext())); - QualType MemPtrType - = Context.getMemberPointerType(Fn->getType(), - ClassType.getTypePtr()); - - DeclRefExpr *NewDRE - = DeclRefExpr::Create(Context, - DRE->getQualifier(), - DRE->getQualifierRange(), - Fn, - DRE->getLocation(), - DRE->hasExplicitTemplateArgumentList(), - DRE->getLAngleLoc(), - DRE->getTemplateArgs(), - DRE->getNumTemplateArgs(), - DRE->getRAngleLoc(), - Fn->getType(), - DRE->isTypeDependent(), - DRE->isValueDependent()); - - return new (Context) UnaryOperator(NewDRE, UnaryOperator::AddrOf, - MemPtrType, - UnOp->getOperatorLoc()); - } + } else { + // Fix the sub expression, which really has to be one of: + // * a DeclRefExpr holding a member function template + // * a TemplateIdRefExpr, also holding a member function template + // * an UnresolvedLookupExpr holding an overloaded member function + Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); + if (SubExpr == UnOp->getSubExpr()) + return UnOp->Retain(); + + assert(isa<DeclRefExpr>(SubExpr) + && "fixed to something other than a decl ref"); + assert(cast<DeclRefExpr>(SubExpr)->getQualifier() + && "fixed to a member ref with no nested name qualifier"); + + // We have taken the address of a pointer to member + // function. Perform the computation here so that we get the + // appropriate pointer to member type. + QualType ClassType + = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext())); + QualType MemPtrType + = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr()); + + return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf, + MemPtrType, UnOp->getOperatorLoc()); } + // FIXME: TemplateIdRefExpr referring to a member function template // specialization! } @@ -5682,8 +5658,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { } if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { - assert((isa<OverloadedFunctionDecl>(DRE->getDecl()) || - isa<FunctionTemplateDecl>(DRE->getDecl()) || + assert((isa<FunctionTemplateDecl>(DRE->getDecl()) || isa<FunctionDecl>(DRE->getDecl())) && "Expected function or function template"); return DeclRefExpr::Create(Context, @@ -5700,6 +5675,18 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { DRE->isTypeDependent(), DRE->isValueDependent()); } + + if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { + return DeclRefExpr::Create(Context, + ULE->getQualifier(), + ULE->getQualifierRange(), + Fn, + ULE->getNameLoc(), + Fn->getType(), + Fn->getType()->isDependentType(), + false); + } + if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) { assert((isa<OverloadedFunctionDecl>(MemExpr->getMemberDecl()) || @@ -5736,13 +5723,6 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { /*FIXME?*/false, /*FIXME?*/false); } - if (isa<UnresolvedFunctionNameExpr>(E)) - return DeclRefExpr::Create(Context, - /*Qualifier=*/0, - /*QualifierRange=*/SourceRange(), - Fn, E->getLocStart(), - Fn->getType(), false, false); - assert(false && "Invalid reference to overloaded function"); return E->Retain(); } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 58fe59e321c..c61481f83d8 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -556,6 +556,9 @@ namespace { bool isAddressOfOperand); Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E, bool isAddressOfOperand); + Sema::OwningExprResult TransformUnresolvedLookupExpr( + UnresolvedLookupExpr *E, + bool isAddressOfOperand); Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E, bool isAddressOfOperand); @@ -694,6 +697,55 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E, } Sema::OwningExprResult +TemplateInstantiator::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old, + bool isAddressOfOperand) { + llvm::SmallVector<NamedDecl*, 16> InstDecls; + + bool HasUnresolved = false; + + for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(), + E = Old->decls_end(); I != E; ++I) { + NamedDecl *InstD = SemaRef.FindInstantiatedDecl(*I, TemplateArgs); + if (!InstD) + return SemaRef.ExprError(); + + // Expand using declarations. + if (isa<UsingDecl>(InstD)) { + UsingDecl *UD = cast<UsingDecl>(InstD); + for (UsingDecl::shadow_iterator UI = UD->shadow_begin(), + UE = UD->shadow_end(); UI != UE; ++UI) { + UsingShadowDecl *Shadow = *UI; + if (isa<UnresolvedUsingValueDecl>(Shadow->getUnderlyingDecl())) + HasUnresolved = true; + InstDecls.push_back(Shadow); + } + + continue; + } + + if (isa<UnresolvedUsingValueDecl>(InstD->getUnderlyingDecl())) + HasUnresolved = true; + InstDecls.push_back(InstD); + } + + CXXScopeSpec SS; + NestedNameSpecifier *Qualifier = 0; + if (Old->getQualifier()) { + Qualifier = TransformNestedNameSpecifier(Old->getQualifier(), + Old->getQualifierRange()); + if (!Qualifier) + return SemaRef.ExprError(); + + SS.setScopeRep(Qualifier); + SS.setRange(Old->getQualifierRange()); + } + + return SemaRef.BuildDeclarationNameExpr(&SS, Old->getNameLoc(), + Old->getName(), Old->requiresADL(), + InstDecls.data(), InstDecls.size()); +} + +Sema::OwningExprResult TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E, bool isAddressOfOperand) { // FIXME: Clean this up a bit @@ -788,46 +840,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E, if (!InstD) return SemaRef.ExprError(); - // Flatten using declarations into their shadow declarations. - if (isa<UsingDecl>(InstD)) { - UsingDecl *UD = cast<UsingDecl>(InstD); - - bool HasNonFunction = false; - - llvm::SmallVector<NamedDecl*, 8> Decls; - for (UsingDecl::shadow_iterator I = UD->shadow_begin(), - E = UD->shadow_end(); I != E; ++I) { - NamedDecl *TD = (*I)->getTargetDecl(); - if (!TD->isFunctionOrFunctionTemplate()) - HasNonFunction = true; - - Decls.push_back(TD); - } - - if (Decls.empty()) - return SemaRef.ExprError(); - - if (Decls.size() == 1) - InstD = Decls[0]; - else if (!HasNonFunction) { - OverloadedFunctionDecl *OFD - = OverloadedFunctionDecl::Create(SemaRef.Context, - UD->getDeclContext(), - UD->getDeclName()); - for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Decls.begin(), - E = Decls.end(); I != E; ++I) - if (isa<FunctionDecl>(*I)) - OFD->addOverload(cast<FunctionDecl>(*I)); - else - OFD->addOverload(cast<FunctionTemplateDecl>(*I)); - - InstD = OFD; - } else { - // FIXME - assert(false && "using declaration resolved to mixed set"); - return SemaRef.ExprError(); - } - } + assert(!isa<UsingDecl>(InstD) && "decl ref instantiated to UsingDecl"); CXXScopeSpec SS; NestedNameSpecifier *Qualifier = 0; @@ -841,10 +854,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E, SS.setRange(E->getQualifierRange()); } - return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD, - /*FIXME:*/false, - &SS, - isAddressOfOperand); + return SemaRef.BuildDeclarationNameExpr(&SS, E->getLocation(), InstD); } Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr( diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 5018b1544e4..101690a2c8a 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4558,10 +4558,10 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr( template<typename Derived> Sema::OwningExprResult -TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr( - UnresolvedFunctionNameExpr *E, +TreeTransform<Derived>::TransformUnresolvedLookupExpr( + UnresolvedLookupExpr *E, bool isAddressOfOperand) { - // There is no transformation we can apply to an unresolved function name. + // There is no transformation we can apply to an unresolved lookup. return SemaRef.Owned(E->Retain()); } @@ -5384,8 +5384,7 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, ExprArg Second) { Expr *FirstExpr = (Expr *)First.get(); Expr *SecondExpr = (Expr *)Second.get(); - DeclRefExpr *DRE - = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts()); + Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts(); bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus); // Determine whether this should be a builtin operation. @@ -5393,7 +5392,7 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, if (!FirstExpr->getType()->isOverloadableType() && !SecondExpr->getType()->isOverloadableType()) return getSema().CreateBuiltinArraySubscriptExpr(move(First), - DRE->getLocStart(), + CalleeExpr->getLocStart(), move(Second), OpLoc); } else if (Op == OO_Arrow) { // -> is never a builtin operation. @@ -5428,10 +5427,18 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, // used during overload resolution. Sema::FunctionSet Functions; - // FIXME: Do we have to check - // IsAcceptableNonMemberOperatorCandidate for each of these? - for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F) - Functions.insert(*F); + 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)); + } else { + Functions.insert(AnyFunctionDecl::getFromNamedDecl( + cast<DeclRefExpr>(CalleeExpr)->getDecl())); + } // Add any functions found via argument-dependent lookup. Expr *Args[2] = { FirstExpr, SecondExpr }; @@ -5449,8 +5456,10 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, } if (Op == OO_Subscript) - return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc, - move(First),move(Second)); + return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(), + OpLoc, + move(First), + move(Second)); // Create the overloaded operator invocation for binary operators. BinaryOperator::Opcode Opc = |