diff options
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 97 |
1 files changed, 79 insertions, 18 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 337a4a3..4555a86 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -665,6 +665,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { // DeclContext *OutsideOfTemplateParamDC = 0; for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) { + DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity()); + // Check whether the IdResolver has anything in this scope. bool Found = false; for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) { @@ -675,10 +677,12 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { } if (Found) { R.resolveKind(); + if (S->isClassScope()) + if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(Ctx)) + R.setNamingClass(Record); return true; } - DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity()); if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC && S->getParent() && !S->getParent()->isTemplateParamScope()) { // We've just searched the last template parameter scope and @@ -761,10 +765,6 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { // context as well as walking through the scopes. for (; S; S = S->getParent()) { - DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity()); - if (Ctx && Ctx->isTransparentContext()) - continue; - // Check whether the IdResolver has anything in this scope. bool Found = false; for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) { @@ -778,21 +778,57 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { } } - // If we have a context, and it's not a context stashed in the - // template parameter scope for an out-of-line definition, also - // look into that context. - if (Ctx && !(Found && S && S->isTemplateParamScope())) { - assert(Ctx->isFileContext() && - "We should have been looking only at file context here already."); + if (Found && S->isTemplateParamScope()) { + R.resolveKind(); + return true; + } - // Look into context considering using-directives. - if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) - Found = true; + DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity()); + if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC && + S->getParent() && !S->getParent()->isTemplateParamScope()) { + // We've just searched the last template parameter scope and + // found nothing, so look into the the contexts between the + // lexical and semantic declaration contexts returned by + // findOuterContext(). This implements the name lookup behavior + // of C++ [temp.local]p8. + Ctx = OutsideOfTemplateParamDC; + OutsideOfTemplateParamDC = 0; } + + if (Ctx) { + DeclContext *OuterCtx; + bool SearchAfterTemplateScope; + llvm::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S); + if (SearchAfterTemplateScope) + OutsideOfTemplateParamDC = OuterCtx; - if (Found) { - R.resolveKind(); - return true; + for (; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) { + // We do not directly look into transparent contexts, since + // those entities will be found in the nearest enclosing + // non-transparent context. + if (Ctx->isTransparentContext()) + continue; + + // If we have a context, and it's not a context stashed in the + // template parameter scope for an out-of-line definition, also + // look into that context. + if (!(Found && S && S->isTemplateParamScope())) { + assert(Ctx->isFileContext() && + "We should have been looking only at file context here already."); + + // Look into context considering using-directives. + if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) + Found = true; + } + + if (Found) { + R.resolveKind(); + return true; + } + + if (R.isForRedeclaration() && !Ctx->isTransparentContext()) + return false; + } } if (R.isForRedeclaration() && Ctx && !Ctx->isTransparentContext()) @@ -2580,6 +2616,12 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS, WantExpressionKeywords = true; WantCXXNamedCasts = true; WantRemainingKeywords = true; + + if (ObjCMethodDecl *Method = getCurMethodDecl()) + if (Method->getClassInterface() && + Method->getClassInterface()->getSuperClass()) + Consumer.addKeywordResult(Context, "super"); + break; case CTC_NoKeywords: @@ -2646,7 +2688,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS, Consumer.addKeywordResult(Context, "typeof"); } - if (WantCXXNamedCasts) { + if (WantCXXNamedCasts && getLangOptions().CPlusPlus) { Consumer.addKeywordResult(Context, "const_cast"); Consumer.addKeywordResult(Context, "dynamic_cast"); Consumer.addKeywordResult(Context, "reinterpret_cast"); @@ -2776,6 +2818,25 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS, BestIvarOrPropertyDecl = 0; FoundIvarOrPropertyDecl = false; Consumer.clear_decls(); + } else if (CTC == CTC_ObjCMessageReceiver && + (*Consumer.keyword_begin())->isStr("super")) { + // In an Objective-C message send, give the "super" keyword a slight + // edge over entities not in function or method scope. + for (TypoCorrectionConsumer::iterator I = Consumer.begin(), + IEnd = Consumer.end(); + I != IEnd; ++I) { + if ((*I)->getDeclName() == BestName) { + if ((*I)->getDeclContext()->isFunctionOrMethod()) + return DeclarationName(); + } + } + + // Everything found was outside a function or method; the 'super' + // keyword takes precedence. + BestIvarOrPropertyDecl = 0; + FoundIvarOrPropertyDecl = false; + Consumer.clear_decls(); + BestName = *Consumer.keyword_begin(); } else { // Name collision; we will not correct typos. return DeclarationName(); |