diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2015-04-09 14:25:23 +0300 |
---|---|---|
committer | Orgad Shaneh <orgads@gmail.com> | 2015-04-23 08:19:10 +0000 |
commit | 8be26d070e3b6bf19907e49a23d26346b0474af8 (patch) | |
tree | 8634d31b16e6ab2667b2fdbb008be81fbee087a2 /src/libs/cplusplus/LookupContext.cpp | |
parent | e1393c71abc9a426c08b1223c0394c5bcd9ae6cd (diff) | |
download | qt-creator-8be26d070e3b6bf19907e49a23d26346b0474af8.tar.gz |
C++: Improve template argument detection for nested types
Change-Id: I7dd3f552f0e85413de8e58047d1fba39c7237182
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
Diffstat (limited to 'src/libs/cplusplus/LookupContext.cpp')
-rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 115 |
1 files changed, 74 insertions, 41 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 69aa682d18..fa3280663f 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -605,9 +605,76 @@ public: void instantiate(LookupScopePrivate *lookupScope, LookupScopePrivate *instantiation); private: bool isInstantiationNeeded(LookupScopePrivate *lookupScope) const; - bool containsTemplateType(Declaration *declaration) const; - bool containsTemplateType(Function *function) const; - NamedType *findNamedType(Type *memberType) const; + + struct TemplateFinder : public TypeVisitor, public NameVisitor + { + public: + TemplateFinder(Subst &subst) : _subst(subst), _found(false) {} + + inline void accept(Type *type) { TypeVisitor::accept(type); } + inline void accept(const Name *name) { NameVisitor::accept(name); } + + bool found() const { return _found; } + private: + void visit(PointerType *type) override { accept(type->elementType().type()); } + void visit(ReferenceType *type) override { accept(type->elementType().type()); } + void visit(NamedType *type) override { accept(type->name()); } + + void visit(Function *type) override + { + accept(type->returnType().type()); + if (_found) + return; + for (int i = 0, total = type->argumentCount(); i < total; ++i) { + accept(type->argumentAt(i)->type().type()); + if (_found) + return; + } + } + + void visit(Class *type) override + { + for (int i = 0, total = type->memberCount(); i < total; ++i) { + accept(type->memberAt(i)->type().type()); + if (_found) + return; + } + } + + void visit(const Identifier *name) override + { + if (_subst.contains(name)) + _found = true; + } + + void visit(const TemplateNameId *name) override + { + if (const Identifier *identifier = name->identifier()) + visit(identifier); + if (_found) + return; + for (unsigned i = 0, total = name->templateArgumentCount(); i < total; ++i) { + accept(name->templateArgumentAt(i).type()); + if (_found) + return; + } + } + + void visit(const ConversionNameId *name) override + { + accept(name->type().type()); + } + + void visit(const QualifiedNameId *name) override + { + accept(name->base()); + if (!_found) + accept(name->name()); + } + + Subst &_subst; + bool _found; + }; ProcessedSet _alreadyConsideredInstantiations; Clone &_cloner; @@ -1461,50 +1528,16 @@ bool Instantiator::isInstantiationNeeded(LookupScopePrivate *lookupScope) const { foreach (Symbol *s, lookupScope->_symbols) { if (Class *klass = s->asClass()) { - int memberCount = klass->memberCount(); - for (int i = 0; i < memberCount; ++i) { - Symbol *memberAsSymbol = klass->memberAt(i); - if (Declaration *declaration = memberAsSymbol->asDeclaration()) { - if (containsTemplateType(declaration)) - return true; - } else if (Function *function = memberAsSymbol->asFunction()) { - if (containsTemplateType(function)) - return true; - } - } + TemplateFinder finder(_subst); + finder.accept(klass); + if (finder.found()) + return true; } } return false; } -bool Instantiator::containsTemplateType(Declaration *declaration) const -{ - Type *memberType = declaration->type().type(); - NamedType *namedType = findNamedType(memberType); - return namedType && _subst.contains(namedType->name()); -} - -bool Instantiator::containsTemplateType(Function *function) const -{ - Type *returnType = function->returnType().type(); - NamedType *namedType = findNamedType(returnType); - return namedType && _subst.contains(namedType->name()); - //TODO: in future we will need also check function arguments, for now returned value is enough -} - -NamedType *Instantiator::findNamedType(Type *memberType) const -{ - if (NamedType *namedType = memberType->asNamedType()) - return namedType; - else if (PointerType *pointerType = memberType->asPointerType()) - return findNamedType(pointerType->elementType().type()); - else if (ReferenceType *referenceType = memberType->asReferenceType()) - return findNamedType(referenceType->elementType().type()); - - return 0; -} - void LookupScopePrivate::flush() { if (! _todo.isEmpty()) { |