diff options
-rw-r--r-- | Driver/PrintParserCallbacks.cpp | 5 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 18 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 5 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 163 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 8 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 139 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 29 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 86 |
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 @@< |