diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/PCHReaderDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriterDecl.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 30 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 58 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 44 |
13 files changed, 174 insertions, 28 deletions
diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index 7c477560c64..27a08696320 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -82,6 +82,7 @@ void PCHDeclReader::VisitDecl(Decl *D) { if (Record[Idx++]) D->addAttr(*Reader.getContext(), Reader.ReadAttributes()); D->setImplicit(Record[Idx++]); + D->setUsed(Record[Idx++]); D->setAccess((AccessSpecifier)Record[Idx++]); } diff --git a/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp index 55cff663c59..5173ce33125 100644 --- a/clang/lib/Frontend/PCHWriterDecl.cpp +++ b/clang/lib/Frontend/PCHWriterDecl.cpp @@ -82,6 +82,7 @@ void PCHDeclWriter::VisitDecl(Decl *D) { Record.push_back(D->isInvalidDecl()); Record.push_back(D->hasAttrs()); Record.push_back(D->isImplicit()); + Record.push_back(D->isUsed()); Record.push_back(D->getAccess()); } @@ -360,6 +361,7 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { // know are true of all PARM_VAR_DECLs. if (!D->hasAttrs() && !D->isImplicit() && + !D->isUsed() && D->getAccess() == AS_none && D->getStorageClass() == 0 && !D->hasCXXDirectInitializer() && // Can params have this ever? @@ -434,6 +436,7 @@ void PCHWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl (!?) Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit + Abv->Add(BitCodeAbbrevOp(0)); // isUsed Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier // NamedDecl diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index efabf3a7c6d..69152523a11 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2699,8 +2699,12 @@ void Parser::ParseBracketDeclarator(Declarator &D) { // things like '=' and '*='. Sema rejects these in C89 mode because they // are not i-c-e's, so we don't need to distinguish between the two here. - // Parse the assignment-expression now. - NumElements = ParseAssignmentExpression(); + // Parse the constant-expression or assignment-expression now (depending + // on dialect). + if (getLang().CPlusPlus) + NumElements = ParseConstantExpression(); + else + NumElements = ParseAssignmentExpression(); } // If there was an error parsing the assignment-expression, recover. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 389ea666f12..1427814c934 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -279,7 +279,7 @@ Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ } SourceLocation LParenLoc = ConsumeParen(); - + OwningExprResult AssertExpr(ParseConstantExpression()); if (AssertExpr.isInvalid()) { SkipUntil(tok::semi); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 3fee78bb719..4a07d05650b 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -276,6 +276,11 @@ Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, Parser::OwningExprResult Parser::ParseConstantExpression() { + // C++ [basic.def.odr]p2: + // An expression is potentially evaluated unless it appears where an + // integral constant expression is required (see 5.19) [...]. + EnterUnevaluatedOperand Unevaluated(Actions); + OwningExprResult LHS(ParseCastExpression(false)); if (LHS.isInvalid()) return move(LHS); @@ -971,8 +976,15 @@ Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo(); return ExprError(); } + + // C++0x [expr.sizeof]p1: + // [...] The operand is either an expression, which is an unevaluated + // operand (Clause 5) [...] + // + // The GNU typeof and alignof extensions also behave as unevaluated + // operands. + EnterUnevaluatedOperand Unevaluated(Actions); Operand = ParseCastExpression(true/*isUnaryExpression*/); - } else { // If it starts with a '(', we know that it is either a parenthesized // type-name, or it is a unary-expression that starts with a compound @@ -980,6 +992,14 @@ Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, // expression. ParenParseOption ExprType = CastExpr; SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; + + // C++0x [expr.sizeof]p1: + // [...] The operand is either an expression, which is an unevaluated + // operand (Clause 5) [...] + // + // The GNU typeof and alignof extensions also behave as unevaluated + // operands. + EnterUnevaluatedOperand Unevaluated(Actions); Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, CastTy, RParenLoc); CastRange = SourceRange(LParenLoc, RParenLoc); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 681c6adb2ea..87aa5dc6711 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -377,6 +377,17 @@ Parser::OwningExprResult Parser::ParseCXXTypeid() { Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, Ty.get(), RParenLoc); } else { + // C++0x [expr.typeid]p3: + // When typeid is applied to an expression other than an lvalue of a + // polymorphic class type [...] The expression is an unevaluated + // operand (Clause 5). + // + // Note that we can't tell whether the expression is an lvalue of a + // polymorphic class type until after we've parsed the expression, so + // we treat the expression as an unevaluated operand and let semantic + // analysis cope with case where the expression is not an unevaluated + // operand. + EnterUnevaluatedOperand Unevaluated(Actions); Result = ParseExpression(); // Match the ')'. diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 60d8e5f987b..e756b41b12f 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -182,7 +182,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), ExternalSource(0), CurContext(0), PreDeclaratorDC(0), CurBlock(0), PackContext(0), IdResolver(pp.getLangOptions()), - GlobalNewDeleteDeclared(false), + GlobalNewDeleteDeclared(false), InUnevaluatedOperand(false), CompleteTranslationUnit(CompleteTranslationUnit), NumSFINAEErrors(0), CurrentInstantiationScope(0) { diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 23bab230097..230bcffa722 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -18,7 +18,9 @@ #include "IdentifierResolver.h" #include "CXXFieldCollector.h" #include "SemaOverload.h" +#include "clang/AST/Attr.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/Parse/Action.h" @@ -245,6 +247,12 @@ public: /// have been declared. bool GlobalNewDeleteDeclared; + /// A flag that indicates when we are processing an unevaluated operand + /// (C++0x [expr]). C99 has the same notion of declarations being + /// "used" and C++03 has the notion of "potentially evaluated", but we + /// adopt the C++0x terminology since it is most precise. + bool InUnevaluatedOperand; + /// \brief Whether the code handled by Sema should be considered a /// complete translation unit or not. /// @@ -454,6 +462,19 @@ public: virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body); DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body, bool IsInstantiation); + + /// \brief Diagnose any unused parameters in the given sequence of + /// ParmVarDecl pointers. + template<typename InputIterator> + void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) { + for (; Param != ParamEnd; ++Param) { + if (!(*Param)->isUsed() && (*Param)->getDeclName() && + !(*Param)->template hasAttr<UnusedAttr>(Context)) + Diag((*Param)->getLocation(), diag::warn_unused_parameter) + << (*Param)->getDeclName(); + } + } + void DiagnoseInvalidJumps(Stmt *Body); virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr); @@ -694,6 +715,7 @@ public: bool isBetterOverloadCandidate(const OverloadCandidate& Cand1, const OverloadCandidate& Cand2); OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet, + SourceLocation Loc, OverloadCandidateSet::iterator& Best); void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, bool OnlyViable); @@ -1312,6 +1334,14 @@ public: void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, Expr **Args, unsigned NumArgs); + virtual bool setUnevaluatedOperand(bool UnevaluatedOperand) { + bool Result = InUnevaluatedOperand; + InUnevaluatedOperand = UnevaluatedOperand; + return Result; + } + + void MarkDeclarationReferenced(SourceLocation Loc, Decl *D); + // Primary Expressions. virtual SourceRange getExprRange(ExprTy *E) const; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c4d1fe9983a..2dd02af7b91 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3094,10 +3094,23 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg, Stmt *Body = BodyArg.takeAs<Stmt>(); if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(dcl)) { FD->setBody(Body); + + if (!FD->isInvalidDecl()) + DiagnoseUnusedParameters(FD->param_begin(), FD->param_end()); + + // C++ [basic.def.odr]p2: + // [...] A virtual member function is used if it is not pure. [...] + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD)) + if (Method->isVirtual() && !Method->isPure()) + MarkDeclarationReferenced(Method->getLocation(), Method); + assert(FD == getCurFunctionDecl() && "Function parsing confused"); } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) { assert(MD == getCurMethodDecl() && "Method parsing confused"); MD->setBody(Body); + + if (!MD->isInvalidDecl()) + DiagnoseUnusedParameters(MD->param_begin(), MD->param_end()); } else { Body->Destroy(Context); return DeclPtrTy(); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index fd1cc0406fc..8c547cd1ccf 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2031,7 +2031,7 @@ Sema::PerformInitializationByConstructor(QualType ClassType, // constructors, we'll need to make them appear here. OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, Loc, Best)) { case OR_Success: // We found a constructor. Return it. return cast<CXXConstructorDecl>(Best->Function); @@ -2263,7 +2263,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, } OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, Init->getLocStart(), Best)) { case OR_Success: // This is a direct binding. BindsDirectly = true; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index de568193119..692502bbbe8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -627,6 +627,7 @@ DeclRefExpr * Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc, bool TypeDependent, bool ValueDependent, const CXXScopeSpec *SS) { + MarkDeclarationReferenced(Loc, D); if (SS && !SS->isEmpty()) { return new (Context) QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent, ValueDependent, SS->getRange(), @@ -721,6 +722,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, // BaseObject is an anonymous struct/union variable (and is, // therefore, not part of another non-anonymous record). if (BaseObjectExpr) BaseObjectExpr->Destroy(Context); + MarkDeclarationReferenced(Loc, BaseObject); BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(), SourceLocation()); ExtraQuals @@ -777,6 +779,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, = MemberType.getCVRQualifiers() | ExtraQuals; MemberType = MemberType.getQualifiedType(combinedQualifiers); } + MarkDeclarationReferenced(Loc, *FI); Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI, OpLoc, MemberType); BaseObjectIsPointer = false; @@ -876,6 +879,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // turn this into Self->ivar, just return a BareIVarExpr or something. IdentifierInfo &II = Context.Idents.get("self"); OwningExprResult SelfExpr = ActOnIdentifierExpr(S, Loc, II, false); + MarkDeclarationReferenced(Loc, IV); return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), Loc, SelfExpr.takeAs<Expr>(), true, true)); @@ -1025,6 +1029,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // Build the implicit member access expression. Expr *This = new (Context) CXXThisExpr(SourceLocation(), MD->getThisType(Context)); + MarkDeclarationReferenced(Loc, D); return Owned(new (Context) MemberExpr(This, true, D, Loc, MemberType)); } @@ -1125,6 +1130,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // as they do not get snapshotted. // if (CurBlock && ShouldSnapshotBlockValueReference(CurBlock, VD)) { + MarkDeclarationReferenced(Loc, VD); QualType ExprTy = VD->getType().getNonReferenceType(); // The BlocksAttr indicates the variable is bound by-reference. if (VD->getAttr<BlocksAttr>(Context)) @@ -1579,7 +1585,7 @@ Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, // Perform overload resolution. OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, OpLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; @@ -1689,7 +1695,7 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, // Perform overload resolution. OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, LLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; @@ -5258,7 +5264,7 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, BSI->isVariadic, 0); // FIXME: Check that return/parameter types are complete/non-abstract - + DiagnoseUnusedParameters(BSI->Params.begin(), BSI->Params.end()); BlockTy = Context.getBlockPointerType(BlockTy); // If needed, diagnose invalid gotos and switches in the block. @@ -5425,3 +5431,49 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){ *Result = EvalResult.Val.getInt(); return false; } + + +/// \brief Note that the given declaration was referenced in the source code. +/// +/// This routine should be invoke whenever a given declaration is referenced +/// in the source code, and where that reference occurred. If this declaration +/// reference means that the the declaration is used (C++ [basic.def.odr]p2, +/// C99 6.9p3), then the declaration will be marked as used. +/// +/// \param Loc the location where the declaration was referenced. +/// +/// \param D the declaration that has been referenced by the source code. +void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { + assert(D && "No declaration?"); + + // Mark a parameter declaration "used", regardless of whether we're in a + // template or not. + if (isa<ParmVarDecl>(D)) + D->setUsed(true); + + // Do not mark anything as "used" within a dependent context; wait for + // an instantiation. + if (CurContext->isDependentContext()) + return; + + // If we are in an unevaluated operand, don't mark any definitions as used. + if (InUnevaluatedOperand) + return; + + // Note that this declaration has been used. + if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + // FIXME: implicit template instantiation + // FIXME: keep track of references to static functions + (void)Function; + Function->setUsed(true); + return; + } + + if (VarDecl *Var = dyn_cast<VarDecl>(D)) { + (void)Var; + // FIXME: implicit template instantiation + // FIXME: keep track of references to static data? + D->setUsed(true); + } +} + diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7353efbae7d..bec595ca9cf 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -546,7 +546,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, // Do the resolution. OverloadCandidateSet::iterator Best; - switch(BestViableFunction(Candidates, Best)) { + switch(BestViableFunction(Candidates, StartLoc, Best)) { case OR_Success: { // Got one! FunctionDecl *FnDecl = Best->Function; @@ -1175,7 +1175,7 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS, Self.AddBuiltinOperatorCandidates(OO_Conditional, Args, 2, CandidateSet); OverloadCandidateSet::iterator Best; - switch (Self.BestViableFunction(CandidateSet, Best)) { + switch (Self.BestViableFunction(CandidateSet, Loc, Best)) { case Sema::OR_Success: // We found a match. Perform the conversions on the arguments and move on. if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0], diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e81985b74a9..11cd5107fc6 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1379,7 +1379,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, } OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, From->getLocStart(), Best)) { case OR_Success: // Record the standard conversion we used and the conversion function. if (CXXConstructorDecl *Constructor @@ -3445,14 +3445,21 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1, return false; } -/// BestViableFunction - Computes the best viable function (C++ 13.3.3) -/// within an overload candidate set. If overloading is successful, -/// the result will be OR_Success and Best will be set to point to the -/// best viable function within the candidate set. Otherwise, one of -/// several kinds of errors will be returned; see -/// Sema::OverloadingResult. +/// \brief Computes the best viable function (C++ 13.3.3) +/// within an overload candidate set. +/// +/// \param CandidateSet the set of candidate functions. +/// +/// \param Loc the location of the function name (or operator symbol) for +/// which overload resolution occurs. +/// +/// \param Best f overload resolution was successful or found a deleted +/// function, Best points to the candidate function found. +/// +/// \returns The result of overload resolution. Sema::OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet, + SourceLocation Loc, OverloadCandidateSet::iterator& Best) { // Find the best viable function. @@ -3487,9 +3494,14 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet, Best->Function->getAttr<UnavailableAttr>(Context))) return OR_Deleted; - // If Best refers to a function that is either deleted (C++0x) or - // unavailable (Clang extension) report an error. - + // C++ [basic.def.odr]p2: + // An overloaded function is used if it is selected by overload resolution + // when referred to from a potentially-evaluated expression. [Note: this + // covers calls to named functions (5.2.2), operator overloading + // (clause 13), user-defined conversions (12.3.2), allocation function for + // placement new (5.3.4), as well as non-default initialization (8.5). + if (Best->Function) + MarkDeclarationReferenced(Loc, Best->Function); return OR_Success; } @@ -3709,7 +3721,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee, CandidateSet); OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) { case OR_Success: return Best->Function; @@ -3815,7 +3827,7 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, // Perform overload resolution. OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, OpLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; @@ -3968,7 +3980,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // Perform overload resolution. OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, OpLoc, Best)) { case OR_Success: { // We found a built-in operator or an overloaded operator. FunctionDecl *FnDecl = Best->Function; @@ -4094,7 +4106,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, } OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, MemExpr->getLocStart(), Best)) { case OR_Success: Method = cast<CXXMethodDecl>(Best->Function); break; @@ -4219,7 +4231,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // Perform overload resolution. OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, Object->getLocStart(), Best)) { case OR_Success: // Overload resolution succeeded; we'll build the appropriate call // below. @@ -4388,7 +4400,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, // Perform overload resolution. OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Best)) { + switch (BestViableFunction(CandidateSet, OpLoc, Best)) { case OR_Success: // Overload resolution succeeded; we'll build the call below. break; |