Commit f74ba9da authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Introduced CPlusPlus::Template and process the template declarations.

parent 6618a3cd
...@@ -234,9 +234,7 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken, Scope * ...@@ -234,9 +234,7 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken, Scope *
if (! scope) if (! scope)
scope = _currentScope; scope = _currentScope;
const QList<LookupItem> results = typeofExpression(expression, scope, const QList<LookupItem> results = typeofExpression(expression, scope, TypeOfExpression::Preprocess);
TypeOfExpression::Preprocess);
reportResult(endToken, results); reportResult(endToken, results);
} }
...@@ -245,7 +243,9 @@ Scope *FindUsages::switchScope(Scope *scope) ...@@ -245,7 +243,9 @@ Scope *FindUsages::switchScope(Scope *scope)
if (! scope) if (! scope)
return _currentScope; return _currentScope;
return switchScope(scope); Scope *previousScope = _currentScope;
_currentScope = scope;
return previousScope;
} }
void FindUsages::statement(StatementAST *ast) void FindUsages::statement(StatementAST *ast)
......
...@@ -3084,6 +3084,9 @@ public: ...@@ -3084,6 +3084,9 @@ public:
unsigned greater_token; unsigned greater_token;
DeclarationAST *declaration; DeclarationAST *declaration;
public: // annotations
Template *symbol;
public: public:
TemplateDeclarationAST() TemplateDeclarationAST()
: export_token(0) : export_token(0)
...@@ -3092,6 +3095,7 @@ public: ...@@ -3092,6 +3095,7 @@ public:
, template_parameter_list(0) , template_parameter_list(0)
, greater_token(0) , greater_token(0)
, declaration(0) , declaration(0)
, symbol(0)
{} {}
virtual TemplateDeclarationAST *asTemplateDeclaration() { return this; } virtual TemplateDeclarationAST *asTemplateDeclaration() { return this; }
......
...@@ -119,6 +119,7 @@ class TypenameArgument; ...@@ -119,6 +119,7 @@ class TypenameArgument;
class Function; class Function;
class Namespace; class Namespace;
class NamespaceAlias; class NamespaceAlias;
class Template;
class BaseClass; class BaseClass;
class Block; class Block;
class Class; class Class;
......
...@@ -447,19 +447,23 @@ bool CheckDeclaration::visit(ParameterDeclarationAST *ast) ...@@ -447,19 +447,23 @@ bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
bool CheckDeclaration::visit(TemplateDeclarationAST *ast) bool CheckDeclaration::visit(TemplateDeclarationAST *ast)
{ {
#warning robe process template arguments Template *templ = control()->newTemplate(ast->firstToken());
#if 0 ast->symbol = templ;
Scope *scope = new Scope(_scope->owner());
for (DeclarationListAST *param = ast->template_parameter_list; param; param = param->next) { 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, semantic()->check(ast->declaration, templ);
new TemplateParameters(_templateParameters, scope));
#else if (Symbol *decl = templ->declaration()) {
semantic()->check(ast->declaration, _scope); // propagate the name
#endif if (decl->sourceLocation())
templ->setSourceLocation(decl->sourceLocation(), translationUnit());
templ->setName(decl->name());
}
_scope->addMember(templ);
return false; return false;
} }
......
...@@ -333,40 +333,35 @@ public: ...@@ -333,40 +333,35 @@ public:
Declaration *newDeclaration(unsigned sourceLocation, const Name *name) Declaration *newDeclaration(unsigned sourceLocation, const Name *name)
{ {
Declaration *declaration = new Declaration(translationUnit, Declaration *declaration = new Declaration(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(declaration); symbols.push_back(declaration);
return declaration; return declaration;
} }
Argument *newArgument(unsigned sourceLocation, const Name *name) Argument *newArgument(unsigned sourceLocation, const Name *name)
{ {
Argument *argument = new Argument(translationUnit, Argument *argument = new Argument(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(argument); symbols.push_back(argument);
return argument; return argument;
} }
TypenameArgument *newTypenameArgument(unsigned sourceLocation, const Name *name) TypenameArgument *newTypenameArgument(unsigned sourceLocation, const Name *name)
{ {
TypenameArgument *argument = new TypenameArgument(translationUnit, TypenameArgument *argument = new TypenameArgument(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(argument); symbols.push_back(argument);
return argument; return argument;
} }
Function *newFunction(unsigned sourceLocation, const Name *name) Function *newFunction(unsigned sourceLocation, const Name *name)
{ {
Function *function = new Function(translationUnit, Function *function = new Function(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(function); symbols.push_back(function);
return function; return function;
} }
BaseClass *newBaseClass(unsigned sourceLocation, const Name *name) BaseClass *newBaseClass(unsigned sourceLocation, const Name *name)
{ {
BaseClass *baseClass = new BaseClass(translationUnit, BaseClass *baseClass = new BaseClass(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(baseClass); symbols.push_back(baseClass);
return baseClass; return baseClass;
} }
...@@ -380,40 +375,42 @@ public: ...@@ -380,40 +375,42 @@ public:
Class *newClass(unsigned sourceLocation, const Name *name) Class *newClass(unsigned sourceLocation, const Name *name)
{ {
Class *klass = new Class(translationUnit, Class *klass = new Class(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(klass); symbols.push_back(klass);
return klass; return klass;
} }
Namespace *newNamespace(unsigned sourceLocation, const Name *name) Namespace *newNamespace(unsigned sourceLocation, const Name *name)
{ {
Namespace *ns = new Namespace(translationUnit, Namespace *ns = new Namespace(translationUnit, sourceLocation, name);
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); symbols.push_back(ns);
return ns; return ns;
} }
NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name) NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name)
{ {
NamespaceAlias *ns = new NamespaceAlias(translationUnit, NamespaceAlias *ns = new NamespaceAlias(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(ns); symbols.push_back(ns);
return ns; return ns;
} }
UsingNamespaceDirective *newUsingNamespaceDirective(unsigned sourceLocation, const Name *name) UsingNamespaceDirective *newUsingNamespaceDirective(unsigned sourceLocation, const Name *name)
{ {
UsingNamespaceDirective *u = new UsingNamespaceDirective(translationUnit, UsingNamespaceDirective *u = new UsingNamespaceDirective(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(u); symbols.push_back(u);
return u; return u;
} }
ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, const Name *name) ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, const Name *name)
{ {
ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit, ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(c); symbols.push_back(c);
return c; return c;
} }
...@@ -476,16 +473,14 @@ public: ...@@ -476,16 +473,14 @@ public:
Enum *newEnum(unsigned sourceLocation, const Name *name) Enum *newEnum(unsigned sourceLocation, const Name *name)
{ {
Enum *e = new Enum(translationUnit, Enum *e = new Enum(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(e); symbols.push_back(e);
return e; return e;
} }
UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, const Name *name) UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, const Name *name)
{ {
UsingDeclaration *u = new UsingDeclaration(translationUnit, UsingDeclaration *u = new UsingDeclaration(translationUnit, sourceLocation, name);
sourceLocation, name);
symbols.push_back(u); symbols.push_back(u);
return u; return u;
} }
...@@ -689,6 +684,9 @@ Function *Control::newFunction(unsigned sourceLocation, const Name *name) ...@@ -689,6 +684,9 @@ Function *Control::newFunction(unsigned sourceLocation, const Name *name)
Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name) Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name)
{ return d->newNamespace(sourceLocation, 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) NamespaceAlias *Control::newNamespaceAlias(unsigned sourceLocation, const Name *name)
{ return d->newNamespaceAlias(sourceLocation, name); } { return d->newNamespaceAlias(sourceLocation, name); }
......
...@@ -129,6 +129,9 @@ public: ...@@ -129,6 +129,9 @@ public:
/// Creates a new Namespace symbol. /// Creates a new Namespace symbol.
Namespace *newNamespace(unsigned sourceLocation, const Name *name = 0); 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. /// Creates a new Namespace symbol.
NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0); NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0);
......
...@@ -143,7 +143,7 @@ void SymbolTable::enterSymbol(Symbol *symbol) ...@@ -143,7 +143,7 @@ void SymbolTable::enterSymbol(Symbol *symbol)
_symbols = reinterpret_cast<Symbol **>(realloc(_symbols, sizeof(Symbol *) * _allocatedSymbols)); _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->_index = _symbolCount;
symbol->_scope = _owner; symbol->_scope = _owner;
_symbols[_symbolCount] = symbol; _symbols[_symbolCount] = symbol;
......
...@@ -347,6 +347,9 @@ bool Symbol::isFunction() const ...@@ -347,6 +347,9 @@ bool Symbol::isFunction() const
bool Symbol::isNamespace() const bool Symbol::isNamespace() const
{ return asNamespace() != 0; } { return asNamespace() != 0; }
bool Symbol::isTemplate() const
{ return asNamespace() != 0; }
bool Symbol::isClass() const bool Symbol::isClass() const
{ return asClass() != 0; } { return asClass() != 0; }
......
...@@ -168,6 +168,9 @@ public: ...@@ -168,6 +168,9 @@ public:
/// Returns true if this Symbol is a Namespace. /// Returns true if this Symbol is a Namespace.
bool isNamespace() const; bool isNamespace() const;
/// Returns true if this Symbol is a Namespace.
bool isTemplate() const;
/// Returns true if this Symbol is a Class. /// Returns true if this Symbol is a Class.
bool isClass() const; bool isClass() const;
...@@ -220,6 +223,7 @@ public: ...@@ -220,6 +223,7 @@ public:
virtual const Enum *asEnum() const { return 0; } virtual const Enum *asEnum() const { return 0; }
virtual const Function *asFunction() const { return 0; } virtual const Function *asFunction() const { return 0; }
virtual const Namespace *asNamespace() 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 NamespaceAlias *asNamespaceAlias() const { return 0; }
virtual const Class *asClass() const { return 0; } virtual const Class *asClass() const { return 0; }
virtual const Block *asBlock() const { return 0; } virtual const Block *asBlock() const { return 0; }
...@@ -243,6 +247,7 @@ public: ...@@ -243,6 +247,7 @@ public:
virtual Enum *asEnum() { return 0; } virtual Enum *asEnum() { return 0; }
virtual Function *asFunction() { return 0; } virtual Function *asFunction() { return 0; }
virtual Namespace *asNamespace() { return 0; } virtual Namespace *asNamespace() { return 0; }
virtual Template *asTemplate() { return 0; }
virtual NamespaceAlias *asNamespaceAlias() { return 0; } virtual NamespaceAlias *asNamespaceAlias() { return 0; }
virtual Class *asClass() { return 0; } virtual Class *asClass() { return 0; }
virtual Block *asBlock() { return 0; } virtual Block *asBlock() { return 0; }
......
...@@ -78,6 +78,7 @@ public: ...@@ -78,6 +78,7 @@ public:
virtual bool visit(Enum *) { return true; } virtual bool visit(Enum *) { return true; }
virtual bool visit(Function *) { return true; } virtual bool visit(Function *) { return true; }
virtual bool visit(Namespace *) { return true; } virtual bool visit(Namespace *) { return true; }
virtual bool visit(Template *) { return true; }
virtual bool visit(Class *) { return true; } virtual bool visit(Class *) { return true; }
virtual bool visit(Block *) { return true; } virtual bool visit(Block *) { return true; }
virtual bool visit(ForwardClassDeclaration *) { return true; } virtual bool visit(ForwardClassDeclaration *) { return true; }
......
...@@ -430,6 +430,63 @@ void Enum::visitSymbol0(SymbolVisitor *visitor) ...@@ -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) Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
: Scope(translationUnit, sourceLocation, name) : Scope(translationUnit, sourceLocation, name)
{ } { }
......
...@@ -376,6 +376,41 @@ private: ...@@ -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 class CPLUSPLUS_EXPORT Namespace: public Scope, public Type
{ {
public: public:
......
...@@ -92,6 +92,9 @@ bool Type::isFunctionType() const ...@@ -92,6 +92,9 @@ bool Type::isFunctionType() const
bool Type::isNamespaceType() const bool Type::isNamespaceType() const
{ return asNamespaceType() != 0; } { return asNamespaceType() != 0; }
bool Type::isTemplateType() const
{ return asTemplateType() != 0; }
bool Type::isClassType() const bool Type::isClassType() const
{ return asClassType() != 0; } { return asClassType() != 0; }
......
...@@ -70,6 +70,7 @@ public: ...@@ -70,6 +70,7 @@ public:
bool isNamedType() const; bool isNamedType() const;
bool isFunctionType() const; bool isFunctionType() const;
bool isNamespaceType() const; bool isNamespaceType() const;
bool isTemplateType() const;
bool isClassType() const; bool isClassType() const;
bool isEnumType() const; bool isEnumType() const;
bool isForwardClassDeclarationType() const; bool isForwardClassDeclarationType() const;
...@@ -90,6 +91,7 @@ public: ...@@ -90,6 +91,7 @@ public:
virtual const NamedType *asNamedType() const { return 0; } virtual const NamedType *asNamedType() const { return 0; }
virtual const Function *asFunctionType() const { return 0; } virtual const Function *asFunctionType() const { return 0; }
virtual const Namespace *asNamespaceType() 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 Class *asClassType() const { return 0; }
virtual const Enum *asEnumType() const { return 0; } virtual const Enum *asEnumType() const { return 0; }
virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; } virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; }
...@@ -110,6 +112,7 @@ public: ...@@ -110,6 +112,7 @@ public:
virtual NamedType *asNamedType() { return 0; } virtual NamedType *asNamedType() { return 0; }
virtual Function *asFunctionType() { return 0; } virtual Function *asFunctionType() { return 0; }
virtual Namespace *asNamespaceType() { return 0; } virtual Namespace *asNamespaceType() { return 0; }
virtual Template *asTemplateType() { return 0; }
virtual Class *asClassType() { return 0; } virtual Class *asClassType() { return 0; }
virtual Enum *asEnumType() { return 0; } virtual Enum *asEnumType() { return 0; }
virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; } virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; }
......
...@@ -174,6 +174,14 @@ bool TypeMatcher::match(const Namespace *type, const Namespace *otherType) ...@@ -174,6 +174,14 @@ bool TypeMatcher::match(const Namespace *type, const Namespace *otherType)
return true; 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) bool TypeMatcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType)
{ {
if (type != otherType) if