summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.h8
-rw-r--r--clang/lib/Sema/SemaDecl.cpp139
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp40
-rw-r--r--clang/lib/Sema/SemaExpr.cpp40
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp29
-rw-r--r--clang/lib/Sema/SemaOverload.cpp86
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
OpenPOWER on IntegriCloud