diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 30 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 2 |
5 files changed, 25 insertions, 16 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 0b55ecd770..3f31405426 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -929,7 +929,7 @@ public: FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, bool Complain); - bool FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn); + Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn); void AddOverloadedCallCandidates(NamedDecl *Callee, DeclarationName &UnqualifiedName, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d2ef113b30..ba2a93d65c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3569,7 +3569,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, if (DiagnoseUseOfDecl(Fn, DeclLoc)) return true; - FixOverloadedFunctionReference(Init, Fn); + Init = FixOverloadedFunctionReference(Init, Fn); } T2 = Fn->getType(); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 181c1349bd..567111223a 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1226,12 +1226,13 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin())) return true; - bool WasAddrOf = FixOverloadedFunctionReference(From, Fn); + From = FixOverloadedFunctionReference(From, Fn); FromType = From->getType(); + // If there's already an address-of operator in the expression, we have // the right type already, and the code below would just introduce an // invalid additional pointer level. - if (WasAddrOf) + if (FromType->isPointerType() || FromType->isMemberFunctionPointerType()) break; } FromType = Context.getPointerType(FromType); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 5c3e131eb4..f5a7d18980 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5368,13 +5368,12 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) { /// a C++ overloaded function (possibly with some parentheses and /// perhaps a '&' around it). We have resolved the overloaded function /// to the function declaration Fn, so patch up the expression E to -/// refer (possibly indirectly) to Fn. -/// Returns true if the function reference used an explicit address-of operator. -bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { +/// refer (possibly indirectly) to Fn. Returns the new expr. +Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) { - bool ret = FixOverloadedFunctionReference(PE->getSubExpr(), Fn); - E->setType(PE->getSubExpr()->getType()); - return ret; + Expr *NewExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Fn); + NewExpr->setType(PE->getSubExpr()->getType()); + return NewExpr; } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) { assert(UnOp->getOpcode() == UnaryOperator::AddrOf && "Can only take the address of an overloaded function"); @@ -5393,12 +5392,14 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext())); E->setType(Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr())); - return true; + return E; } } - FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); - E->setType(Context.getPointerType(UnOp->getSubExpr()->getType())); - return true; + Expr *NewExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); + UnOp->setSubExpr(NewExpr); + UnOp->setType(Context.getPointerType(NewExpr->getType())); + + return UnOp; } else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) { assert((isa<OverloadedFunctionDecl>(DR->getDecl()) || isa<FunctionTemplateDecl>(DR->getDecl())) && @@ -5408,10 +5409,17 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { } else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) { MemExpr->setMemberDecl(Fn); E->setType(Fn->getType()); + } else if (TemplateIdRefExpr *TID = dyn_cast<TemplateIdRefExpr>(E)) { + // FIXME: Should we create QualifiedDeclRefExprs here too? + // FIXME: We should capture the template arguments here. + E = new (Context) DeclRefExpr(Fn, Fn->getType(), + TID->getSourceRange().getBegin()); + TID->Destroy(Context); } else { assert(false && "Invalid reference to overloaded function"); } - return false; + + return E; } } // end namespace clang diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index da7545c02d..d9c53ebec6 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2037,7 +2037,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) return true; - FixOverloadedFunctionReference(Arg, Fn); + Arg = FixOverloadedFunctionReference(Arg, Fn); ArgType = Arg->getType(); if (ArgType->isFunctionType() && ParamType->isPointerType()) { ArgType = Context.getPointerType(Arg->getType()); |