@@ -222,6 +222,7 @@ namespace {
222
222
bool IsType (NamedDecl *ND) const ;
223
223
bool IsMember (NamedDecl *ND) const ;
224
224
bool IsObjCIvar (NamedDecl *ND) const ;
225
+ bool IsObjCMessageReceiver (NamedDecl *ND) const ;
225
226
// @}
226
227
};
227
228
}
@@ -732,6 +733,78 @@ bool ResultBuilder::IsMember(NamedDecl *ND) const {
732
733
isa<ObjCPropertyDecl>(ND);
733
734
}
734
735
736
+ // / \brief Get the type that a given expression will have if this declaration
737
+ // / is used as an expression in its "typical" code-completion form.
738
+ static QualType getDeclUsageType (ASTContext &C, NamedDecl *ND) {
739
+ ND = cast<NamedDecl>(ND->getUnderlyingDecl ());
740
+
741
+ if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
742
+ return C.getTypeDeclType (Type);
743
+ if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
744
+ return C.getObjCInterfaceType (Iface);
745
+
746
+ QualType T;
747
+ if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
748
+ T = Function->getResultType ();
749
+ else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
750
+ T = Method->getResultType ();
751
+ else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
752
+ T = FunTmpl->getTemplatedDecl ()->getResultType ();
753
+ else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
754
+ T = C.getTypeDeclType (cast<EnumDecl>(Enumerator->getDeclContext ()));
755
+ else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
756
+ T = Property->getType ();
757
+ else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
758
+ T = Value->getType ();
759
+ else
760
+ return QualType ();
761
+
762
+ return T.getNonReferenceType ();
763
+ }
764
+
765
+ static bool isObjCReceiverType (ASTContext &C, QualType T) {
766
+ T = C.getCanonicalType (T);
767
+ switch (T->getTypeClass ()) {
768
+ case Type::ObjCObject:
769
+ case Type::ObjCInterface:
770
+ case Type::ObjCObjectPointer:
771
+ return true ;
772
+
773
+ case Type::Builtin:
774
+ switch (cast<BuiltinType>(T)->getKind ()) {
775
+ case BuiltinType::ObjCId:
776
+ case BuiltinType::ObjCClass:
777
+ case BuiltinType::ObjCSel:
778
+ return true ;
779
+
780
+ default :
781
+ break ;
782
+ }
783
+ return false ;
784
+
785
+ default :
786
+ break ;
787
+ }
788
+
789
+ if (!C.getLangOptions ().CPlusPlus )
790
+ return false ;
791
+
792
+ // FIXME: We could perform more analysis here to determine whether a
793
+ // particular class type has any conversions to Objective-C types. For now,
794
+ // just accept all class types.
795
+ return T->isDependentType () || T->isRecordType ();
796
+ }
797
+
798
+ bool ResultBuilder::IsObjCMessageReceiver (NamedDecl *ND) const {
799
+ QualType T = getDeclUsageType (SemaRef.Context , ND);
800
+ if (T.isNull ())
801
+ return false ;
802
+
803
+ T = SemaRef.Context .getBaseElementType (T);
804
+ return isObjCReceiverType (SemaRef.Context , T);
805
+ }
806
+
807
+
735
808
// / \rief Determines whether the given declaration is an Objective-C
736
809
// / instance variable.
737
810
bool ResultBuilder::IsObjCIvar (NamedDecl *ND) const {
@@ -3021,6 +3094,31 @@ static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3021
3094
.Default (0 );
3022
3095
}
3023
3096
3097
+ void Sema::CodeCompleteObjCMessageReceiver (Scope *S) {
3098
+ typedef CodeCompleteConsumer::Result Result;
3099
+ ResultBuilder Results (*this );
3100
+
3101
+ // Find anything that looks like it could be a message receiver.
3102
+ Results.setFilter (&ResultBuilder::IsObjCMessageReceiver);
3103
+ CodeCompletionDeclConsumer Consumer (Results, CurContext);
3104
+ Results.EnterNewScope ();
3105
+ LookupVisibleDecls (S, LookupOrdinaryName, Consumer);
3106
+
3107
+ // If we are in an Objective-C method inside a class that has a superclass,
3108
+ // add "super" as an option.
3109
+ if (ObjCMethodDecl *Method = getCurMethodDecl ())
3110
+ if (ObjCInterfaceDecl *Iface = Method->getClassInterface ())
3111
+ if (Iface->getSuperClass ())
3112
+ Results.AddResult (Result (" super" ));
3113
+
3114
+ Results.ExitScope ();
3115
+
3116
+ if (CodeCompleter->includeMacros ())
3117
+ AddMacroResults (PP, Results);
3118
+ HandleCodeCompleteResults (this , CodeCompleter, Results.data (),Results.size ());
3119
+
3120
+ }
3121
+
3024
3122
void Sema::CodeCompleteObjCSuperMessage (Scope *S, SourceLocation SuperLoc,
3025
3123
IdentifierInfo **SelIdents,
3026
3124
unsigned NumSelIdents) {
0 commit comments