Commit f74ba9da authored by Roberto Raggi's avatar Roberto Raggi

Introduced CPlusPlus::Template and process the template declarations.

parent 6618a3cd
......@@ -234,9 +234,7 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken, Scope *
if (! scope)
scope = _currentScope;
const QList<LookupItem> results = typeofExpression(expression, scope,
TypeOfExpression::Preprocess);
const QList<LookupItem> results = typeofExpression(expression, scope, TypeOfExpression::Preprocess);
reportResult(endToken, results);
}
......@@ -245,7 +243,9 @@ Scope *FindUsages::switchScope(Scope *scope)
if (! scope)
return _currentScope;
return switchScope(scope);
Scope *previousScope = _currentScope;
_currentScope = scope;
return previousScope;
}
void FindUsages::statement(StatementAST *ast)
......
......@@ -3084,6 +3084,9 @@ public:
unsigned greater_token;
DeclarationAST *declaration;
public: // annotations
Template *symbol;
public:
TemplateDeclarationAST()
: export_token(0)
......@@ -3092,6 +3095,7 @@ public:
, template_parameter_list(0)
, greater_token(0)
, declaration(0)
, symbol(0)
{}
virtual TemplateDeclarationAST *asTemplateDeclaration() { return this; }
......
......@@ -119,6 +119,7 @@ class TypenameArgument;
class Function;
class Namespace;
class NamespaceAlias;
class Template;
class BaseClass;
class Block;
class Class;
......
......@@ -447,19 +447,23 @@ bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
bool CheckDeclaration::visit(TemplateDeclarationAST *ast)
{
#warning robe process template arguments
#if 0
Scope *scope = new Scope(_scope->owner());
Template *templ = control()->newTemplate(ast->firstToken());
ast->symbol = templ;
for (DeclarationListAST *param = ast->template_parameter_list; param; param = param->next) {
semantic()->check(param->value, scope);
semantic()->check(param->value, templ);
}
semantic()->check(ast->declaration, _scope,
new TemplateParameters(_templateParameters, scope));
#else
semantic()->check(ast->declaration, _scope);
#endif
semantic()->check(ast->declaration, templ);
if (Symbol *decl = templ->declaration()) {
// propagate the name
if (decl->sourceLocation())
templ->setSourceLocation(decl->sourceLocation(), translationUnit());
templ->setName(decl->name());
}
_scope->addMember(templ);
return false;
}
......
......@@ -333,40 +333,35 @@ public:
Declaration *newDeclaration(unsigned sourceLocation, const Name *name)
{
Declaration *declaration = new Declaration(translationUnit,
sourceLocation, name);
Declaration *declaration = new Declaration(translationUnit, sourceLocation, name);
symbols.push_back(declaration);
return declaration;
}
Argument *newArgument(unsigned sourceLocation, const Name *name)
{
Argument *argument = new Argument(translationUnit,
sourceLocation, name);
Argument *argument = new Argument(translationUnit, sourceLocation, name);
symbols.push_back(argument);
return argument;
}
TypenameArgument *newTypenameArgument(unsigned sourceLocation, const Name *name)
{
TypenameArgument *argument = new TypenameArgument(translationUnit,
sourceLocation, name);
TypenameArgument *argument = new TypenameArgument(translationUnit, sourceLocation, name);
symbols.push_back(argument);
return argument;
}
Function *newFunction(unsigned sourceLocation, const Name *name)
{
Function *function = new Function(translationUnit,
sourceLocation, name);
Function *function = new Function(translationUnit, sourceLocation, name);
symbols.push_back(function);
return function;
}
BaseClass *newBaseClass(unsigned sourceLocation, const Name *name)
{
BaseClass *baseClass = new BaseClass(translationUnit,
sourceLocation, name);
BaseClass *baseClass = new BaseClass(translationUnit, sourceLocation, name);
symbols.push_back(baseClass);
return baseClass;
}
......@@ -380,40 +375,42 @@ public:
Class *newClass(unsigned sourceLocation, const Name *name)
{
Class *klass = new Class(translationUnit,
sourceLocation, name);
Class *klass = new Class(translationUnit, sourceLocation, name);
symbols.push_back(klass);
return klass;
}
Namespace *newNamespace(unsigned sourceLocation, const Name *name)
{
Namespace *ns = new Namespace(translationUnit,
sourceLocation, name);
Namespace *ns = new Namespace(translationUnit, sourceLocation, name);
symbols.push_back(ns);
return ns;
}
Template *newTemplate(unsigned sourceLocation, const Name *name)
{
Template *ns = new Template(translationUnit, sourceLocation, name);
symbols.push_back(ns);
return ns;
}
NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name)
{
NamespaceAlias *ns = new NamespaceAlias(translationUnit,
sourceLocation, name);
NamespaceAlias *ns = new NamespaceAlias(translationUnit, sourceLocation, name);
symbols.push_back(ns);
return ns;
}
UsingNamespaceDirective *newUsingNamespaceDirective(unsigned sourceLocation, const Name *name)
{
UsingNamespaceDirective *u = new UsingNamespaceDirective(translationUnit,
sourceLocation, name);
UsingNamespaceDirective *u = new UsingNamespaceDirective(translationUnit, sourceLocation, name);
symbols.push_back(u);
return u;
}
ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, const Name *name)
{
ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit,
sourceLocation, name);
ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit, sourceLocation, name);
symbols.push_back(c);
return c;
}
......@@ -476,16 +473,14 @@ public:
Enum *newEnum(unsigned sourceLocation, const Name *name)
{
Enum *e = new Enum(translationUnit,
sourceLocation, name);
Enum *e = new Enum(translationUnit, sourceLocation, name);
symbols.push_back(e);
return e;
}
UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, const Name *name)
{
UsingDeclaration *u = new UsingDeclaration(translationUnit,
sourceLocation, name);
UsingDeclaration *u = new UsingDeclaration(translationUnit, sourceLocation, name);
symbols.push_back(u);
return u;
}
......@@ -689,6 +684,9 @@ Function *Control::newFunction(unsigned sourceLocation, const Name *name)
Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name)
{ return d->newNamespace(sourceLocation, name); }
Template *Control::newTemplate(unsigned sourceLocation, const Name *name)
{ return d->newTemplate(sourceLocation, name); }
NamespaceAlias *Control::newNamespaceAlias(unsigned sourceLocation, const Name *name)
{ return d->newNamespaceAlias(sourceLocation, name); }
......
......@@ -129,6 +129,9 @@ public:
/// Creates a new Namespace symbol.
Namespace *newNamespace(unsigned sourceLocation, const Name *name = 0);
/// Creates a new Template symbol.
Template *newTemplate(unsigned sourceLocation, const Name *name = 0);
/// Creates a new Namespace symbol.
NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0);
......
......@@ -143,7 +143,7 @@ void SymbolTable::enterSymbol(Symbol *symbol)
_symbols = reinterpret_cast<Symbol **>(realloc(_symbols, sizeof(Symbol *) * _allocatedSymbols));
}
assert(! symbol->_scope || symbol->scope() == this);
assert(! symbol->_scope || symbol->scope() == _owner);
symbol->_index = _symbolCount;
symbol->_scope = _owner;
_symbols[_symbolCount] = symbol;
......
......@@ -347,6 +347,9 @@ bool Symbol::isFunction() const
bool Symbol::isNamespace() const
{ return asNamespace() != 0; }
bool Symbol::isTemplate() const
{ return asNamespace() != 0; }
bool Symbol::isClass() const
{ return asClass() != 0; }
......
......@@ -168,6 +168,9 @@ public:
/// Returns true if this Symbol is a Namespace.
bool isNamespace() const;
/// Returns true if this Symbol is a Namespace.
bool isTemplate() const;
/// Returns true if this Symbol is a Class.
bool isClass() const;
......@@ -220,6 +223,7 @@ public:
virtual const Enum *asEnum() const { return 0; }
virtual const Function *asFunction() const { return 0; }
virtual const Namespace *asNamespace() const { return 0; }
virtual const Template *asTemplate() const { return 0; }
virtual const NamespaceAlias *asNamespaceAlias() const { return 0; }
virtual const Class *asClass() const { return 0; }
virtual const Block *asBlock() const { return 0; }
......@@ -243,6 +247,7 @@ public:
virtual Enum *asEnum() { return 0; }
virtual Function *asFunction() { return 0; }
virtual Namespace *asNamespace() { return 0; }
virtual Template *asTemplate() { return 0; }
virtual NamespaceAlias *asNamespaceAlias() { return 0; }
virtual Class *asClass() { return 0; }
virtual Block *asBlock() { return 0; }
......
......@@ -78,6 +78,7 @@ public:
virtual bool visit(Enum *) { return true; }
virtual bool visit(Function *) { return true; }
virtual bool visit(Namespace *) { return true; }
virtual bool visit(Template *) { return true; }
virtual bool visit(Class *) { return true; }
virtual bool visit(Block *) { return true; }
virtual bool visit(ForwardClassDeclaration *) { return true; }
......
......@@ -430,6 +430,63 @@ void Enum::visitSymbol0(SymbolVisitor *visitor)
}
}
Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name)
{ }
Template::~Template()
{ }
unsigned Template::templateParameterCount() const
{
if (declaration() != 0)
return memberCount() - 1;
return 0;
}
Symbol *Template::templateParameterAt(unsigned index) const
{ return memberAt(index); }
Symbol *Template::declaration() const
{
if (isEmpty())
return 0;
if (Symbol *s = memberAt(memberCount() - 1)) {
if (s->isClass() || s->isForwardClassDeclaration() ||
s->isTemplate() || s->isFunction() || s->isDeclaration())
return s;
}
return 0;
}
FullySpecifiedType Template::type() const
{ return FullySpecifiedType(const_cast<Template *>(this)); }
bool Template::isEqualTo(const Type *other) const
{ return other == this; }
void Template::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
for (unsigned i = 0; i < memberCount(); ++i) {
visitSymbol(memberAt(i), visitor);
}
}
}
void Template::accept0(TypeVisitor *visitor)
{ visitor->visit(this); }
bool Template::matchType0(const Type *otherType, TypeMatcher *matcher) const
{
if (const Template *otherTy = otherType->asTemplateType())
return matcher->match(this, otherTy);
return false;
}
Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name)
{ }
......
......@@ -376,6 +376,41 @@ private:
};
};
class CPLUSPLUS_EXPORT Template: public Scope, public Type
{
public:
Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
virtual ~Template();
unsigned templateParameterCount() const;
Symbol *templateParameterAt(unsigned index) const;
Symbol *declaration() const;
// Symbol's interface
virtual FullySpecifiedType type() const;
// Type's interface
virtual bool isEqualTo(const Type *other) const;
virtual const Template *asTemplate() const
{ return this; }
virtual Template *asTemplate()
{ return this; }
virtual const Template *asTemplateType() const
{ return this; }
virtual Template *asTemplateType()
{ return this; }
protected:
virtual void visitSymbol0(SymbolVisitor *visitor);
virtual void accept0(TypeVisitor *visitor);
virtual bool matchType0(const Type *otherType, TypeMatcher *matcher) const;
};
class CPLUSPLUS_EXPORT Namespace: public Scope, public Type
{
public:
......
......@@ -92,6 +92,9 @@ bool Type::isFunctionType() const
bool Type::isNamespaceType() const
{ return asNamespaceType() != 0; }
bool Type::isTemplateType() const
{ return asTemplateType() != 0; }
bool Type::isClassType() const
{ return asClassType() != 0; }
......
......@@ -70,6 +70,7 @@ public:
bool isNamedType() const;
bool isFunctionType() const;
bool isNamespaceType() const;
bool isTemplateType() const;
bool isClassType() const;
bool isEnumType() const;
bool isForwardClassDeclarationType() const;
......@@ -90,6 +91,7 @@ public:
virtual const NamedType *asNamedType() const { return 0; }
virtual const Function *asFunctionType() const { return 0; }
virtual const Namespace *asNamespaceType() const { return 0; }
virtual const Template *asTemplateType() const { return 0; }
virtual const Class *asClassType() const { return 0; }
virtual const Enum *asEnumType() const { return 0; }
virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; }
......@@ -110,6 +112,7 @@ public:
virtual NamedType *asNamedType() { return 0; }
virtual Function *asFunctionType() { return 0; }
virtual Namespace *asNamespaceType() { return 0; }
virtual Template *asTemplateType() { return 0; }
virtual Class *asClassType() { return 0; }
virtual Enum *asEnumType() { return 0; }
virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; }
......
......@@ -174,6 +174,14 @@ bool TypeMatcher::match(const Namespace *type, const Namespace *otherType)
return true;
}
bool TypeMatcher::match(const Template *type, const Template *otherType)
{
if (type != otherType)
return false;
return true;
}
bool TypeMatcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType)
{
if (type != otherType)
......
......@@ -56,6 +56,7 @@ public:
virtual bool match(const Function *type, const Function *otherType);
virtual bool match(const Enum *type, const Enum *otherType);
virtual bool match(const Namespace *type, const Namespace *otherType);
virtual bool match(const Template *type, const Template *otherType);
virtual bool match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType);
virtual bool match(const Class *type, const Class *otherType);
virtual bool match(const ObjCClass *type, const ObjCClass *otherType);
......
......@@ -78,6 +78,7 @@ public:
virtual void visit(NamedType *) {}
virtual void visit(Function *) {}
virtual void visit(Namespace *) {}
virtual void visit(Template *) {}
virtual void visit(Class *) {}
virtual void visit(Enum *) {}
virtual void visit(ForwardClassDeclaration *) {}
......
......@@ -130,7 +130,7 @@ void parse(const char *fileName, const char *source, unsigned size)
Semantic sem(&unit);
Namespace *globalNamespace = control.newNamespace(0);
for (List<DeclarationAST *> *it = ast->declaration_list; it; it = it->next) {
sem.check(it->value, globalNamespace->members());
sem.check(it->value, globalNamespace);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment