diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 139 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 40 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 40 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 29 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 86 |
6 files changed, 151 insertions, 191 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 48af5af0a37..2664c57ee4b 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -479,7 +479,7 @@ public: SourceLocation *CommaLocs, SourceLocation RParenLoc); - ExprResult BuildOverloadedArrowExpr(Expr *Base, SourceLocation OpLoc, + ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, SourceLocation MemberLoc, IdentifierInfo &Member); @@ -696,7 +696,8 @@ public: virtual ExprResult ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, ExprTy *Idx, SourceLocation RLoc); - virtual ExprResult ActOnMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc, + virtual ExprResult ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, + SourceLocation OpLoc, tok::TokenKind OpKind, SourceLocation MemberLoc, IdentifierInfo &Member); @@ -747,7 +748,8 @@ public: SourceLocation RPLoc); // "({..})" /// __builtin_offsetof(type, a.b[123][456].c) - virtual ExprResult ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc, + virtual ExprResult ActOnBuiltinOffsetOf(Scope *S, + SourceLocation BuiltinLoc, SourceLocation TypeLoc, TypeTy *Arg1, OffsetOfComponent *CompPtr, unsigned NumComponents, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 024ca8138a6..270de5546bc 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -106,7 +106,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) { // require some reshuffling in the identifier resolver. IdentifierResolver::iterator I = IdResolver.begin(TD->getIdentifier(), CurContext, - false/*LookInParentCtx*/); + false/*LookInParentCtx*/); if (I != IdResolver.end()) { // There is already a declaration with the same name in the same // scope. It must be found before we find the new declaration, @@ -123,57 +123,47 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) { // We are pushing the name of a function, which might be an // overloaded name. FunctionDecl *FD = cast<FunctionDecl>(D); - Decl *Prev = LookupDecl(FD->getDeclName(), Decl::IDNS_Ordinary, S, - FD->getDeclContext(), false, false); - if (Prev && (isa<OverloadedFunctionDecl>(Prev) || isa<FunctionDecl>(Prev))) { - // There is already a declaration with the same name in - // the same scope. It must be a function or an overloaded - // function. - OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(Prev); - if (!Ovl) { - // We haven't yet overloaded this function. Take the existing - // FunctionDecl and put it into an OverloadedFunctionDecl. - Ovl = OverloadedFunctionDecl::Create(Context, - FD->getDeclContext(), - FD->getDeclName()); - Ovl->addOverload(cast<FunctionDecl>(Prev)); + if (CurContext == FD->getDeclContext()) { + IdentifierResolver::iterator + I = IdResolver.begin(FD->getDeclName(), CurContext, + false/*LookInParentCtx*/); + if (I != IdResolver.end() && + (isa<OverloadedFunctionDecl>(*I) || isa<FunctionDecl>(*I))) { + // There is already a declaration with the same name in + // the same scope. It must be a function or an overloaded + // function. + OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(*I); + if (!Ovl) { + // We haven't yet overloaded this function. Take the existing + // FunctionDecl and put it into an OverloadedFunctionDecl. + Ovl = OverloadedFunctionDecl::Create(Context, + FD->getDeclContext(), + FD->getDeclName()); + Ovl->addOverload(cast<FunctionDecl>(*I)); + + IdResolver.RemoveDecl(*I); + S->RemoveDecl(*I); - // If there is a name binding for the existing FunctionDecl, - // remove it. - for (IdentifierResolver::iterator I - = IdResolver.begin(FD->getDeclName(), FD->getDeclContext(), - false/*LookInParentCtx*/), - E = IdResolver.end(); I != E; ++I) { - if (*I == Prev) { - IdResolver.RemoveDecl(*I); - S->RemoveDecl(*I); - break; - } + // Add the name binding for the OverloadedFunctionDecl. + IdResolver.AddDecl(Ovl); + + S->AddDecl(Ovl); } - - // Add the name binding for the OverloadedFunctionDecl. - IdResolver.AddDecl(Ovl); - - // Update the context with the newly-created overloaded - // function set. - FD->getDeclContext()->insert(Context, Ovl); - S->AddDecl(Ovl); + // We added this function declaration to the scope earlier, but + // we don't want it there because it is part of the overloaded + // function declaration. + S->RemoveDecl(FD); + + // We have an OverloadedFunctionDecl. Add the new FunctionDecl + // to its list of overloads. + Ovl->addOverload(FD); + + // Add this new function declaration to the declaration context. + CurContext->addDecl(Context, FD); + + return; } - - // We added this function declaration to the scope earlier, but - // we don't want it there because it is part of the overloaded - // function declaration. - S->RemoveDecl(FD); - - // We have an OverloadedFunctionDecl. Add the new FunctionDecl - // to its list of overloads. - Ovl->addOverload(FD); - - // Add this new function declaration to the declaration context. - CurContext->addDecl(Context, FD, false); - - return; } } @@ -216,6 +206,52 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) { return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl); } +/// MaybeConstructOverloadSet - Name lookup has determined that the +/// elements in [I, IEnd) have the name that we are looking for, and +/// *I is a match for the namespace. This routine returns an +/// appropriate Decl for name lookup, which may either be *I or an +/// OverloadeFunctionDecl that represents the overloaded functions in +/// [I, IEnd). +/// +/// The existance of this routine is temporary; LookupDecl should +/// probably be able to return multiple results, to deal with cases of +/// ambiguity and overloaded functions without needing to create a +/// Decl node. +static Decl * +MaybeConstructOverloadSet(ASTContext &Context, const DeclContext *DC, + DeclContext::lookup_const_iterator I, + DeclContext::lookup_const_iterator IEnd) { + assert(I != IEnd && "Iterator range cannot be empty"); + assert(!isa<OverloadedFunctionDecl>(*I) && + "Cannot have an overloaded function"); + + if (isa<FunctionDecl>(*I)) { + // If we found a function, there might be more functions. If + // so, collect them into an overload set. + DeclContext::lookup_const_iterator Last = I; + OverloadedFunctionDecl *Ovl = 0; + for (++Last; Last != IEnd && isa<FunctionDecl>(*Last); ++Last) { + if (!Ovl) { + // FIXME: We leak this overload set. Eventually, we want to + // stop building the declarations for these overload sets, so + // there will be nothing to leak. + Ovl = OverloadedFunctionDecl::Create(Context, + const_cast<DeclContext *>(DC), + (*I)->getDeclName()); + Ovl->addOverload(cast<FunctionDecl>(*I)); + } + Ovl->addOverload(cast<FunctionDecl>(*Last)); + } + + // If we had more than one function, we built an overload + // set. Return it. + if (Ovl) + return Ovl; + } + + return *I; +} + /// LookupDecl - Look up the inner-most declaration in the specified /// namespace. Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, @@ -244,14 +280,12 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, if ((*I)->getIdentifierNamespace() & NS) return *I; } else if (LookupCtx) { - assert(getLangOptions().CPlusPlus && "No qualified name lookup in C"); - // Perform qualified name lookup into the LookupCtx. // FIXME: Will need to look into base classes and such. DeclContext::lookup_const_iterator I, E; for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) if ((*I)->getIdentifierNamespace() & NS) - return *I; + return MaybeConstructOverloadSet(Context, LookupCtx, I, E); } else { // Name lookup for ordinary names and tag names in C++ requires // looking into scopes that aren't strictly lexical, and @@ -279,7 +313,7 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S, for (llvm::tie(I, E) = Ctx->lookup(Context, Name); I != E; ++I) { // FIXME: Cache this result in the IdResolver if ((*I)->getIdentifierNamespace() & NS) - return *I; + return MaybeConstructOverloadSet(Context, LookupCtx, I, E); } Ctx = Ctx->getParent(); @@ -533,6 +567,7 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) { if (OldReturnType != NewReturnType) { Diag(New->getLocation(), diag::err_ovl_diff_return_type); Diag(Old->getLocation(), PrevDiag); + Redeclaration = true; return New; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8a37bbbe7b4..918fd2ac9a7 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -20,6 +20,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Parse/DeclSpec.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" #include <algorithm> // for std::equal #include <map> @@ -844,23 +845,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { CopyConstructor->setParams(&FromParam, 1); ClassDecl->addedConstructor(Context, CopyConstructor); - DeclContext::lookup_result Lookup = ClassDecl->lookup(Context, Name); - if (Lookup.first == Lookup.second - || (!isa<CXXConstructorDecl>(*Lookup.first) && - !isa<OverloadedFunctionDecl>(*Lookup.first))) - ClassDecl->addDecl(Context, CopyConstructor); - else { - OverloadedFunctionDecl *Ovl - = dyn_cast<OverloadedFunctionDecl>(*Lookup.first); - if (!Ovl) { - Ovl = OverloadedFunctionDecl::Create(Context, ClassDecl, Name); - Ovl->addOverload(cast<CXXConstructorDecl>(*Lookup.first)); - ClassDecl->insert(Context, Ovl); - } - - Ovl->addOverload(CopyConstructor); - ClassDecl->addDecl(Context, CopyConstructor, false); - } + ClassDecl->addDecl(Context, CopyConstructor); } if (!ClassDecl->hasUserDeclaredDestructor()) { @@ -1470,23 +1455,10 @@ Sema::PerformInitializationByConstructor(QualType ClassType, DeclarationName ConstructorName = Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(ClassType.getUnqualifiedType())); - DeclContext::lookup_const_result Lookup - = ClassDecl->lookup(Context, ConstructorName); - if (Lookup.first == Lookup.second) - /* No constructors */; - else if (OverloadedFunctionDecl *Constructors - = dyn_cast<OverloadedFunctionDecl>(*Lookup.first)) { - for (OverloadedFunctionDecl::function_iterator Con - = Constructors->function_begin(); - Con != Constructors->function_end(); ++Con) { - CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); - if ((Kind == IK_Direct) || - (Kind == IK_Copy && Constructor->isConvertingConstructor()) || - (Kind == IK_Default && Constructor->isDefaultConstructor())) - AddOverloadCandidate(Constructor, Args, NumArgs, CandidateSet); - } - } else if (CXXConstructorDecl *Constructor - = dyn_cast<CXXConstructorDecl>(*Lookup.first)) { + DeclContext::lookup_const_iterator Con, ConEnd; + for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(Context, ConstructorName); + Con != ConEnd; ++Con) { + CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); if ((Kind == IK_Direct) || (Kind == IK_Copy && Constructor->isConvertingConstructor()) || (Kind == IK_Default && Constructor->isDefaultConstructor())) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 307e1ad45ee..4088f443f75 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1254,7 +1254,7 @@ static IdentifierInfo *constructSetterName(IdentifierTable &Idents, } Action::ExprResult Sema:: -ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, +ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, tok::TokenKind OpKind, SourceLocation MemberLoc, IdentifierInfo &Member) { Expr *BaseExpr = static_cast<Expr *>(Base); @@ -1272,7 +1272,7 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, if (const PointerType *PT = BaseType->getAsPointerType()) BaseType = PT->getPointeeType(); else if (getLangOptions().CPlusPlus && BaseType->isRecordType()) - return BuildOverloadedArrowExpr(BaseExpr, OpLoc, MemberLoc, Member); + return BuildOverloadedArrowExpr(S, BaseExpr, OpLoc, MemberLoc, Member); else return Diag(MemberLoc, diag::err_typecheck_member_reference_arrow) << BaseType << BaseExpr->getSourceRange(); @@ -1288,42 +1288,42 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, // The record definition is complete, now make sure the member is valid. // FIXME: Qualified name lookup for C++ is a bit more complicated // than this. - DeclContext::lookup_result Lookup = RDecl->lookup(Context, &Member); - if (Lookup.first == Lookup.second) { + Decl *MemberDecl = LookupDecl(DeclarationName(&Member), Decl::IDNS_Ordinary, + S, RDecl, false, false); + if (!MemberDecl) return Diag(MemberLoc, diag::err_typecheck_no_member) << &Member << BaseExpr->getSourceRange(); - } - if (FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first)) { + if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) { // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref] // FIXME: Handle address space modifiers - QualType MemberType = MemberDecl->getType(); + QualType MemberType = FD->getType(); if (const ReferenceType *Ref = MemberType->getAsReferenceType()) MemberType = Ref->getPointeeType(); else { unsigned combinedQualifiers = MemberType.getCVRQualifiers() | BaseType.getCVRQualifiers(); - if (MemberDecl->isMutable()) + if (FD->isMutable()) combinedQualifiers &= ~QualType::Const; MemberType = MemberType.getQualifiedType(combinedQualifiers); } - return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl, + return new MemberExpr(BaseExpr, OpKind == tok::arrow, FD, MemberLoc, MemberType); - } else if (CXXClassVarDecl *Var = dyn_cast<CXXClassVarDecl>(*Lookup.first)) + } else if (CXXClassVarDecl *Var = dyn_cast<CXXClassVarDecl>(MemberDecl)) return new MemberExpr(BaseExpr, OpKind == tok::arrow, Var, MemberLoc, Var->getType().getNonReferenceType()); - else if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(*Lookup.first)) + else if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberFn, MemberLoc, MemberFn->getType()); else if (OverloadedFunctionDecl *Ovl - = dyn_cast<OverloadedFunctionDecl>(*Lookup.first)) + = dyn_cast<OverloadedFunctionDecl>(MemberDecl)) return new MemberExpr(BaseExpr, OpKind == tok::arrow, Ovl, MemberLoc, Context.OverloadTy); - else if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(*Lookup.first)) + else if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) return new MemberExpr(BaseExpr, OpKind == tok::arrow, Enum, MemberLoc, Enum->getType()); - else if (isa<TypeDecl>(*Lookup.first)) + else if (isa<TypeDecl>(MemberDecl)) return Diag(MemberLoc, diag::err_typecheck_member_reference_type) << DeclarationName(&Member) << int(OpKind == tok::arrow); @@ -3573,7 +3573,8 @@ Sema::ExprResult Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtTy *substmt, return new StmtExpr(Compound, Ty, LPLoc, RPLoc); } -Sema::ExprResult Sema::ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc, +Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, + SourceLocation BuiltinLoc, SourceLocation TypeLoc, TypeTy *argty, OffsetOfComponent *CompPtr, @@ -3628,11 +3629,10 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc, // Get the decl corresponding to this. RecordDecl *RD = RC->getDecl(); - FieldDecl *MemberDecl = 0; - DeclContext::lookup_result Lookup = RD->lookup(Context, OC.U.IdentInfo); - if (Lookup.first != Lookup.second) - MemberDecl = dyn_cast<FieldDecl>(*Lookup.first); - + FieldDecl *MemberDecl + = dyn_cast_or_null<FieldDecl>(LookupDecl(OC.U.IdentInfo, + Decl::IDNS_Ordinary, + S, RD, false, false)); if (!MemberDecl) return Diag(BuiltinLoc, diag::err_typecheck_no_member) << OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index e18f1437ab6..eb2e647f013 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -18,6 +18,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/STLExtras.h" using namespace clang; /// ActOnCXXConversionFunctionExpr - Parse a C++ conversion function @@ -412,8 +413,9 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name, DeclContext *Ctx, bool AllowMissing, FunctionDecl *&Operator) { - DeclContext::lookup_result Lookup = Ctx->lookup(Context, Name); - if (Lookup.first == Lookup.second) { + DeclContext::lookup_iterator Alloc, AllocEnd; + llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Context, Name); + if (Alloc == AllocEnd) { if (AllowMissing) return false; // FIXME: Bad location information. @@ -422,21 +424,12 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name, } OverloadCandidateSet Candidates; - NamedDecl *Decl = *Lookup.first; - // Even member operator new/delete are implicitly treated as static, so don't - // use AddMemberCandidate. - if (FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(Decl)) - AddOverloadCandidate(Fn, Args, NumArgs, Candidates, - /*SuppressUserConversions=*/false); - else if (OverloadedFunctionDecl *Ovl - = dyn_cast_or_null<OverloadedFunctionDecl>(Decl)) { - for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), - FEnd = Ovl->function_end(); - F != FEnd; ++F) { - if (FunctionDecl *Fn = *F) - AddOverloadCandidate(Fn, Args, NumArgs, Candidates, - /*SuppressUserConversions=*/false); - } + for (; Alloc != AllocEnd; ++Alloc) { + // Even member operator new/delete are implicitly treated as + // static, so don't use AddMemberCandidate. + if (FunctionDecl *Fn = dyn_cast<FunctionDecl>(*Alloc)) + AddOverloadCandidate(Fn, Args, NumArgs, Candidates, + /*SuppressUserConversions=*/false); } // Do the resolution. @@ -555,7 +548,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, 0, Argument, VarDecl::None, 0, 0); Alloc->setParams(&Param, 1); - PushOnScopeChains(Alloc, TUScope); + ((DeclContext *)TUScope->getEntity())->addDecl(Context, Alloc); } /// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 83653495132..8463c5d34ba 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -20,6 +20,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/TypeOrdering.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" #include <algorithm> @@ -1106,22 +1107,10 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, DeclarationName ConstructorName = Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(ToType)); - DeclContext::lookup_result Lookup - = ToRecordDecl->lookup(Context, ConstructorName); - if (Lookup.first == Lookup.second) - /* No constructors. FIXME: Implicit copy constructor? */; - else if (OverloadedFunctionDecl *Constructors - = dyn_cast<OverloadedFunctionDecl>(*Lookup.first)) { - for (OverloadedFunctionDecl::function_const_iterator func - = Constructors->function_begin(); - func != Constructors->function_end(); ++func) { - CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*func); - if (Constructor->isConvertingConstructor()) - AddOverloadCandidate(Constructor, &From, 1, CandidateSet, - /*SuppressUserConversions=*/true); - } - } else if (CXXConstructorDecl *Constructor - = dyn_cast<CXXConstructorDecl>(*Lookup.first)) { + DeclContext::lookup_iterator Con, ConEnd; + for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(Context, ConstructorName); + Con != ConEnd; ++Con) { + CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); if (Constructor->isConvertingConstructor()) AddOverloadCandidate(Constructor, &From, 1, CandidateSet, /*SuppressUserConversions=*/true); @@ -2142,22 +2131,12 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S, // (13.3.1.1.1); otherwise, the set of member candidates is // empty. if (const RecordType *T1Rec = T1->getAsRecordType()) { - DeclContext::lookup_const_result Lookup - = T1Rec->getDecl()->lookup(Context, OpName); - NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first; - if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps)) - AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet, + DeclContext::lookup_const_iterator Oper, OperEnd; + for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName); + Oper != OperEnd; ++Oper) + AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0], + Args+1, NumArgs - 1, CandidateSet, /*SuppressUserConversions=*/false); - else if (OverloadedFunctionDecl *Ovl - = dyn_cast_or_null<OverloadedFunctionDecl>(MemberOps)) { - for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), - FEnd = Ovl->function_end(); - F != FEnd; ++F) { - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*F)) - AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet, - /*SuppressUserConversions=*/false); - } - } } // -- The set of non-member candidates is the result of the @@ -3405,22 +3384,11 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // (E).operator(). OverloadCandidateSet CandidateSet; DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call); - DeclContext::lookup_const_result Lookup - = Record->getDecl()->lookup(Context, OpName); - NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first; - if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps)) - AddMethodCandidate(Method, Object, Args, NumArgs, CandidateSet, - /*SuppressUserConversions=*/false); - else if (OverloadedFunctionDecl *Ovl - = dyn_cast_or_null<OverloadedFunctionDecl>(MemberOps)) { - for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), - FEnd = Ovl->function_end(); - F != FEnd; ++F) { - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*F)) - AddMethodCandidate(Method, Object, Args, NumArgs, CandidateSet, - /*SuppressUserConversions=*/false); - } - } + DeclContext::lookup_const_iterator Oper, OperEnd; + for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName); + Oper != OperEnd; ++Oper) + AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs, + CandidateSet, /*SuppressUserConversions=*/false); // C++ [over.call.object]p2: // In addition, for each conversion function declared in T of the @@ -3585,7 +3553,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, /// (if one exists), where @c Base is an expression of class type and /// @c Member is the name of the member we're trying to find. Action::ExprResult -Sema::BuildOverloadedArrowExpr(Expr *Base, SourceLocation OpLoc, +Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, SourceLocation MemberLoc, IdentifierInfo &Member) { assert(Base->getType()->isRecordType() && "left-hand side must have class type"); @@ -3600,22 +3568,12 @@ Sema::BuildOverloadedArrowExpr(Expr *Base, SourceLocation OpLoc, DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow); OverloadCandidateSet CandidateSet; const RecordType *BaseRecord = Base->getType()->getAsRecordType(); - DeclContext::lookup_const_result Lookup - = BaseRecord->getDecl()->lookup(Context, OpName); - NamedDecl *MemberOps = (Lookup.first == Lookup.second)? 0 : *Lookup.first; - if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(MemberOps)) - AddMethodCandidate(Method, Base, 0, 0, CandidateSet, + + DeclContext::lookup_const_iterator Oper, OperEnd; + for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(Context, OpName); + Oper != OperEnd; ++Oper) + AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet, /*SuppressUserConversions=*/false); - else if (OverloadedFunctionDecl *Ovl - = dyn_cast_or_null<OverloadedFunctionDecl>(MemberOps)) { - for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), - FEnd = Ovl->function_end(); - F != FEnd; ++F) { - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*F)) - AddMethodCandidate(Method, Base, 0, 0, CandidateSet, - /*SuppressUserConversions=*/false); - } - } llvm::OwningPtr<Expr> BasePtr(Base); @@ -3658,7 +3616,7 @@ Sema::BuildOverloadedArrowExpr(Expr *Base, SourceLocation OpLoc, Base = new CXXOperatorCallExpr(FnExpr, &Base, 1, Method->getResultType().getNonReferenceType(), OpLoc); - return ActOnMemberReferenceExpr(Base, OpLoc, tok::arrow, MemberLoc, Member); + return ActOnMemberReferenceExpr(S, Base, OpLoc, tok::arrow, MemberLoc, Member); } /// FixOverloadedFunctionReference - E is an expression that refers to |

