summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/LookupContext.cpp
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2015-04-02 07:42:19 +0300
committerOrgad Shaneh <orgads@gmail.com>2015-05-15 14:22:10 +0000
commit372173331c689474b2ca7002a1d7ed770b052b80 (patch)
treead1151bfc9dc9ab84f117c58490372a6f1e29969 /src/libs/cplusplus/LookupContext.cpp
parentcf66beffb67fc309445739ccbe69f04f02bff576 (diff)
downloadqt-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.cpp100
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;
}