summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libs/cplusplus/GenTemplateInstance.cpp32
-rw-r--r--src/libs/cplusplus/GenTemplateInstance.h8
-rw-r--r--src/libs/cplusplus/LookupContext.cpp69
-rw-r--r--src/libs/cplusplus/LookupContext.h20
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp44
5 files changed, 110 insertions, 63 deletions
diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp
index bb6afc6655..a9191461e1 100644
--- a/src/libs/cplusplus/GenTemplateInstance.cpp
+++ b/src/libs/cplusplus/GenTemplateInstance.cpp
@@ -369,11 +369,37 @@ GenTemplateInstance::GenTemplateInstance(Control *control, const Substitution &s
_substitution(substitution)
{ }
-FullySpecifiedType GenTemplateInstance::operator()(Symbol *symbol)
+FullySpecifiedType GenTemplateInstance::gen(Symbol *symbol)
{
ApplySubstitution o(_control, symbol, _substitution);
return o.apply(symbol->type());
}
-Control *GenTemplateInstance::control() const
-{ return _control; }
+FullySpecifiedType GenTemplateInstance::instantiate(const Name *className, Symbol *candidate, Control *control)
+{
+ if (className) {
+ if (const TemplateNameId *templId = className->asTemplateNameId()) {
+ if (Class *klass = candidate->enclosingSymbol()->asClass()) {
+ GenTemplateInstance::Substitution subst;
+
+ for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
+ FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
+
+ if (i < klass->templateParameterCount()) {
+ const Name *templArgName = klass->templateParameterAt(i)->name();
+
+ if (templArgName && templArgName->identifier()) {
+ const Identifier *templArgId = templArgName->identifier();
+ subst.append(qMakePair(templArgId, templArgTy));
+ }
+ }
+ }
+
+ GenTemplateInstance inst(control, subst);
+ return inst.gen(candidate);
+ }
+ }
+ }
+
+ return candidate->type();
+}
diff --git a/src/libs/cplusplus/GenTemplateInstance.h b/src/libs/cplusplus/GenTemplateInstance.h
index b667cc2ab4..8d186341dc 100644
--- a/src/libs/cplusplus/GenTemplateInstance.h
+++ b/src/libs/cplusplus/GenTemplateInstance.h
@@ -47,11 +47,11 @@ public:
typedef QList< QPair<const Identifier *, FullySpecifiedType> > Substitution;
public:
- GenTemplateInstance(Control *control, const Substitution &substitution);
-
- FullySpecifiedType operator()(Symbol *symbol);
+ static FullySpecifiedType instantiate(const Name *className, Symbol *candidate, Control *control);
- Control *control() const;
+private:
+ GenTemplateInstance(Control *control, const Substitution &substitution);
+ FullySpecifiedType gen(Symbol *symbol);
private:
Symbol *_symbol;
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 74612de3ba..33cab4103b 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -31,6 +31,7 @@
#include "ResolveExpression.h"
#include "Overview.h"
#include "CppBindings.h"
+#include "GenTemplateInstance.h"
#include <CoreTypes.h>
#include <Symbols.h>
@@ -40,6 +41,7 @@
#include <Control.h>
#include <QtDebug>
+#include <cxxabi.h>
//#define CPLUSPLUS_NO_LAZY_LOOKUP
@@ -197,7 +199,7 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
for (; scope; scope = scope->enclosingScope()) {
if (id && scope->isBlockScope()) {
- ClassOrNamespace::lookup_helper(name, scope, &candidates);
+ bindings()->lookup_helper(name, scope, &candidates, /*templateId = */ 0);
if (! candidates.isEmpty())
break; // it's a local.
@@ -221,7 +223,7 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
} else if (scope->isFunctionScope()) {
Function *fun = scope->owner()->asFunction();
- ClassOrNamespace::lookup_helper(name, fun->arguments(), &candidates);
+ bindings()->lookup_helper(name, fun->arguments(), &candidates, /*templateId = */ 0);
if (! candidates.isEmpty())
break; // it's a formal argument.
@@ -244,7 +246,7 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
} else if (scope->isObjCMethodScope()) {
ObjCMethod *method = scope->owner()->asObjCMethod();
- ClassOrNamespace::lookup_helper(name, method->arguments(), &candidates);
+ bindings()->lookup_helper(name, method->arguments(), &candidates, /*templateId = */ 0);
if (! candidates.isEmpty())
break; // it's a formal argument.
@@ -261,7 +263,7 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
}
ClassOrNamespace::ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent)
- : _factory(factory), _parent(parent)
+ : _factory(factory), _parent(parent), _templateId(0)
{
}
@@ -323,7 +325,7 @@ QList<Symbol *> ClassOrNamespace::lookup(const Name *name)
QSet<ClassOrNamespace *> processed;
ClassOrNamespace *binding = this;
do {
- lookup_helper(name, binding, &result, &processed);
+ lookup_helper(name, binding, &result, &processed, /*templateId = */ 0);
binding = binding->_parent;
} while (binding);
@@ -332,7 +334,8 @@ QList<Symbol *> ClassOrNamespace::lookup(const Name *name)
void ClassOrNamespace::lookup_helper(const Name *name, ClassOrNamespace *binding,
QList<Symbol *> *result,
- QSet<ClassOrNamespace *> *processed)
+ QSet<ClassOrNamespace *> *processed,
+ const TemplateNameId *templateId)
{
if (! binding)
return;
@@ -340,21 +343,30 @@ void ClassOrNamespace::lookup_helper(const Name *name, ClassOrNamespace *binding
else if (! processed->contains(binding)) {
processed->insert(binding);
+ //Overview oo;
+ //qDebug() << "search for:" << oo(name) << "template:" << oo(templateId) << "b:" << oo(binding->_templateId);
+
foreach (Symbol *s, binding->symbols()) {
if (ScopedSymbol *scoped = s->asScopedSymbol())
- lookup_helper(name, scoped->members(), result);
+ _factory->lookup_helper(name, scoped->members(), result, templateId);
}
foreach (Enum *e, binding->enums())
- lookup_helper(name, e->members(), result);
+ _factory->lookup_helper(name, e->members(), result, templateId);
foreach (ClassOrNamespace *u, binding->usings())
- lookup_helper(name, u, result, processed);
+ lookup_helper(name, u, result, processed, binding->_templateId);
+
+ //qDebug() << "=======" << oo(name) << "template:" << oo(binding->_templateId);
}
}
-void ClassOrNamespace::lookup_helper(const Name *name, Scope *scope, QList<Symbol *> *result)
+void CreateBindings::lookup_helper(const Name *name, Scope *scope,
+ QList<Symbol *> *result,
+ const TemplateNameId *templateId)
{
+ Q_UNUSED(templateId);
+
if (! name) {
return;
@@ -364,6 +376,7 @@ void ClassOrNamespace::lookup_helper(const Name *name, Scope *scope, QList<Symbo
continue;
else if (! s->name()->isEqualTo(op))
continue;
+
result->append(s);
}
@@ -382,6 +395,7 @@ void ClassOrNamespace::lookup_helper(const Name *name, Scope *scope, QList<Symbo
#endif
continue;
}
+
result->append(s);
}
@@ -507,7 +521,28 @@ ClassOrNamespace *ClassOrNamespace::nestedClassOrNamespace(const Name *name) con
if (it == _classOrNamespaces.end())
return 0;
- return it->second;
+ ClassOrNamespace *c = it->second;
+
+ if (const TemplateNameId *templId = name->asTemplateNameId()) {
+ Overview oo;
+ qDebug() << "search for:" << oo(templId);
+
+ foreach (ClassOrNamespace *i, c->_instantiations) {
+ if (templId->isEqualTo(i->_templateId)) {
+ qDebug() << "*** got a match";
+ return i;
+ }
+ }
+
+ ClassOrNamespace *i = _factory->allocClassOrNamespace(c);
+ i->_templateId = templId;
+ i->_usings.append(c);
+ c->_instantiations.append(i);
+ qDebug() << "created a new instantiation" << i;
+ return i;
+ }
+
+ return c;
}
void ClassOrNamespace::flush()
@@ -566,6 +601,11 @@ ClassOrNamespace *ClassOrNamespace::findOrCreate(const Name *name)
if (! e) {
e = _factory->allocClassOrNamespace(this);
+
+ if (const TemplateNameId *templId = name->asTemplateNameId()) {
+ Overview oo;
+ qDebug() << "find or create:" << oo(templId);
+ }
_classOrNamespaces[name] = e;
}
@@ -578,6 +618,7 @@ ClassOrNamespace *ClassOrNamespace::findOrCreate(const Name *name)
CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot)
: _snapshot(snapshot)
{
+ _control = new Control();
_globalNamespace = allocClassOrNamespace(/*parent = */ 0);
_currentClassOrNamespace = _globalNamespace;
@@ -587,6 +628,7 @@ CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snaps
CreateBindings::~CreateBindings()
{
qDeleteAll(_entities);
+ delete _control;
}
ClassOrNamespace *CreateBindings::switchCurrentEntity(ClassOrNamespace *classOrNamespace)
@@ -639,6 +681,11 @@ void CreateBindings::process(Symbol *symbol)
#endif
}
+Control *CreateBindings::control() const
+{
+ return _control;
+}
+
ClassOrNamespace *CreateBindings::allocClassOrNamespace(ClassOrNamespace *parent)
{
ClassOrNamespace *e = new ClassOrNamespace(this, parent);
diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h
index 3d073aa6bb..20188c6d21 100644
--- a/src/libs/cplusplus/LookupContext.h
+++ b/src/libs/cplusplus/LookupContext.h
@@ -60,9 +60,6 @@ public:
ClassOrNamespace *findClassOrNamespace(const Name *name);
ClassOrNamespace *findClassOrNamespace(const QList<const Name *> &path);
- /// \internal
- static void lookup_helper(const Name *name, Scope *scope, QList<Symbol *> *result);
-
private:
/// \internal
void flush();
@@ -78,7 +75,8 @@ private:
void lookup_helper(const Name *name, ClassOrNamespace *binding,
QList<Symbol *> *result,
- QSet<ClassOrNamespace *> *processed);
+ QSet<ClassOrNamespace *> *processed,
+ const TemplateNameId *templateId);
ClassOrNamespace *lookupClassOrNamespace_helper(const Name *name, QSet<ClassOrNamespace *> *processed);
ClassOrNamespace *findClassOrNamespace_helper(const Name *name, QSet<ClassOrNamespace *> *processed);
@@ -99,6 +97,12 @@ private:
QList<Enum *> _enums;
QList<Symbol *> _todo;
+ // it's an instantiation.
+ const TemplateNameId *_templateId;
+
+ // templates
+ QList<ClassOrNamespace *> _instantiations;
+
friend class CreateBindings;
};
@@ -121,6 +125,13 @@ public:
/// \internal
ClassOrNamespace *allocClassOrNamespace(ClassOrNamespace *parent);
+ /// \internal
+ Control *control() const;
+
+ /// \internal
+ void lookup_helper(const Name *name, Scope *scope, QList<Symbol *> *result,
+ const TemplateNameId *templateId);
+
protected:
using SymbolVisitor::visit;
@@ -150,6 +161,7 @@ protected:
virtual bool visit(ObjCMethod *);
private:
+ Control *_control;
Snapshot _snapshot;
QSet<Namespace *> _processed;
QList<ClassOrNamespace *> _entities;
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 3f1a72eced..89c4b5ae27 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -679,29 +679,7 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults,
FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol *candidate) const
{
- if (const TemplateNameId *templId = className->asTemplateNameId()) {
- if (Class *klass = candidate->enclosingSymbol()->asClass()) {
- GenTemplateInstance::Substitution subst;
-
- for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
- FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
-
- if (i < klass->templateParameterCount()) {
- const Name *templArgName = klass->templateParameterAt(i)->name();
-
- if (templArgName && templArgName->identifier()) {
- const Identifier *templArgId = templArgName->identifier();
- subst.append(qMakePair(templArgId, templArgTy));
- }
- }
- }
-
- GenTemplateInstance inst(_context.control(), subst);
- return inst(candidate);
- }
- }
-
- return candidate->type();
+ return GenTemplateInstance::instantiate(className, candidate, _context.control());
}
QList<LookupItem>
@@ -728,24 +706,8 @@ ResolveExpression::resolveMember(const Name *memberName, Class *klass,
if (const QualifiedNameId *q = className->asQualifiedNameId())
unqualifiedNameId = q->unqualifiedNameId();
- if (const TemplateNameId *templId = unqualifiedNameId->asTemplateNameId()) {
- GenTemplateInstance::Substitution subst;
-
- for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
- FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
-
- if (i < klass->templateParameterCount()) {
- const Name *templArgName = klass->templateParameterAt(i)->name();
- if (templArgName && templArgName->identifier()) {
- const Identifier *templArgId = templArgName->identifier();
- subst.append(qMakePair(templArgId, templArgTy));
- }
- }
- }
-
- GenTemplateInstance inst(_context.control(), subst);
- ty = inst(candidate);
- }
+ if (const TemplateNameId *templId = unqualifiedNameId->asTemplateNameId())
+ ty = GenTemplateInstance::instantiate(templId, candidate, _context.control());
results.append(LookupItem(ty, candidate));
}