From fb8d699aac2cfe4b84a6f86abbd24e68333d1b12 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Mon, 26 Oct 2009 12:41:13 +0100
Subject: [PATCH] Introduced CPlusPlus::GenTemplateInstance.

---
 src/libs/cplusplus/GenTemplateInstance.cpp | 145 ++++++++++++++++++++
 src/libs/cplusplus/GenTemplateInstance.h   |  58 ++++++++
 src/libs/cplusplus/ResolveExpression.cpp   | 150 +--------------------
 src/libs/cplusplus/cplusplus-lib.pri       |   2 +
 4 files changed, 208 insertions(+), 147 deletions(-)
 create mode 100644 src/libs/cplusplus/GenTemplateInstance.cpp
 create mode 100644 src/libs/cplusplus/GenTemplateInstance.h

diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp
new file mode 100644
index 00000000000..07555932505
--- /dev/null
+++ b/src/libs/cplusplus/GenTemplateInstance.cpp
@@ -0,0 +1,145 @@
+
+#include "GenTemplateInstance.h"
+#include <Control.h>
+#include <Scope.h>
+#include <Names.h>
+#include <Symbols.h>
+#include <CoreTypes.h>
+#include <QtCore/QVarLengthArray>
+
+using namespace CPlusPlus;
+
+GenTemplateInstance::GenTemplateInstance(Control *control, const Substitution &substitution)
+    : _control(control),
+      _substitution(substitution)
+{ }
+
+FullySpecifiedType GenTemplateInstance::operator()(const FullySpecifiedType &ty)
+{ return subst(ty); }
+
+FullySpecifiedType GenTemplateInstance::subst(Name *name)
+{
+    if (TemplateNameId *t = name->asTemplateNameId()) {
+        QVarLengthArray<FullySpecifiedType, 8> args(t->templateArgumentCount());
+
+        for (unsigned i = 0; i < t->templateArgumentCount(); ++i)
+            args[i] = subst(t->templateArgumentAt(i));
+
+        TemplateNameId *n = _control->templateNameId(t->identifier(),
+                                                     args.data(), args.size());
+
+        return FullySpecifiedType(_control->namedType(n));
+    } else if (name->isQualifiedNameId()) {
+        // ### implement me
+    }
+
+    for (int i = 0; i < _substitution.size(); ++i) {
+        const QPair<Name *, FullySpecifiedType> s = _substitution.at(i);
+        if (name->isEqualTo(s.first))
+            return s.second;
+    }
+
+    return FullySpecifiedType(_control->namedType(name));
+}
+
+FullySpecifiedType GenTemplateInstance::subst(const FullySpecifiedType &ty)
+{
+    FullySpecifiedType previousType = switchType(ty);
+    TypeVisitor::accept(ty.type());
+    return switchType(previousType);
+}
+
+FullySpecifiedType GenTemplateInstance::switchType(const FullySpecifiedType &type)
+{
+    FullySpecifiedType previousType = _type;
+    _type = type;
+    return previousType;
+}
+
+// types
+void GenTemplateInstance::visit(PointerToMemberType * /*ty*/)
+{
+    Q_ASSERT(false);
+}
+
+void GenTemplateInstance::visit(PointerType *ty)
+{
+    FullySpecifiedType elementType = subst(ty->elementType());
+    _type.setType(_control->pointerType(elementType));
+}
+
+void GenTemplateInstance::visit(ReferenceType *ty)
+{
+    FullySpecifiedType elementType = subst(ty->elementType());
+    _type.setType(_control->referenceType(elementType));
+}
+
+void GenTemplateInstance::visit(ArrayType *ty)
+{
+    FullySpecifiedType elementType = subst(ty->elementType());
+    _type.setType(_control->arrayType(elementType, ty->size()));
+}
+
+void GenTemplateInstance::visit(NamedType *ty)
+{
+    Name *name = ty->name();
+    _type.setType(subst(name).type());
+}
+
+void GenTemplateInstance::visit(Function *ty)
+{
+    Name *name = ty->name();
+    FullySpecifiedType returnType = subst(ty->returnType());
+
+    Function *fun = _control->newFunction(0, name);
+    fun->setScope(ty->scope());
+    fun->setConst(ty->isConst());
+    fun->setVolatile(ty->isVolatile());
+    fun->setReturnType(returnType);
+    for (unsigned i = 0; i < ty->argumentCount(); ++i) {
+        Symbol *arg = ty->argumentAt(i);
+        FullySpecifiedType argTy = subst(arg->type());
+        Argument *newArg = _control->newArgument(0, arg->name());
+        newArg->setType(argTy);
+        fun->arguments()->enterSymbol(newArg);
+    }
+    _type.setType(fun);
+}
+
+void GenTemplateInstance::visit(VoidType *)
+{ /* nothing to do*/ }
+
+void GenTemplateInstance::visit(IntegerType *)
+{ /* nothing to do*/ }
+
+void GenTemplateInstance::visit(FloatType *)
+{ /* nothing to do*/ }
+
+void GenTemplateInstance::visit(Namespace *)
+{ Q_ASSERT(false); }
+
+void GenTemplateInstance::visit(Class *)
+{ Q_ASSERT(false); }
+
+void GenTemplateInstance::visit(Enum *)
+{ Q_ASSERT(false); }
+
+// names
+void GenTemplateInstance::visit(NameId *)
+{ Q_ASSERT(false); }
+
+void GenTemplateInstance::visit(TemplateNameId *)
+{ Q_ASSERT(false); }
+
+void GenTemplateInstance::visit(DestructorNameId *)
+{ Q_ASSERT(false); }
+
+void GenTemplateInstance::visit(OperatorNameId *)
+{ Q_ASSERT(false); }
+
+void GenTemplateInstance::visit(ConversionNameId *)
+{ Q_ASSERT(false); }
+
+void GenTemplateInstance::visit(QualifiedNameId *)
+{ Q_ASSERT(false); }
+
diff --git a/src/libs/cplusplus/GenTemplateInstance.h b/src/libs/cplusplus/GenTemplateInstance.h
new file mode 100644
index 00000000000..a4845f8bc3d
--- /dev/null
+++ b/src/libs/cplusplus/GenTemplateInstance.h
@@ -0,0 +1,58 @@
+#ifndef GENTEMPLATEINSTANCE_H
+#define GENTEMPLATEINSTANCE_H
+
+#include <TypeVisitor.h>
+#include <NameVisitor.h>
+#include <FullySpecifiedType.h>
+
+#include <QtCore/QList>
+#include <QtCore/QPair>
+
+namespace CPlusPlus {
+
+class CPLUSPLUS_EXPORT GenTemplateInstance: protected TypeVisitor, protected NameVisitor
+{
+public:
+    typedef QList< QPair<Name *, FullySpecifiedType> > Substitution;
+
+public:
+    GenTemplateInstance(Control *control, const Substitution &substitution);
+
+    FullySpecifiedType operator()(const FullySpecifiedType &ty);
+
+protected:
+    FullySpecifiedType subst(Name *name);
+    FullySpecifiedType subst(const FullySpecifiedType &ty);
+
+    FullySpecifiedType switchType(const FullySpecifiedType &type);
+
+    virtual void visit(PointerToMemberType * /*ty*/);
+    virtual void visit(PointerType *ty);
+    virtual void visit(ReferenceType *ty);
+    virtual void visit(ArrayType *ty);
+    virtual void visit(NamedType *ty);
+    virtual void visit(Function *ty);
+    virtual void visit(VoidType *);
+    virtual void visit(IntegerType *);
+    virtual void visit(FloatType *);
+    virtual void visit(Namespace *);
+    virtual void visit(Class *);
+    virtual void visit(Enum *);
+
+    // names
+    virtual void visit(NameId *);
+    virtual void visit(TemplateNameId *);
+    virtual void visit(DestructorNameId *);
+    virtual void visit(OperatorNameId *);
+    virtual void visit(ConversionNameId *);
+    virtual void visit(QualifiedNameId *);
+
+private:
+    Control *_control;
+    FullySpecifiedType _type;
+    const Substitution _substitution;
+};
+
+} // end of namespace CPlusPlus
+
+#endif // GENTEMPLATEINSTANCE_H
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index aff38db4b3f..f89c2c9afd5 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -30,6 +30,7 @@
 #include "ResolveExpression.h"
 #include "LookupContext.h"
 #include "Overview.h"
