From fb8d699aac2cfe4b84a6f86abbd24e68333d1b12 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 12:41:13 +0100 Subject: Introduced CPlusPlus::GenTemplateInstance. --- src/libs/cplusplus/GenTemplateInstance.cpp | 145 +++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/libs/cplusplus/GenTemplateInstance.cpp (limited to 'src/libs/cplusplus/GenTemplateInstance.cpp') diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp new file mode 100644 index 0000000000..0755593250 --- /dev/null +++ b/src/libs/cplusplus/GenTemplateInstance.cpp @@ -0,0 +1,145 @@ + +#include "GenTemplateInstance.h" +#include +#include +#include +#include +#include +#include + +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 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 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); } + -- cgit v1.2.1