forked from qt-creator/qt-creator
		
	Search for type names in template type and template-template-type parameters.
This commit is contained in:
		| @@ -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; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user