summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/LookupContext.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2012-10-08 13:23:21 +0200
committerErik Verbruggen <erik.verbruggen@digia.com>2012-10-11 16:13:32 +0200
commitba75725a7a6855538a1a5516786440e5ab189f93 (patch)
tree513e654894d0f7be4444a37ea57b93d12e37e2cd /src/libs/cplusplus/LookupContext.cpp
parentcc69195c6f4ee00475c5659fc3ff8a492224ced0 (diff)
downloadqt-creator-ba75725a7a6855538a1a5516786440e5ab189f93.tar.gz
C++: fix member rewriting when doing template instantiation.
Task-number: QTCREATORBUG-7964 Change-Id: Icc7d87bb4f2d1ab0560a6c06187d9c23da9fe3e9 Reviewed-by: David Schulz <david.schulz@digia.com>
Diffstat (limited to 'src/libs/cplusplus/LookupContext.cpp')
-rw-r--r--src/libs/cplusplus/LookupContext.cpp52
1 files changed, 36 insertions, 16 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 51efb92a29..1fbe5c5e60 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -120,21 +120,12 @@ bool compareFullyQualifiedName(const QList<const Name *> &path, const QList<cons
}
-bool ClassOrNamespace::CompareName::operator()(const Name *name, const Name *other) const
-{
- Q_ASSERT(name != 0);
- Q_ASSERT(other != 0);
-
- const Identifier *id = name->identifier();
- const Identifier *otherId = other->identifier();
- return strcmp(id->chars(), otherId->chars()) < 0;
-}
-
/////////////////////////////////////////////////////////////////////
// LookupContext
/////////////////////////////////////////////////////////////////////
LookupContext::LookupContext()
: _control(new Control())
+ , m_expandTemplates(false)
{ }
LookupContext::LookupContext(Document::Ptr thisDocument,
@@ -142,7 +133,8 @@ LookupContext::LookupContext(Document::Ptr thisDocument,
: _expressionDocument(Document::create("<LookupContext>")),
_thisDocument(thisDocument),
_snapshot(snapshot),
- _control(new Control())
+ _control(new Control()),
+ m_expandTemplates(false)
{
}
@@ -152,7 +144,8 @@ LookupContext::LookupContext(Document::Ptr expressionDocument,
: _expressionDocument(expressionDocument),
_thisDocument(thisDocument),
_snapshot(snapshot),
- _control(new Control())
+ _control(new Control()),
+ m_expandTemplates(false)
{
}
@@ -161,7 +154,8 @@ LookupContext::LookupContext(const LookupContext &other)
_thisDocument(other._thisDocument),
_snapshot(other._snapshot),
_bindings(other._bindings),
- _control(other._control)
+ _control(other._control),
+ m_expandTemplates(other.m_expandTemplates)
{ }
LookupContext &LookupContext::operator = (const LookupContext &other)
@@ -171,6 +165,7 @@ LookupContext &LookupContext::operator = (const LookupContext &other)
_snapshot = other._snapshot;
_bindings = other._bindings;
_control = other._control;
+ m_expandTemplates = other.m_expandTemplates;
return *this;
}
@@ -227,8 +222,10 @@ const Name *LookupContext::minimalName(Symbol *symbol, ClassOrNamespace *target,
QSharedPointer<CreateBindings> LookupContext::bindings() const
{
- if (! _bindings)
+ if (! _bindings) {
_bindings = QSharedPointer<CreateBindings>(new CreateBindings(_thisDocument, _snapshot, control()));
+ _bindings->setExpandTemplates(m_expandTemplates);
+ }
return _bindings;
}
@@ -728,7 +725,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
instantiation->_instantiationOrigin = origin;
// The instantiation should have all symbols, enums, and usings from the reference.
- instantiation->_symbols.append(reference->symbols());
instantiation->_enums.append(reference->enums());
instantiation->_usings.append(reference->usings());
@@ -736,6 +732,28 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
// now must worry about dependent names in base classes.
if (Template *templ = referenceClass->enclosingTemplate()) {
const unsigned argumentCount = templId->templateArgumentCount();
+
+ if (_factory->expandTemplates()) {
+ Subst subst(_control.data());
+ for (unsigned i = 0, ei = std::min(argumentCount, templ->templateParameterCount()); i < ei; ++i) {
+ const TypenameArgument *tParam = templ->templateParameterAt(i)->asTypenameArgument();
+ if (!tParam)
+ continue;
+ const Name *name = tParam->name();
+ if (!name)
+ continue;
+ const FullySpecifiedType &ty = templId->templateArgumentAt(i);
+ subst.bind(name, ty);
+ }
+
+ Clone cloner(_control.data());
+ foreach (Symbol *s, reference->symbols()) {
+ instantiation->_symbols.append(cloner.symbol(s, &subst));
+ }
+ } else {
+ instantiation->_symbols.append(reference->symbols());
+ }
+
QHash<const Name*, unsigned> templParams;
for (unsigned i = 0; i < templ->templateParameterCount(); ++i)
templParams.insert(templ->templateParameterAt(i)->name(), i);
@@ -794,6 +812,8 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac
if (baseBinding && !knownUsings.contains(baseBinding))
instantiation->addUsing(baseBinding);
}
+ } else {
+ instantiation->_symbols.append(reference->symbols());
}
_alreadyConsideredTemplates.clear(templId);
@@ -907,7 +927,7 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNa
}
CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot, QSharedPointer<Control> control)
- : _snapshot(snapshot), _control(control)
+ : _snapshot(snapshot), _control(control), _expandTemplates(false)
{
_globalNamespace = allocClassOrNamespace(/*parent = */ 0);
_currentClassOrNamespace = _globalNamespace;