diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2015-04-02 07:42:19 +0300 |
---|---|---|
committer | Orgad Shaneh <orgads@gmail.com> | 2015-05-15 14:22:10 +0000 |
commit | 372173331c689474b2ca7002a1d7ed770b052b80 (patch) | |
tree | ad1151bfc9dc9ab84f117c58490372a6f1e29969 /src/libs/cplusplus/LookupContext.cpp | |
parent | cf66beffb67fc309445739ccbe69f04f02bff576 (diff) | |
download | qt-creator-372173331c689474b2ca7002a1d7ed770b052b80.tar.gz |
C++: Fix explicit typedef from base type in templated class
Use-case:
struct Foo { int bar; };
template<typename T>
struct Base { typedef T F; };
template<typename T>
struct Derived : Base<T>
{
typedef typename Base<T>::F F;
F f;
};
void func()
{
Derived<Foo> d;
d.f.bar; // bar not highlighted
}
Task-number: QTCREATORBUG-14218
Change-Id: Ic0b22b2f8adf80ff88a2f8b7359c276a744f89e8
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
Diffstat (limited to 'src/libs/cplusplus/LookupContext.cpp')
-rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 100 |
1 files changed, 63 insertions, 37 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 1c9be7bb1e..d4edde6035 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -612,7 +612,10 @@ public: : _cloner(cloner) , _subst(subst) {} - void instantiate(LookupScopePrivate *lookupScope, LookupScopePrivate *instantiation); + void instantiate(LookupScopePrivate *lookupScope, + LookupScopePrivate *instantiation, + bool includeSymbols); + LookupScopePrivate *maybeInstantiate(LookupScopePrivate *lookupScope); private: bool isInstantiationNeeded(LookupScopePrivate *lookupScope) const; @@ -1356,7 +1359,6 @@ LookupScopePrivate *LookupScopePrivate::nestedType(const Name *name, LookupScope // The instantiation should have all symbols, enums, and usings from the reference. instantiation->_enums = reference->_enums; - instantiation->_usings = reference->_usings; instantiation->_rootClass = reference->_rootClass; @@ -1400,8 +1402,9 @@ LookupScopePrivate *LookupScopePrivate::nestedType(const Name *name, LookupScope } Instantiator instantiator(cloner, subst); - instantiator.instantiate(reference, instantiation); + instantiator.instantiate(reference, instantiation, true); } else { + instantiation->_usings = reference->_usings; instantiation->_symbols.append(reference->_symbols); instantiation->_typedefs = reference->_typedefs; } @@ -1477,6 +1480,7 @@ LookupScopePrivate *LookupScopePrivate::nestedType(const Name *name, LookupScope } } else { instantiation->_nestedScopes = reference->_nestedScopes; + instantiation->_usings = reference->_usings; instantiation->_symbols.append(reference->_symbols); instantiation->_typedefs = reference->_typedefs; } @@ -1517,8 +1521,34 @@ LookupScopePrivate *LookupScopePrivate::nestedType(const Name *name, LookupScope return reference; } +LookupScopePrivate *Instantiator::maybeInstantiate(LookupScopePrivate *lookupScope) +{ + lookupScope->flush(); + LookupScopePrivate *instantiation = lookupScope; + + bool hasTemplateSymbols = isInstantiationNeeded(lookupScope); + bool hasTemplateUsings = false; + if (!hasTemplateSymbols) { + foreach (LookupScope *usingLookupScope, lookupScope->_usings) { + if (isInstantiationNeeded(usingLookupScope->d)) { + hasTemplateUsings = true; + break; + } + } + } + if (hasTemplateSymbols || hasTemplateUsings) { + instantiation = lookupScope->allocateChild(lookupScope->_name); + instantiation->_enums = lookupScope->_enums; + instantiation->_instantiationOrigin = lookupScope; + instantiate(lookupScope, instantiation, hasTemplateSymbols); + } + + return instantiation; +} + void Instantiator::instantiate(LookupScopePrivate *lookupScope, - LookupScopePrivate *instantiation) + LookupScopePrivate *instantiation, + bool includeSymbols) { if (_alreadyConsideredInstantiations.contains(lookupScope)) return; @@ -1531,52 +1561,48 @@ void Instantiator::instantiate(LookupScopePrivate *lookupScope, instantiation->_typedefs[typedefit->first] = _cloner.symbol(typedefit->second, &_subst)->asDeclaration(); } - foreach (Symbol *s, lookupScope->_symbols) { - Symbol *clone = _cloner.symbol(s, &_subst); - if (!clone->enclosingScope()) // Not from the cache but just cloned. - clone->setEnclosingScope(s->enclosingScope()); - instantiation->_symbols.append(clone); - if (s == instantiation->_rootClass) { - clone->setName(instantiation->_name); - instantiation->_rootClass = clone->asClass(); - } - if (Q_UNLIKELY(debug)) { - Overview oo; - oo.showFunctionSignatures = true; - oo.showReturnTypes = true; - oo.showTemplateParameters = true; - qDebug() << "cloned" << oo(clone->type()); - if (Class *klass = clone->asClass()) { - const unsigned klassMemberCount = klass->memberCount(); - for (unsigned i = 0; i < klassMemberCount; ++i){ - Symbol *klassMemberAsSymbol = klass->memberAt(i); - if (klassMemberAsSymbol->isTypedef()) { - if (Declaration *declaration = klassMemberAsSymbol->asDeclaration()) - qDebug() << "Member: " << oo(declaration->type(), declaration->name()); + foreach (LookupScope *usingLookupScope, lookupScope->_usings) + instantiation->_usings.append(maybeInstantiate(usingLookupScope->d)->q); + if (includeSymbols) { + foreach (Symbol *s, lookupScope->_symbols) { + Symbol *clone = _cloner.symbol(s, &_subst); + if (!clone->enclosingScope()) // Not from the cache but just cloned. + clone->setEnclosingScope(s->enclosingScope()); + instantiation->_symbols.append(clone); + if (s == instantiation->_rootClass) { + clone->setName(instantiation->_name); + instantiation->_rootClass = clone->asClass(); + } + if (Q_UNLIKELY(debug)) { + Overview oo; + oo.showFunctionSignatures = true; + oo.showReturnTypes = true; + oo.showTemplateParameters = true; + qDebug() << "cloned" << oo(clone->type()); + if (Class *klass = clone->asClass()) { + const unsigned klassMemberCount = klass->memberCount(); + for (unsigned i = 0; i < klassMemberCount; ++i){ + Symbol *klassMemberAsSymbol = klass->memberAt(i); + if (klassMemberAsSymbol->isTypedef()) { + if (Declaration *declaration = klassMemberAsSymbol->asDeclaration()) + qDebug() << "Member: " << oo(declaration->type(), declaration->name()); + } } } } } + } else { + instantiation->_symbols = lookupScope->_symbols; } } auto cit = lookupScope->_nestedScopes.begin(); for (; cit != lookupScope->_nestedScopes.end(); ++cit) { const Name *nestedName = cit->first; LookupScopePrivate *nestedLookupScope = cit->second; - LookupScopePrivate *nestedInstantiation = nestedLookupScope; - nestedLookupScope->flush(); - - const bool instantiationNeeded = isInstantiationNeeded(nestedInstantiation); - if (instantiationNeeded) { - nestedInstantiation = nestedLookupScope->allocateChild(nestedName); - nestedInstantiation->_enums = nestedLookupScope->_enums; - nestedInstantiation->_usings = nestedLookupScope->_usings; - nestedInstantiation->_instantiationOrigin = nestedLookupScope; - } + LookupScopePrivate *nestedInstantiation = maybeInstantiate(nestedLookupScope); if (isNestedInstantiationEnclosingTemplate(nestedInstantiation, lookupScope)) nestedInstantiation->_parent = instantiation; - instantiate(nestedLookupScope, nestedInstantiation); instantiation->_nestedScopes[nestedName] = nestedInstantiation; } |