diff options
| author | Roberto Raggi <roberto.raggi@nokia.com> | 2009-07-13 12:26:44 +0200 |
|---|---|---|
| committer | Roberto Raggi <roberto.raggi@nokia.com> | 2009-07-13 12:26:44 +0200 |
| commit | 00f7cdac36bb4ba737d0de558420cba1c16177c2 (patch) | |
| tree | 01ba147dd099dc8146b2f40b4f430160fa32d544 /src/libs/cplusplus/CheckUndefinedSymbols.cpp | |
| parent | 1eefd16383bd0e3adb167ccf4e80f6563096594f (diff) | |
| download | qt-creator-00f7cdac36bb4ba737d0de558420cba1c16177c2.tar.gz | |
Search for type names in template type and template-template-type parameters.
Diffstat (limited to 'src/libs/cplusplus/CheckUndefinedSymbols.cpp')
| -rw-r--r-- | src/libs/cplusplus/CheckUndefinedSymbols.cpp | 86 |
1 files changed, 63 insertions, 23 deletions
diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.cpp b/src/libs/cplusplus/CheckUndefinedSymbols.cpp index bf2c201bb6..d0d6918746 100644 --- a/src/libs/cplusplus/CheckUndefinedSymbols.cpp +++ b/src/libs/cplusplus/CheckUndefinedSymbols.cpp @@ -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()); |
