aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCodeComplete.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r--lib/Sema/SemaCodeComplete.cpp114
1 files changed, 67 insertions, 47 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index cb60f0aba1..e71f8c84eb 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2947,62 +2947,82 @@ static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
.Default(0);
}
-void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
- SourceLocation FNameLoc,
+void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
IdentifierInfo **SelIdents,
unsigned NumSelIdents) {
- typedef CodeCompleteConsumer::Result Result;
ObjCInterfaceDecl *CDecl = 0;
+ 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 (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(SuperLoc, SuperTy));
+ return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
+ SelIdents, NumSelIdents);
+ }
- 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(FNameLoc, SuperTy));
- return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
- SelIdents, NumSelIdents);
- }
+ // Fall through to send to the superclass in CDecl.
+ } else {
+ // "super" may be the name of a type or variable. Figure out which
+ // it is.
+ IdentifierInfo *Super = &Context.Idents.get("super");
+ NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
+ LookupOrdinaryName);
+ if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
+ // "super" names an interface. Use it.
+ } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
+ if (const ObjCInterfaceType *Iface
+ = Context.getTypeDeclType(TD)->getAs<ObjCInterfaceType>())
+ CDecl = Iface->getDecl();
+ } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
+ // "super" names an unresolved type; we can't be more specific.
+ } else {
+ // Assume that "super" names some kind of value and parse that way.
+ CXXScopeSpec SS;
+ UnqualifiedId id;
+ id.setIdentifier(Super, SuperLoc);
+ OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
+ return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
+ SelIdents, NumSelIdents);
+ }
- // Okay, we're calling a factory method in our superclass.
- }
+ // Fall through
}
+ TypeTy *Receiver = 0;
+ if (CDecl)
+ Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
+ return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
+ NumSelIdents);
+}
+
+void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
+ typedef CodeCompleteConsumer::Result Result;
+ ObjCInterfaceDecl *CDecl = 0;
+
// If the given name refers to an interface type, retrieve the
// corresponding declaration.
- if (!CDecl)
- if (TypeTy *Ty = getTypeName(*FName, FNameLoc, 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.
- CXXScopeSpec SS;
- UnqualifiedId id;
- id.setIdentifier(FName, FNameLoc);
- OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
- return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
- SelIdents, NumSelIdents);
+ if (Receiver) {
+ QualType T = GetTypeFromParser(Receiver, 0);
+ if (!T.isNull())
+ if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
+ CDecl = Interface->getDecl();
}
// Add all of the factory methods in this Objective-C class, its protocols,
@@ -3013,7 +3033,7 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
if (CDecl)
AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
Results);
- else if (FName->isStr("id")) {
+ else {
// We're messaging "id" as a type; provide all class/factory methods.
// If we have an external source, load the entire class method