summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/LookupContext.cpp
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2015-04-09 14:25:23 +0300
committerOrgad Shaneh <orgads@gmail.com>2015-04-23 08:19:10 +0000
commit8be26d070e3b6bf19907e49a23d26346b0474af8 (patch)
tree8634d31b16e6ab2667b2fdbb008be81fbee087a2 /src/libs/cplusplus/LookupContext.cpp
parente1393c71abc9a426c08b1223c0394c5bcd9ae6cd (diff)
downloadqt-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.cpp115
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()) {