diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index ba926cc81ee..4015bf6fc06 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1204,6 +1204,28 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor, } } + if (result.first->isObjCForwardClassDeclarationType()) { + while (! resolvedSymbols.isEmpty()) { + TypeOfExpression::Result r = resolvedSymbols.takeFirst(); + + if (! r.first->isObjCForwardClassDeclarationType()) { + result = r; + break; + } + } + } + + if (result.first->isObjCForwardProtocolDeclarationType()) { + while (! resolvedSymbols.isEmpty()) { + TypeOfExpression::Result r = resolvedSymbols.takeFirst(); + + if (! r.first->isObjCForwardProtocolDeclarationType()) { + result = r; + break; + } + } + } + if (Symbol *symbol = result.second) { Symbol *def = 0; if (resolveTarget && !lastSymbol->isFunction()) diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp index 27b33e62175..2496454d041 100644 --- a/src/shared/cplusplus/Symbols.cpp +++ b/src/shared/cplusplus/Symbols.cpp @@ -557,7 +557,8 @@ void Class::visitSymbol0(SymbolVisitor *visitor) ObjCClass::ObjCClass(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name): ScopedSymbol(translationUnit, sourceLocation, name), - _categoryName(0) + _categoryName(0), + _baseClass(0) { } @@ -584,10 +585,14 @@ bool ObjCClass::isEqualTo(const Type *other) const void ObjCClass::visitSymbol0(SymbolVisitor *visitor) { if (visitor->visit(this)) { - for (unsigned i = 0; i < _baseClasses.size(); ++i) - visitSymbol(_baseClasses.at(i), visitor); + if (_baseClass) + visitSymbol(_baseClass, visitor); + for (unsigned i = 0; i < _protocols.size(); ++i) visitSymbol(_protocols.at(i), visitor); + + for (unsigned i = 0; i < memberCount(); ++i) + visitSymbol(memberAt(i), visitor); } } @@ -641,9 +646,26 @@ ObjCForwardClassDeclaration::~ObjCForwardClassDeclaration() FullySpecifiedType ObjCForwardClassDeclaration::type() const { return FullySpecifiedType(); } +bool ObjCForwardClassDeclaration::isEqualTo(const Type *other) const +{ + if (const ObjCForwardClassDeclaration *otherFwdClass = other->asObjCForwardClassDeclarationType()) { + if (name() == otherFwdClass->name()) + return true; + else if (name() && otherFwdClass->name()) + return name()->isEqualTo(otherFwdClass->name()); + else + return false; + } + + return false; +} + void ObjCForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor) { visitor->visit(this); } +void ObjCForwardClassDeclaration::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + ObjCForwardProtocolDeclaration::ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name): Symbol(translationUnit, sourceLocation, name) { @@ -655,9 +677,26 @@ ObjCForwardProtocolDeclaration::~ObjCForwardProtocolDeclaration() FullySpecifiedType ObjCForwardProtocolDeclaration::type() const { return FullySpecifiedType(); } +bool ObjCForwardProtocolDeclaration::isEqualTo(const Type *other) const +{ + if (const ObjCForwardProtocolDeclaration *otherFwdProtocol = other->asObjCForwardProtocolDeclarationType()) { + if (name() == otherFwdProtocol->name()) + return true; + else if (name() && otherFwdProtocol->name()) + return name()->isEqualTo(otherFwdProtocol->name()); + else + return false; + } + + return false; +} + void ObjCForwardProtocolDeclaration::visitSymbol0(SymbolVisitor *visitor) { visitor->visit(this); } +void ObjCForwardProtocolDeclaration::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + ObjCMethod::ObjCMethod(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name) : ScopedSymbol(translationUnit, sourceLocation, name), _flags(0) diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h index a911c21ab97..7ed4cf30f9a 100644 --- a/src/shared/cplusplus/Symbols.h +++ b/src/shared/cplusplus/Symbols.h @@ -472,23 +472,31 @@ private: Array _baseClasses; }; -class CPLUSPLUS_EXPORT ObjCForwardProtocolDeclaration: public Symbol +class CPLUSPLUS_EXPORT ObjCForwardProtocolDeclaration: public Symbol, public Type { public: ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name); virtual ~ObjCForwardProtocolDeclaration(); - // Symbol's interface virtual FullySpecifiedType type() const; + virtual bool isEqualTo(const Type *other) const; + virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return this; } virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return this; } + virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() const + { return this; } + + virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() + { return this; } + protected: virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); private: }; @@ -525,23 +533,31 @@ private: Array _protocols; }; -class CPLUSPLUS_EXPORT ObjCForwardClassDeclaration: public Symbol +class CPLUSPLUS_EXPORT ObjCForwardClassDeclaration: public Symbol, public Type { public: ObjCForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name); virtual ~ObjCForwardClassDeclaration(); - // Symbol's interface virtual FullySpecifiedType type() const; + virtual bool isEqualTo(const Type *other) const; + virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const { return this; } virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() { return this; } + virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() const + { return this; } + + virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() + { return this; } + protected: virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); private: }; @@ -559,6 +575,20 @@ public: Name *categoryName() const { return _categoryName; } void setCategoryName(Name *categoryName) { _categoryName = categoryName; } + ObjCClass *baseClass() const + { return _baseClass; } + void setBaseClass(ObjCClass *baseClass) + { _baseClass = baseClass; } + + unsigned protocolCount() const + { return _protocols.count(); } + + ObjCProtocol *protocolAt(unsigned index) const + { return _protocols.at(index); } + + void addProtocol(ObjCProtocol *protocol) + { _protocols.push_back(protocol); } + // Symbol's interface virtual FullySpecifiedType type() const; @@ -584,7 +614,7 @@ protected: private: bool _isInterface; Name *_categoryName; - Array _baseClasses; + ObjCClass * _baseClass; Array _protocols; }; diff --git a/src/shared/cplusplus/Type.cpp b/src/shared/cplusplus/Type.cpp index 2d2a94f9467..99cef5fab4c 100644 --- a/src/shared/cplusplus/Type.cpp +++ b/src/shared/cplusplus/Type.cpp @@ -110,6 +110,12 @@ bool Type::isObjCProtocolType() const bool Type::isObjCMethodType() const { return asObjCMethodType() != 0; } +bool Type::isObjCForwardClassDeclarationType() const +{ return asObjCForwardClassDeclarationType() != 0; } + +bool Type::isObjCForwardProtocolDeclarationType() const +{ return asObjCForwardProtocolDeclarationType() != 0; } + void Type::accept(TypeVisitor *visitor) { if (visitor->preVisit(this)) diff --git a/src/shared/cplusplus/Type.h b/src/shared/cplusplus/Type.h index 74f64ec932a..a3c5fb0c006 100644 --- a/src/shared/cplusplus/Type.h +++ b/src/shared/cplusplus/Type.h @@ -80,6 +80,8 @@ public: bool isObjCClassType() const; bool isObjCProtocolType() const; bool isObjCMethodType() const; + bool isObjCForwardClassDeclarationType() const; + bool isObjCForwardProtocolDeclarationType() const; virtual const VoidType *asVoidType() const { return 0; } virtual const IntegerType *asIntegerType() const { return 0; } @@ -97,6 +99,8 @@ public: virtual const ObjCClass *asObjCClassType() const { return 0; } virtual const ObjCProtocol *asObjCProtocolType() const { return 0; } virtual const ObjCMethod *asObjCMethodType() const { return 0; } + virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() const { return 0; } + virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() const { return 0; } virtual VoidType *asVoidType() { return 0; } virtual IntegerType *asIntegerType() { return 0; } @@ -114,6 +118,8 @@ public: virtual ObjCClass *asObjCClassType() { return 0; } virtual ObjCProtocol *asObjCProtocolType() { return 0; } virtual ObjCMethod *asObjCMethodType() { return 0; } + virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() { return 0; } + virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() { return 0; } void accept(TypeVisitor *visitor); static void accept(Type *type, TypeVisitor *visitor); diff --git a/src/shared/cplusplus/TypeVisitor.h b/src/shared/cplusplus/TypeVisitor.h index 7e1ce82666f..50337ae93f3 100644 --- a/src/shared/cplusplus/TypeVisitor.h +++ b/src/shared/cplusplus/TypeVisitor.h @@ -84,6 +84,8 @@ public: virtual void visit(ObjCClass *) {} virtual void visit(ObjCProtocol *) {} virtual void visit(ObjCMethod *) {} + virtual void visit(ObjCForwardClassDeclaration *) {} + virtual void visit(ObjCForwardProtocolDeclaration*) {} }; CPLUSPLUS_END_NAMESPACE