aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Driver/PrintParserCallbacks.cpp5
-rw-r--r--include/clang/AST/DeclBase.h18
-rw-r--r--include/clang/Parse/Action.h5
-rw-r--r--lib/AST/DeclBase.cpp163
-rw-r--r--lib/Parse/ParseExpr.cpp9
-rw-r--r--lib/Sema/Sema.h8
-rw-r--r--lib/Sema/SemaDecl.cpp139
-rw-r--r--lib/Sema/SemaDeclCXX.cpp40
-rw-r--r--lib/Sema/SemaExpr.cpp40
-rw-r--r--lib/Sema/SemaExprCXX.cpp29
-rw-r--r--lib/Sema/SemaOverload.cpp86
11 files changed, 267 insertions, 275 deletions
diff --git a/Driver/PrintParserCallbacks.cpp b/Driver/PrintParserCallbacks.cpp
index 3f6562893c..c97e95a51a 100644
--- a/Driver/PrintParserCallbacks.cpp
+++ b/Driver/PrintParserCallbacks.cpp
@@ -483,7 +483,8 @@ namespace {
llvm::cout << __FUNCTION__ << "\n";
return 0;
}
- virtual ExprResult ActOnMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc,
+ virtual ExprResult ActOnMemberReferenceExpr(Scope *S, ExprTy *Base,
+ SourceLocation OpLoc,
tok::TokenKind OpKind,
SourceLocation MemberLoc,
IdentifierInfo &Member) {
@@ -565,7 +566,7 @@ namespace {
return 0;
}
- virtual ExprResult ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc,
+ virtual ExprResult ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc,
SourceLocation TypeLoc, TypeTy *Arg1,
OffsetOfComponent *CompPtr,
unsigned NumComponents,
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 68a484666e..9ceb780172 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -191,6 +191,8 @@ public:
case EnumConstant:
case NonTypeTemplateParm:
case Field:
+ case ObjCAtDefsField:
+ case ObjCIvar:
case ObjCInterface:
case ObjCCompatibleAlias:
case OverloadedFunction:
@@ -267,8 +269,7 @@ class DeclContext {
/// LookupPtrKind - Describes what kind of pointer LookupPtr
/// actually is.
enum LookupPtrKind {
- /// LookupIsMap - Indicates that LookupPtr is actually a
- /// DenseMap<DeclarationName, TwoNamedDecls> pointer.
+ /// LookupIsMap - Indicates that LookupPtr is actually a map.
LookupIsMap = 7
};
@@ -276,9 +277,10 @@ class DeclContext {
/// declarations within this context. If the context contains fewer
/// than seven declarations, the number of declarations is provided
/// in the 3 lowest-order bits and the upper bits are treated as a
- /// pointer to an array of NamedDecl pointers. If the context
+ /// pointer to an array of ScopedDecl pointers. If the context
/// contains seven or more declarations, the upper bits are treated
- /// as a pointer to a DenseMap<DeclarationName, TwoNamedDecls>.
+ /// as a pointer to a DenseMap<DeclarationName, std::vector<ScopedDecl>>.
+ /// FIXME: We need a better data structure for this.
llvm::PointerIntPair<void*, 3> LookupPtr;
/// Decls - Contains all of the declarations that are defined inside
@@ -440,11 +442,11 @@ public:
/// lookup_iterator - An iterator that provides access to the results
/// of looking up a name within this context.
- typedef NamedDecl **lookup_iterator;
+ typedef ScopedDecl **lookup_iterator;
/// lookup_const_iterator - An iterator that provides non-mutable
/// access to the results of lookup up a name within this context.
- typedef NamedDecl * const * lookup_const_iterator;
+ typedef ScopedDecl * const * lookup_const_iterator;
typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
typedef std::pair<lookup_const_iterator, lookup_const_iterator>
@@ -471,7 +473,7 @@ public:
/// that this replacement is semantically correct, e.g., that
/// declarations are only replaced by later declarations of the same
/// entity and not a declaration of some other kind of entity.
- void insert(ASTContext &Context, NamedDecl *D);
+ void insert(ASTContext &Context, ScopedDecl *D);
static bool classof(const Decl *D) {
switch (D->getKind()) {
@@ -503,7 +505,7 @@ public:
static bool classof(const BlockDecl *D) { return true; }
private:
- void insertImpl(NamedDecl *D);
+ void insertImpl(ScopedDecl *D);
void EmitOutRec(llvm::Serializer& S) const;
void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 249f1224c7..39de870d12 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -569,7 +569,8 @@ public:
ExprTy *Idx, SourceLocation RLoc) {
return 0;
}
- virtual ExprResult ActOnMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc,
+ virtual ExprResult ActOnMemberReferenceExpr(Scope *S, ExprTy *Base,
+ SourceLocation OpLoc,
tok::TokenKind OpKind,
SourceLocation MemberLoc,
IdentifierInfo &Member) {
@@ -650,7 +651,7 @@ public:
} U;
};
- virtual ExprResult ActOnBuiltinOffsetOf(SourceLocation BuiltinLoc,
+ virtual ExprResult ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc,
SourceLocation TypeLoc, TypeTy *Arg1,
OffsetOfComponent *CompPtr,
unsigned NumComponents,
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 5d70493d1d..87ebf85b41 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/DenseMap.h"
+#include <vector>
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -375,21 +376,15 @@ const DeclContext *DeclContext::getLexicalParent() const {
return getParent();
}
-/// TwoNamedDecls - Stores up to two NamedDecls. The first
-/// declaration, if any, is in the ordinary identifier namespace, and
-/// corresponds to values (functions, variables, etc.). The second
-/// declaration, if any, is in the tag identifier namespace, and
-/// corresponds to tag types (classes, enums).
-struct TwoNamedDecls {
- NamedDecl* Decls[2];
-};
-
// FIXME: We really want to use a DenseSet here to eliminate the
// redundant storage of the declaration names, but (1) it doesn't give
// us the ability to search based on DeclarationName, (2) we really
// need something more like a DenseMultiSet, and (3) it's
-// implemented in terms of DenseMap anyway.
-typedef llvm::DenseMap<DeclarationName, TwoNamedDecls> StoredDeclsMap;
+// implemented in terms of DenseMap anyway. However, this data
+// structure is really space-inefficient, so we'll have to do
+// something.
+typedef llvm::DenseMap<DeclarationName, std::vector<ScopedDecl*> >
+ StoredDeclsMap;
DeclContext::~DeclContext() {
unsigned Size = LookupPtr.getInt();
@@ -397,7 +392,7 @@ DeclContext::~DeclContext() {
StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
delete Map;
} else {
- NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
+ ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
delete [] Array;
}
}
@@ -497,7 +492,7 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
if (PrimaryContext != this)
return PrimaryContext->lookup(Context, Name);
- /// If there is no lookup data structure, build one now by talking
+ /// If there is no lookup data structure, build one now by walking
/// all of the linked DeclContexts (in declaration order!) and
/// inserting their values.
if (LookupPtr.getPointer() == 0) {
@@ -506,32 +501,27 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
insertImpl(*D);
}
- lookup_result Result(0, 0);
if (isLookupMap()) {
StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
StoredDeclsMap::iterator Pos = Map->find(Name);
- if (Pos != Map->end()) {
- Result.first = Pos->second.Decls[0]? &Pos->second.Decls[0]
- : &Pos->second.Decls[1];
- Result.second = Pos->second.Decls[1]? &Pos->second.Decls[2]
- : &Pos->second.Decls[1];
- }
- return Result;
+ if (Pos != Map->end())
+ return lookup_result(&Pos->second.front(),
+ &Pos->second.front() + Pos->second.size());
+ return lookup_result(0, 0);
}
// We have a small array. Look into it.
unsigned Size = LookupPtr.getInt();
- NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
+ ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
for (unsigned Idx = 0; Idx != Size; ++Idx)
if (Array[Idx]->getDeclName() == Name) {
- Result.first = &Array[Idx];
- Result.second = Result.first + 1;
- if (Idx + 1 < Size && Array[Idx + 1]->getDeclName() == Name)
- ++Result.second;
- break;
+ unsigned Last = Idx + 1;
+ while (Last != Size && Array[Last]->getDeclName() == Name)
+ ++Last;
+ return lookup_result(&Array[Idx], &Array[Last]);
}
- return Result;
+ return lookup_result(0, 0);
}
DeclContext::lookup_const_result
@@ -539,7 +529,7 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
return const_cast<DeclContext*>(this)->lookup(Context, Name);
}
-void DeclContext::insert(ASTContext &Context, NamedDecl *D) {
+void DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
DeclContext *PrimaryContext = getPrimaryContext(Context);
if (PrimaryContext != this) {
PrimaryContext->insert(Context, D);
@@ -553,60 +543,80 @@ void DeclContext::insert(ASTContext &Context, NamedDecl *D) {
insertImpl(D);
}
-void DeclContext::insertImpl(NamedDecl *D) {
+static bool isRedeclarationOf(ScopedDecl *D, ScopedDecl *OldD) {
+ assert(D->getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
+
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ // For function declarations, we keep track of redeclarations.
+ return FD->getPreviousDeclaration() == OldD;
+
+ // For non-function declarations, if the declarations are of the
+ // same kind then this must be a redeclaration, or semantic analysis
+ // would not have given us the new declaration.
+ return D->getKind() == OldD->getKind();
+}
+
+void DeclContext::insertImpl(ScopedDecl *D) {
+ bool MayBeRedeclaration = true;
+
if (!isLookupMap()) {
unsigned Size = LookupPtr.getInt();
// The lookup data is stored as an array. Search through the array
// to find the insertion location.
- NamedDecl **Array;
+ ScopedDecl **Array;
if (Size == 0) {
- Array = new NamedDecl*[LookupIsMap - 1];
+ Array = new ScopedDecl*[LookupIsMap - 1];
LookupPtr.setPointer(Array);
} else {
- Array = static_cast<NamedDecl **>(LookupPtr.getPointer());
+ Array = static_cast<ScopedDecl **>(LookupPtr.getPointer());
}
// We always keep declarations of the same name next to each other
// in the array, so that it is easy to return multiple results
- // from lookup(). There will be zero, one, or two declarations of
- // the same name.
- unsigned Match;
- for (Match = 0; Match != Size; ++Match)
- if (Array[Match]->getDeclName() == D->getDeclName())
+ // from lookup().
+ unsigned FirstMatch;
+ for (FirstMatch = 0; FirstMatch != Size; ++FirstMatch)
+ if (Array[FirstMatch]->getDeclName() == D->getDeclName())
break;
- if (Match != Size) {
- // We found another declaration with the same name. If it's also
- // in the same identifier namespace, update the declaration in
- // place.
- Decl::IdentifierNamespace NS = D->getIdentifierNamespace();
- if (Array[Match]->getIdentifierNamespace() == NS) {
- Array[Match] = D;
- return;
- }
- if (Match + 1 < Size && Array[Match + 1]->getIdentifierNamespace() == NS) {
- Array[Match + 1] = D;
- return;
+ unsigned InsertPos = FirstMatch;
+ if (FirstMatch != Size) {
+ // We found another declaration with the same name. First
+ // determine whether this is a redeclaration of an existing
+ // declaration in this scope, in which case we will replace the
+ // existing declaration.
+ unsigned LastMatch = FirstMatch;
+ for (; LastMatch != Size; ++LastMatch) {
+ if (Array[LastMatch]->getDeclName() != D->getDeclName())
+ break;
+
+ if (isRedeclarationOf(D, Array[LastMatch])) {
+ // D is a redeclaration of an existing element in the
+ // array. Replace that element with D.
+ Array[LastMatch] = D;
+ return;
+ }
}
- // If there is an existing declaration in the namespace of
- // ordinary identifiers, then it must precede the tag
- // declaration for C++ name lookup to operate properly. Therefore,
- // if our match is an ordinary name and the new name is in the
- // tag namespace, we'll insert the new declaration after it.
- if (Match != Size && (NS == Decl::IDNS_Tag) &&
- (Array[Match]->getIdentifierNamespace() & Decl::IDNS_Ordinary))
- ++Match;
+ // [FirstMatch, LastMatch) contains the set of declarations that
+ // have the same name as this declaration. Determine where the
+ // declaration D will be inserted into this range.
+ if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
+ InsertPos = LastMatch;
+ else if (Array[LastMatch-1]->getIdentifierNamespace() == Decl::IDNS_Tag)
+ InsertPos = LastMatch - 1;
+ else
+ InsertPos = LastMatch;
}
if (Size < LookupIsMap - 1) {
// The new declaration will fit in the array. Insert the new
// declaration at the position Match in the array.
- for (unsigned Idx = Size; Idx > Match; --Idx)
+ for (unsigned Idx = Size; Idx > InsertPos; --Idx)
Array[Idx] = Array[Idx-1];
- Array[Match] = D;
+ Array[InsertPos] = D;
LookupPtr.setInt(Size + 1);
return;
}
@@ -621,20 +631,37 @@ void DeclContext::insertImpl(NamedDecl *D) {
delete [] Array;
// Fall through to perform insertion into the map.
- }
+ MayBeRedeclaration = false;
+ }
// Insert this declaration into the map.
StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
StoredDeclsMap::iterator Pos = Map->find(D->getDeclName());
- unsigned IndexOfD = D->getIdentifierNamespace() & Decl::IDNS_Ordinary? 0 : 1;
+ if (Pos != Map->end()) {
+ if (MayBeRedeclaration) {
+ // Determine if this declaration is actually a redeclaration.
+ for (std::vector<ScopedDecl *>::iterator I = Pos->second.begin(),
+ IEnd = Pos->second.end();
+ I != IEnd; ++I) {
+ if (isRedeclarationOf(D, *I)) {
+ // D is a redeclaration of *I. Replace *I with D and we're
+ // done.
+ *I = D;
+ return;
+ }
+ }
+ }
- if (Pos == Map->end()) {
// Put this declaration into the appropriate slot.
- TwoNamedDecls Val;
- Val.Decls[IndexOfD] = D;
- Val.Decls[!IndexOfD] = 0;
- Map->insert(std::make_pair(D->getDeclName(),Val)).first;
+ if (D->getIdentifierNamespace() == Decl::IDNS_Tag || Pos->second.empty())
+ Pos->second.push_back(D);
+ else if (Pos->second.back()->getIdentifierNamespace() == Decl::IDNS_Tag) {
+ ScopedDecl *TagD = Pos->second.back();
+ Pos->second.back() = D;
+ Pos->second.push_back(TagD);
+ } else
+ Pos->second.push_back(D);
} else {
- Pos->second.Decls[IndexOfD] = D;
+ (*Map)[D->getDeclName()].push_back(D);
}
}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 127ddf4078..0c25fab4f4 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -745,8 +745,8 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
}
if (!LHS.isInvalid()) {
- LHS = Actions.ActOnMemberReferenceExpr(LHS.release(), OpLoc, OpKind,
- Tok.getLocation(),
+ LHS = Actions.ActOnMemberReferenceExpr(CurScope, LHS.release(), OpLoc,
+ OpKind, Tok.getLocation(),
*Tok.getIdentifierInfo());
}
ConsumeToken();
@@ -920,8 +920,9 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
Comps.back().LocEnd =
MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
} else if (Tok.is(tok::r_paren)) {
- Res = Actions.ActOnBuiltinOffsetOf(StartLoc, TypeLoc, Ty, &Comps[0],
- Comps.size(), ConsumeParen());
+ Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc, Ty,
+ &Comps[0], Comps.size(),
+ ConsumeParen());
break;
} else {
// Error occurred.
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 48af5af0a3..2664c57ee4 100644
--- a/lib/Sema/Sema.h
+++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 024ca8138a..270de5546b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/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/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8a37bbbe7b..918fd2ac9a 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/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/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 307e1ad45e..4088f443f7 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/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/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e18f1437ab..eb2e647f01 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -18,6 +18,7 @@<