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