Commit 00f7cdac authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Search for type names in template type and template-template-type parameters.

parent 1eefd163
......@@ -61,6 +61,48 @@ void CheckUndefinedSymbols::setGlobalNamespaceBinding(NamespaceBindingPtr global
void CheckUndefinedSymbols::operator()(AST *ast)
{ accept(ast); }
QByteArray CheckUndefinedSymbols::templateParameterName(NameAST *ast) const
{
if (ast && ast->name) {
if (Identifier *id = ast->name->identifier())
return QByteArray::fromRawData(id->chars(), id->size());
}
return QByteArray();
}
QByteArray CheckUndefinedSymbols::templateParameterName(DeclarationAST *ast) const
{
if (ast) {
if (TypenameTypeParameterAST *d = ast->asTypenameTypeParameter())
return templateParameterName(d->name);
else if (TemplateTypeParameterAST *d = ast->asTemplateTypeParameter())
return templateParameterName(d->name);
}
return QByteArray();
}
bool CheckUndefinedSymbols::isType(const QByteArray &name) const
{
for (int i = _templateDeclarationStack.size() - 1; i != - 1; --i) {
TemplateDeclarationAST *templateDeclaration = _templateDeclarationStack.at(i);
for (DeclarationListAST *it = templateDeclaration->template_parameters; it; it = it->next) {
DeclarationAST *templateParameter = it->declaration;
if (templateParameterName(templateParameter) == name)
return true;
}
}
return _types.contains(name);
}
bool CheckUndefinedSymbols::isType(Identifier *id) const
{
if (! id)
return false;
return isType(QByteArray::fromRawData(id->chars(), id->size()));
}
void CheckUndefinedSymbols::addType(Name *name)
{
if (! name)
......@@ -124,22 +166,22 @@ void CheckUndefinedSymbols::buildTypeMap(NamespaceBinding *binding, QSet<Namespa
FunctionDeclaratorAST *CheckUndefinedSymbols::currentFunctionDeclarator() const
{
if (functionDeclarationStack.isEmpty())
if (_functionDeclaratorStack.isEmpty())
return 0;
return functionDeclarationStack.last();
return _functionDeclaratorStack.last();
}
bool CheckUndefinedSymbols::visit(FunctionDeclaratorAST *ast)
{
functionDeclarationStack.append(ast);
_functionDeclaratorStack.append(ast);
return true;
}
void CheckUndefinedSymbols::endVisit(FunctionDeclaratorAST *)
{
functionDeclarationStack.removeLast();
_functionDeclaratorStack.removeLast();
}
bool CheckUndefinedSymbols::visit(TypeofSpecifierAST *ast)
......@@ -148,22 +190,6 @@ bool CheckUndefinedSymbols::visit(TypeofSpecifierAST *ast)
return false;
}
bool CheckUndefinedSymbols::visit(TypenameTypeParameterAST *ast)
{
if (NameAST *nameAst = ast->name)
addType(nameAst->name);
return true;
}
bool CheckUndefinedSymbols::visit(TemplateTypeParameterAST *ast)
{
if (ast->name)
addType(ast->name->name);
return true;
}
bool CheckUndefinedSymbols::visit(NamedTypeSpecifierAST *ast)
{
if (ast->name) {
......@@ -172,7 +198,7 @@ bool CheckUndefinedSymbols::visit(NamedTypeSpecifierAST *ast)
getTokenStartPosition(ast->firstToken(), &line, &col);
// qWarning() << _doc->fileName() << line << col;
} else if (Identifier *id = ast->name->name->identifier()) {
if (! _types.contains(QByteArray::fromRawData(id->chars(), id->size()))) {
if (! isType(id)) {
if (FunctionDeclaratorAST *functionDeclarator = currentFunctionDeclarator()) {
if (functionDeclarator->as_cpp_initializer)
return true;
......@@ -187,6 +213,17 @@ bool CheckUndefinedSymbols::visit(NamedTypeSpecifierAST *ast)
return true;
}
bool CheckUndefinedSymbols::visit(TemplateDeclarationAST *ast)
{
_templateDeclarationStack.append(ast);
return true;
}
void CheckUndefinedSymbols::endVisit(TemplateDeclarationAST *)
{
_templateDeclarationStack.removeLast();
}
bool CheckUndefinedSymbols::visit(ClassSpecifierAST *ast)
{
if (ast->base_clause) {
......@@ -241,6 +278,9 @@ bool CheckUndefinedSymbols::visit(FunctionDefinitionAST *ast)
return true;
}
void CheckUndefinedSymbols::endVisit(FunctionDefinitionAST *)
{ }
bool CheckUndefinedSymbols::visit(SimpleDeclarationAST *ast)
{
const bool check = qobjectCheck();
......@@ -265,7 +305,7 @@ bool CheckUndefinedSymbols::visit(BaseSpecifierAST *base)
if (Name *name = nameAST->name) {
Identifier *id = name->identifier();
const QByteArray spell = QByteArray::fromRawData(id->chars(), id->size());
if (_types.contains(spell))
if (isType(spell))
resolvedBaseClassName = true;
}
......@@ -310,7 +350,7 @@ bool CheckUndefinedSymbols::visit(QualifiedNameAST *ast)
Name *name = q->nameAt(i);
if (Identifier *id = name->identifier()) {
const QByteArray spell = QByteArray::fromRawData(id->chars(), id->size());
if (! (_namespaceNames.contains(spell) || _types.contains(spell))) {
if (! (_namespaceNames.contains(spell) || isType(id))) {
translationUnit()->warning(ast->firstToken(),
"`%s' is not a namespace or class name",
spell.constData());
......
......@@ -52,24 +52,33 @@ public:
protected:
using ASTVisitor::visit;
bool isType(Identifier *id) const;
bool isType(const QByteArray &name) const;
void addType(Name *name);
void buildTypeMap(Class *klass);
void buildTypeMap(NamespaceBinding *binding, QSet<NamespaceBinding *> *processed);
FunctionDeclaratorAST *currentFunctionDeclarator() const;
bool qobjectCheck() const;
QByteArray templateParameterName(NameAST *ast) const;
QByteArray templateParameterName(DeclarationAST *ast) const;
virtual bool visit(FunctionDeclaratorAST *ast);
virtual void endVisit(FunctionDeclaratorAST *ast);
virtual bool visit(TypeofSpecifierAST *ast);
virtual bool visit(TypenameTypeParameterAST *ast);
virtual bool visit(TemplateTypeParameterAST *ast);
virtual bool visit(NamedTypeSpecifierAST *ast);
virtual bool visit(TemplateDeclarationAST *ast);
virtual void endVisit(TemplateDeclarationAST *);
virtual bool visit(ClassSpecifierAST *ast);
virtual void endVisit(ClassSpecifierAST *);
virtual bool visit(FunctionDefinitionAST *ast);
virtual void endVisit(FunctionDefinitionAST *ast);
virtual bool visit(SimpleDeclarationAST *ast);
virtual bool visit(BaseSpecifierAST *base);
virtual bool visit(UsingDirectiveAST *ast);
......@@ -81,7 +90,8 @@ private:
Document::Ptr _doc;
NamespaceBindingPtr _globalNamespaceBinding;
QList<bool> _qobjectStack;
QList<FunctionDeclaratorAST *> functionDeclarationStack;
QList<FunctionDeclaratorAST *> _functionDeclaratorStack;
QList<TemplateDeclarationAST *> _templateDeclarationStack;
QSet<QByteArray> _types;
QSet<QByteArray> _namespaceNames;
};
......
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