[cfe-commits] r118052 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaLookup.cpp test/Index/complete-synthesized.m
Douglas Gregor
dgregor at apple.com
Tue Nov 2 13:36:02 PDT 2010
Author: dgregor
Date: Tue Nov 2 15:36:02 2010
New Revision: 118052
URL: http://llvm.org/viewvc/llvm-project?rev=118052&view=rev
Log:
Teach code completion to provide property results when the property
can be used to automatically synthesize an ivar.
Added:
cfe/trunk/test/Index/complete-synthesized.m
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=118052&r1=118051&r2=118052&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Nov 2 15:36:02 2010
@@ -1377,6 +1377,14 @@
ObjCIvarDecl **Fields, unsigned nIvars,
SourceLocation Loc);
+ /// \brief Determine whether we can synthesize a provisional ivar for the
+ /// given name.
+ ObjCPropertyDecl *canSynthesizeProvisionalIvar(IdentifierInfo *II);
+
+ /// \brief Determine whether we can synthesize a provisional ivar for the
+ /// given property.
+ bool canSynthesizeProvisionalIvar(ObjCPropertyDecl *Property);
+
/// ImplMethodsVsClassMethods - This is main routine to warn if any method
/// remains unimplemented in the class or category @implementation.
void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=118052&r1=118051&r2=118052&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Nov 2 15:36:02 2010
@@ -147,9 +147,13 @@
/// \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 @@
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 @@
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 @@
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 @@
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;
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=118052&r1=118051&r2=118052&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 2 15:36:02 2010
@@ -1027,25 +1027,41 @@
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 @@
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);
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=118052&r1=118051&r2=118052&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Nov 2 15:36:02 2010
@@ -2630,9 +2630,27 @@
// 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
Added: cfe/trunk/test/Index/complete-synthesized.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-synthesized.m?rev=118052&view=auto
==============================================================================
--- cfe/trunk/test/Index/complete-synthesized.m (added)
+++ cfe/trunk/test/Index/complete-synthesized.m Tue Nov 2 15:36:02 2010
@@ -0,0 +1,56 @@
+// Note: this test is line- and column-sensitive. Test commands are at
+// the end.
+
+
+ at interface A
+ at property int prop1;
+ at end
+
+ at interface B : A {
+ float _prop2;
+}
+ at property float prop2;
+ at property short prop3;
+ at end
+
+ at interface B ()
+ at property double prop4;
+ at end
+
+ at implementation B
+ at synthesize prop2 = _prop2;
+
+- (int)method {
+ return _prop2;
+}
+
+ at dynamic prop3;
+
+- (short)method2 {
+ return prop4;
+}
+
+- (short)method3 {
+ return prop3;
+}
+ at end
+
+// RUN: c-index-test -code-completion-at=%s:24:1 -Xclang -fobjc-nonfragile-abi2 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: NotImplemented:{TypedText _Bool} (50)
+// CHECK-CC1: ObjCIvarDecl:{ResultType float}{TypedText _prop2} (35)
+// CHECK-CC1-NOT: prop2
+// CHECK-CC1: ObjCPropertyDecl:{ResultType short}{TypedText prop3} (35)
+// CHECK-CC1: ObjCPropertyDecl:{ResultType double}{TypedText prop4} (35)
+
+// RUN: c-index-test -code-completion-at=%s:30:2 -Xclang -fobjc-nonfragile-abi2 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: NotImplemented:{TypedText _Bool} (50)
+// CHECK-CC2: ObjCIvarDecl:{ResultType float}{TypedText _prop2} (35)
+// CHECK-CC2-NOT: prop3
+// CHECK-CC2: ObjCPropertyDecl:{ResultType double}{TypedText prop4} (35)
+
+// RUN: c-index-test -code-completion-at=%s:34:2 -Xclang -fobjc-nonfragile-abi2 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: NotImplemented:{TypedText _Bool} (50)
+// CHECK-CC3: ObjCIvarDecl:{ResultType float}{TypedText _prop2} (35)
+// CHECK-CC3: ObjCIvarDecl:{ResultType double}{TypedText prop4}
+// CHECK-CC3-NOT: ObjCPropertyDecl:{ResultType double}{TypedText prop4} (35)
+// CHECK-CC1: restrict
More information about the cfe-commits
mailing list