+#include "GenTemplateInstance.h"
 
 #include <Control.h>
 #include <AST.h>
@@ -49,151 +50,6 @@ using namespace CPlusPlus;
 
 namespace {
 
-typedef QList< QPair<Name *, FullySpecifiedType> > Substitution;
-
-class GenerateInstance: protected TypeVisitor, protected NameVisitor
-{
-    Control *_control;
-    FullySpecifiedType _type;
-    const Substitution _substitution;
-
-public:
-    GenerateInstance(Control *control, const Substitution &substitution)
-        : _control(control),
-          _substitution(substitution)
-    { }
-
-    FullySpecifiedType operator()(const FullySpecifiedType &ty)
-    { return subst(ty); }
-
-protected:
-    FullySpecifiedType subst(Name *name)
-    {
-        if (TemplateNameId *t = name->asTemplateNameId()) {
-            QVarLengthArray<FullySpecifiedType, 8> args(t->templateArgumentCount());
-
-            for (unsigned i = 0; i < t->templateArgumentCount(); ++i)
-                args[i] = subst(t->templateArgumentAt(i));
-
-            TemplateNameId *n = _control->templateNameId(t->identifier(),
-                                                         args.data(), args.size());
-
-            return FullySpecifiedType(_control->namedType(n));
-        } else if (name->isQualifiedNameId()) {
-            // ### implement me
-        }
-
-        for (int i = 0; i < _substitution.size(); ++i) {
-            const QPair<Name *, FullySpecifiedType> s = _substitution.at(i);
-            if (name->isEqualTo(s.first))
-                return s.second;
-        }
-
-        return FullySpecifiedType(_control->namedType(name));
-    }
-
-    FullySpecifiedType subst(const FullySpecifiedType &ty)
-    {
-        FullySpecifiedType previousType = switchType(ty);
-        TypeVisitor::accept(ty.type());
-        return switchType(previousType);
-    }
-
-    FullySpecifiedType switchType(const FullySpecifiedType &type)
-    {
-        FullySpecifiedType previousType = _type;
-        _type = type;
-        return previousType;
-    }
-
-    // types
-    virtual void visit(PointerToMemberType * /*ty*/)
-    {
-        Q_ASSERT(false);
-    }
-
-    virtual void visit(PointerType *ty)
-    {
-        FullySpecifiedType elementType = subst(ty->elementType());
-        _type.setType(_control->pointerType(elementType));
-    }
-
-    virtual void visit(ReferenceType *ty)
-    {
-        FullySpecifiedType elementType = subst(ty->elementType());
-        _type.setType(_control->referenceType(elementType));
-    }
-
-    virtual void visit(ArrayType *ty)
-    {
-        FullySpecifiedType elementType = subst(ty->elementType());
-        _type.setType(_control->arrayType(elementType, ty->size()));
-    }
-
-    virtual void visit(NamedType *ty)
-    {
-        Name *name = ty->name();
-        _type.setType(subst(name).type());
-    }
-
-    virtual void visit(Function *ty)
-    {
-        Name *name = ty->name();
-        FullySpecifiedType returnType = subst(ty->returnType());
-
-        Function *fun = _control->newFunction(0, name);
-        fun->setScope(ty->scope());
-        fun->setConst(ty->isConst());
-        fun->setVolatile(ty->isVolatile());
-        fun->setReturnType(returnType);
-        for (unsigned i = 0; i < ty->argumentCount(); ++i) {
-            Symbol *arg = ty->argumentAt(i);
-            FullySpecifiedType argTy = subst(arg->type());
-            Argument *newArg = _control->newArgument(0, arg->name());
-            newArg->setType(argTy);
-            fun->arguments()->enterSymbol(newArg);
-        }
-        _type.setType(fun);
-    }
-
-    virtual void visit(VoidType *)
-    { /* nothing to do*/ }
-
-    virtual void visit(IntegerType *)
-    { /* nothing to do*/ }
-
-    virtual void visit(FloatType *)
-    { /* nothing to do*/ }
-
-    virtual void visit(Namespace *)
-    { Q_ASSERT(false); }
-
-    virtual void visit(Class *)
-    { Q_ASSERT(false); }
-
-    virtual void visit(Enum *)
-    { Q_ASSERT(false); }
-
-    // names
-    virtual void visit(NameId *)
-    { Q_ASSERT(false); }
-
-    virtual void visit(TemplateNameId *)
-    { Q_ASSERT(false); }
-
-    virtual void visit(DestructorNameId *)
-    { Q_ASSERT(false); }
-
-    virtual void visit(OperatorNameId *)
-    { Q_ASSERT(false); }
-
-    virtual void visit(ConversionNameId *)
-    { Q_ASSERT(false); }
-
-    virtual void visit(QualifiedNameId *)
-    { Q_ASSERT(false); }
-};
-
 template <typename _Tp>
 static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
 {
@@ -849,7 +705,7 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass,
             unqualifiedNameId = q->unqualifiedNameId();
         
         if (TemplateNameId *templId = unqualifiedNameId->asTemplateNameId()) {
-            Substitution subst;
+            GenTemplateInstance::Substitution subst;
             
             for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
                 FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
@@ -859,7 +715,7 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass,
                                            templArgTy));
             }
             
-            GenerateInstance inst(control(), subst);
+            GenTemplateInstance inst(control(), subst);
             ty = inst(ty);
         }
         
diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri
index 34caa520a80..812dbe0c9a4 100644
--- a/src/libs/cplusplus/cplusplus-lib.pri
+++ b/src/libs/cplusplus/cplusplus-lib.pri
@@ -32,6 +32,7 @@ HEADERS += \
     $$PWD/LookupContext.h \
     $$PWD/CppBindings.h \
     $$PWD/ASTParent.h \
+    $$PWD/GenTemplateInstance.h \
     $$PWD/CheckUndefinedSymbols.h \
     $$PWD/PreprocessorClient.h \
     $$PWD/PreprocessorEnvironment.h \
@@ -54,6 +55,7 @@ SOURCES += \
     $$PWD/LookupContext.cpp \
     $$PWD/CppBindings.cpp \
     $$PWD/ASTParent.cpp \
+    $$PWD/GenTemplateInstance.cpp \
     $$PWD/CheckUndefinedSymbols.cpp \
     $$PWD/PreprocessorClient.cpp \
     $$PWD/PreprocessorEnvironment.cpp \
-- 
GitLab