forked from qt-creator/qt-creator
146 lines
3.9 KiB
C++
146 lines
3.9 KiB
C++
|
|
#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); }
|
|
|