diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 52 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 20 |
3 files changed, 85 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index b07ae391f96..c245e38bb40 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -147,9 +147,13 @@ namespace { /// \brief The selector that we prefer. Selector PreferredSelector; - /// \brief The completion context in which + /// \brief The completion context in which we are gathering results. CodeCompletionContext CompletionContext; + /// \brief If we are in an instance method definition, the @implementation + /// object. + ObjCImplementationDecl *ObjCImplementation; + void AdjustResultPriorityForDecl(Result &R); void MaybeAddConstructorResults(Result R); @@ -160,7 +164,27 @@ namespace { LookupFilter Filter = 0) : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false), - CompletionContext(CompletionContext) { } + CompletionContext(CompletionContext), + ObjCImplementation(0) + { + // If this is an Objective-C instance method definition, dig out the + // corresponding implementation. + switch (CompletionContext.getKind()) { + case CodeCompletionContext::CCC_Expression: + case CodeCompletionContext::CCC_ObjCMessageReceiver: + case CodeCompletionContext::CCC_ParenthesizedExpression: + case CodeCompletionContext::CCC_Statement: + case CodeCompletionContext::CCC_Recovery: + if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) + if (Method->isInstanceMethod()) + if (ObjCInterfaceDecl *Interface = Method->getClassInterface()) + ObjCImplementation = Interface->getImplementation(); + break; + + default: + break; + } + } /// \brief Whether we should include code patterns in the completion /// results. @@ -203,7 +227,7 @@ namespace { void setPreferredSelector(Selector Sel) { PreferredSelector = Sel; } - + /// \brief Retrieve the code-completion context for which results are /// being collected. const CodeCompletionContext &getCompletionContext() const { @@ -919,9 +943,14 @@ bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const { unsigned IDNS = Decl::IDNS_Ordinary; if (SemaRef.getLangOptions().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; - else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND)) - return true; - + else if (SemaRef.getLangOptions().ObjC1) { + if (isa<ObjCIvarDecl>(ND)) + return true; + if (isa<ObjCPropertyDecl>(ND) && + SemaRef.canSynthesizeProvisionalIvar(cast<ObjCPropertyDecl>(ND))) + return true; + } + return ND->getIdentifierNamespace() & IDNS; } @@ -935,9 +964,14 @@ bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const { unsigned IDNS = Decl::IDNS_Ordinary; if (SemaRef.getLangOptions().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; - else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND)) - return true; - + else if (SemaRef.getLangOptions().ObjC1) { + if (isa<ObjCIvarDecl>(ND)) + return true; + if (isa<ObjCPropertyDecl>(ND) && + SemaRef.canSynthesizeProvisionalIvar(cast<ObjCPropertyDecl>(ND))) + return true; + } + return ND->getIdentifierNamespace() & IDNS; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9e28172c97e..fdc4828cf11 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1027,25 +1027,41 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, return true; } -static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef, - IdentifierInfo *II, - SourceLocation NameLoc) { - ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl(); +ObjCPropertyDecl *Sema::canSynthesizeProvisionalIvar(IdentifierInfo *II) { + ObjCMethodDecl *CurMeth = getCurMethodDecl(); ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface(); if (!IDecl) return 0; ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation(); if (!ClassImpDecl) return 0; - ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II); + ObjCPropertyDecl *property = LookupPropertyDecl(IDecl, II); if (!property) return 0; if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II)) - if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) + if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic || + PIDecl->getPropertyIvarDecl()) return 0; return property; } +bool Sema::canSynthesizeProvisionalIvar(ObjCPropertyDecl *Property) { + ObjCMethodDecl *CurMeth = getCurMethodDecl(); + ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface(); + if (!IDecl) + return false; + ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation(); + if (!ClassImpDecl) + return false; + if (ObjCPropertyImplDecl *PIDecl + = ClassImpDecl->FindPropertyImplDecl(Property->getIdentifier())) + if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic || + PIDecl->getPropertyIvarDecl()) + return false; + + return true; +} + static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef, LookupResult &Lookup, IdentifierInfo *II, @@ -1228,8 +1244,7 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp && !getLangOptions().ObjCNonFragileABI2 && Var->isFileVarDecl()) { - ObjCPropertyDecl *Property = - OkToSynthesizeProvisionalIvar(*this, II, NameLoc); + ObjCPropertyDecl *Property = canSynthesizeProvisionalIvar(II); if (Property) { Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName(); Diag(Property->getLocation(), diag::note_property_declare); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index acc5b354f8a..f0c21f43962 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2630,9 +2630,27 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result, // For instance methods, look for ivars in the method's interface. LookupResult IvarResult(Result.getSema(), Result.getLookupName(), Result.getNameLoc(), Sema::LookupMemberName); - if (ObjCInterfaceDecl *IFace = Method->getClassInterface()) + if (ObjCInterfaceDecl *IFace = Method->getClassInterface()) { LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false, /*InBaseClass=*/false, Consumer, Visited); + + // Look for properties from which we can synthesize ivars, if + // permitted. + if (Result.getSema().getLangOptions().ObjCNonFragileABI2 && + IFace->getImplementation() && + Result.getLookupKind() == Sema::LookupOrdinaryName) { + for (ObjCInterfaceDecl::prop_iterator + P = IFace->prop_begin(), + PEnd = IFace->prop_end(); + P != PEnd; ++P) { + if (Result.getSema().canSynthesizeProvisionalIvar(*P) && + !IFace->lookupInstanceVariable((*P)->getIdentifier())) { + Consumer.FoundDecl(*P, Visited.checkHidden(*P), false); + Visited.add(*P); + } + } + } + } } // We've already performed all of the name lookup that we need |