[cfe-commits] r89112 - in /cfe/trunk: lib/Sema/SemaCodeComplete.cpp test/Index/complete-objc-message.m
Douglas Gregor
dgregor at apple.com
Tue Nov 17 09:59:40 PST 2009
Author: dgregor
Date: Tue Nov 17 11:59:40 2009
New Revision: 89112
URL: http://llvm.org/viewvc/llvm-project?rev=89112&view=rev
Log:
Implement code completion for Objective-C message sends to "super".
Modified:
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/test/Index/complete-objc-message.m
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=89112&r1=89111&r2=89112&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Nov 17 11:59:40 2009
@@ -13,6 +13,7 @@
#include "Sema.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -1555,11 +1556,61 @@
void Sema::CodeCompleteObjCFactoryMethod(Scope *S, IdentifierInfo *FName) {
typedef CodeCompleteConsumer::Result Result;
+ ObjCInterfaceDecl *CDecl = 0;
+
+ // FIXME: Pass this in!
+ SourceLocation NameLoc;
+
+ if (FName->isStr("super")) {
+ // We're sending a message to "super".
+ if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
+ // Figure out which interface we're in.
+ CDecl = CurMethod->getClassInterface();
+ if (!CDecl)
+ return;
+
+ // Find the superclass of this class.
+ CDecl = CDecl->getSuperClass();
+ if (!CDecl)
+ return;
+
+ if (CurMethod->isInstanceMethod()) {
+ // We are inside an instance method, which means that the message
+ // send [super ...] is actually calling an instance method on the
+ // current object. Build the super expression and handle this like
+ // an instance method.
+ QualType SuperTy = Context.getObjCInterfaceType(CDecl);
+ SuperTy = Context.getObjCObjectPointerType(SuperTy);
+ OwningExprResult Super
+ = Owned(new (Context) ObjCSuperExpr(NameLoc, SuperTy));
+ return CodeCompleteObjCInstanceMethod(S, (Expr *)Super.get());
+ }
+
+ // Okay, we're calling a factory method in our superclass.
+ }
+ }
+
+ // If the given name refers to an interface type, retrieve the
+ // corresponding declaration.
+ if (!CDecl)
+ if (TypeTy *Ty = getTypeName(*FName, NameLoc, S, 0, false)) {
+ QualType T = GetTypeFromParser(Ty, 0);
+ if (!T.isNull())
+ if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
+ CDecl = Interface->getDecl();
+ }
+
+ if (!CDecl && FName->isStr("super")) {
+ // "super" may be the name of a variable, in which case we are
+ // probably calling an instance method.
+ OwningExprResult Super = ActOnDeclarationNameExpr(S, NameLoc, FName,
+ false, 0, false);
+ return CodeCompleteObjCInstanceMethod(S, (Expr *)Super.get());
+ }
+
ResultBuilder Results(*this);
Results.EnterNewScope();
- ObjCInterfaceDecl *CDecl = getObjCInterfaceDecl(FName);
-
while (CDecl != NULL) {
for (ObjCInterfaceDecl::classmeth_iterator I = CDecl->classmeth_begin(),
E = CDecl->classmeth_end();
Modified: cfe/trunk/test/Index/complete-objc-message.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-objc-message.m?rev=89112&r1=89111&r2=89112&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-objc-message.m (original)
+++ cfe/trunk/test/Index/complete-objc-message.m Tue Nov 17 11:59:40 2009
@@ -23,6 +23,57 @@
Foo *obj = [Foo new];
[obj xx];
}
+
+ at interface MyClass { }
++ (int)MyClassMethod:(id)obj;
+- (int)MyInstMethod:(id)x second:(id)y;
+ at end
+
+ at interface MySubClass : MyClass { }
++ (int)MySubClassMethod;
+- (int)MySubInstMethod;
+ at end
+
+ at implementation MyClass
++ (int)MyClassMethod:(id)obj {
+ return 0;
+}
+
++ (int)MyPrivateMethod {
+ return 1;
+}
+
+- (int)MyInstMethod:(id)x second:(id)y {
+ return 2;
+}
+
+- (int)MyPrivateInstMethod {
+ return 3;
+}
+ at end
+
+ at implementation MySubClass
++ (int)MySubClassMethod {
+ return 2;
+}
+
++ (int)MySubPrivateMethod {
+ return [super MyPrivateMethod];
+}
+
+- (int)MySubInstMethod:(id)obj {
+ return [super MyInstMethod: obj second:obj];
+}
+
+- (int)MyInstMethod:(id)x second:(id)y {
+ return 3;
+}
+ at end
+
+void test_super_var(MySubClass *super) {
+ [super MyInstMethod: super second:super];
+}
+
// RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: {TypedText categoryClassMethod}
// CHECK-CC1: {TypedText classMethod2}
@@ -33,3 +84,13 @@
// CHECK-CC2: {TypedText categoryInstanceMethod}
// CHECK-CC2: {TypedText instanceMethod1}
// CHECK-CC2: {TypedText protocolInstanceMethod:}{Placeholder (int)value}
+// RUN: c-index-test -code-completion-at=%s:61:16 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCClassMethodDecl:{TypedText MyClassMethod:}{Placeholder (id)obj}
+// FIXME-CC3: ObjCClassMethodDecl:{TypedText MyPrivateMethod}
+// RUN: c-index-test -code-completion-at=%s:65:16 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText MyInstMethod:}{Placeholder (id)x}{Text second:}{Placeholder (id)y}
+// FIXME-CC4: ObjCInstanceMethodDecl:{TypedText MyPrivateInstMethod}
+// RUN: c-index-test -code-completion-at=%s:74:9 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCInstanceMethodDecl:{TypedText MySubInstMethod}
+// CHECK-CC5: ObjCInstanceMethodDecl:{TypedText MyInstMethod:}{Placeholder (id)x}{Text second:}{Placeholder (id)y}
+
More information about the cfe-commits
mailing list