summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/CheckUndefinedSymbols.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2009-07-13 12:26:44 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2009-07-13 12:26:44 +0200
commit00f7cdac36bb4ba737d0de558420cba1c16177c2 (patch)
tree01ba147dd099dc8146b2f40b4f430160fa32d544 /src/libs/cplusplus/CheckUndefinedSymbols.cpp
parent1eefd16383bd0e3adb167ccf4e80f6563096594f (diff)
downloadqt-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.cpp86
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());