diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.cpp b/src/libs/cplusplus/CheckUndefinedSymbols.cpp
index bf2c201bb6b1d0be9675fa20b3174b4876ab12f9..d0d69187468ee1f1a4372a6b9f279400db71a682 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());
diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.h b/src/libs/cplusplus/CheckUndefinedSymbols.h
index 79e64a1262dcca371a61d1dd13d780b243852c86..8def4931435aa0aa0e1690fa013efb11d423cdaf 100644
--- a/src/libs/cplusplus/CheckUndefinedSymbols.h
+++ b/src/libs/cplusplus/CheckUndefinedSymbols.h
@@ -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;
 };