diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index a9b2d38d1e9ac024184a8fa9863f529917e64564..5d7f34132ab7613d437ae2d2658f95080fecf167 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -288,8 +288,8 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken)
 
 bool FindUsages::visit(QualifiedNameAST *ast)
 {
-    for (NestedNameSpecifierAST *nested_name_specifier = ast->nested_name_specifier;
-         nested_name_specifier; nested_name_specifier = nested_name_specifier->next) {
+    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier; it; it = it->next) {
+        NestedNameSpecifierAST *nested_name_specifier = it->value;
 
         if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
             SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName();
@@ -299,9 +299,8 @@ bool FindUsages::visit(QualifiedNameAST *ast)
                 template_id = class_or_namespace_name->asTemplateId();
 
                 if (template_id) {
-                    for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
-                         template_arguments; template_arguments = template_arguments->next) {
-                        accept(template_arguments->value);
+                    for (TemplateArgumentListAST *arg_it = template_id->template_arguments; arg_it; arg_it = arg_it->next) {
+                        accept(arg_it->value);
                     }
                 }
             }
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index ec036230935878c6741048cfaa18d82bb41718f9..cd85bff3dc6e78bbafb06534426a5f1740e503bf 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -308,8 +308,8 @@ protected:
 
     virtual bool visit(QualifiedNameAST *ast)
     {
-        for (NestedNameSpecifierAST *it = ast->nested_name_specifier; it; it = it->next)
-            searchUsesInTemplateArguments(it->class_or_namespace_name);
+        for (NestedNameSpecifierListAST *it = ast->nested_name_specifier; it; it = it->next)
+            searchUsesInTemplateArguments(it->value->class_or_namespace_name);
 
         searchUsesInTemplateArguments(ast->unqualified_name);
         return false;
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 30ba2cba5a6a24cd467dc51f0b683e67dffc5180..4286cc8dff9b5dff389381991dbc17906c40b75c 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -1299,12 +1299,10 @@ unsigned PointerToMemberAST::lastToken() const
     if (star_token)
         return star_token + 1;
 
-    for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next) {
-        if (! it->next)
-            return it->lastToken();
-    }
+    else if (nested_name_specifier)
+        return nested_name_specifier->lastToken();
 
-    if (global_scope_token)
+    else if (global_scope_token)
         return global_scope_token + 1;
 
     return 0;
@@ -1349,10 +1347,8 @@ unsigned QualifiedNameAST::lastToken() const
     if (unqualified_name)
         return unqualified_name->lastToken();
 
-    for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next) {
-        if (! it->next)
-            return it->lastToken();
-    }
+    if (nested_name_specifier)
+        return nested_name_specifier->lastToken();
 
     if (global_scope_token)
         return global_scope_token + 1;
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index e1b901dca5810030678808f2f69b18a2ec2a9ceb..97a56da8efe326b1372dd1b29fcf9a3b44e574b6 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -1175,7 +1175,7 @@ class CPLUSPLUS_EXPORT QualifiedNameAST: public NameAST
 {
 public:
     unsigned global_scope_token;
-    NestedNameSpecifierAST *nested_name_specifier;
+    NestedNameSpecifierListAST *nested_name_specifier;
     NameAST *unqualified_name;
 
 public:
@@ -1614,7 +1614,7 @@ class CPLUSPLUS_EXPORT PointerToMemberAST: public PtrOperatorAST
 {
 public:
     unsigned global_scope_token;
-    NestedNameSpecifierAST *nested_name_specifier;
+    NestedNameSpecifierListAST *nested_name_specifier;
     unsigned star_token;
     SpecifierAST *cv_qualifier_seq;
 
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 2a9160094fea2f9be43ef34cec39c5e0b3dce14e..63ef418ec9edc0d74d280308b1bf70b93c45abf6 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -453,8 +453,7 @@ void NestedNameSpecifierAST::accept0(ASTVisitor *visitor)
 void QualifiedNameAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
-        for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next)
-            accept(it, visitor);
+        accept(nested_name_specifier, visitor);
         accept(unqualified_name, visitor);
     }
     visitor->endVisit(this);
@@ -668,8 +667,8 @@ void PostfixExpressionAST::accept0(ASTVisitor *visitor)
 void PointerToMemberAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
-        for (NestedNameSpecifierAST *it = nested_name_specifier; it; it = it->next)
-            accept(it, visitor);
+        accept(nested_name_specifier, visitor);
+
         for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next)
             accept(it, visitor);
     }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index 07f51b40ae647d6d5c9e15d74514b85c85bd47e0..ac70f735db5676f3d804d13391be5309892c34e6 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -202,6 +202,7 @@ typedef List<NewArrayDeclaratorAST *> NewArrayDeclaratorListAST;
 typedef List<PostfixAST *> PostfixListAST;
 typedef List<PostfixDeclaratorAST *> PostfixDeclaratorListAST;
 typedef List<AttributeAST *> AttributeListAST;
+typedef List<NestedNameSpecifierAST *> NestedNameSpecifierListAST;
 
 typedef List<NameAST *> ObjCIdentifierListAST;
 typedef List<ObjCMessageArgumentAST *> ObjCMessageArgumentListAST;
diff --git a/src/shared/cplusplus/CheckName.cpp b/src/shared/cplusplus/CheckName.cpp
index 4b1c62ff0e617f4e0577cbaa113e1a279c69a6e9..bd899bb7bba62cd942058e4dc91fe59abd1f7133 100644
--- a/src/shared/cplusplus/CheckName.cpp
+++ b/src/shared/cplusplus/CheckName.cpp
@@ -82,17 +82,19 @@ Name *CheckName::check(NameAST *name, Scope *scope)
     return switchName(previousName);
 }
 
-Name *CheckName::check(NestedNameSpecifierAST *nested_name_specifier, Scope *scope)
+Name *CheckName::check(NestedNameSpecifierListAST *nested_name_specifier_list, Scope *scope)
 {
     Name *previousName = switchName(0);
     Scope *previousScope = switchScope(scope);
 
     std::vector<Name *> names;
-    for (NestedNameSpecifierAST *it = nested_name_specifier;
-            it; it = it->next) {
-        names.push_back(semantic()->check(it->class_or_namespace_name, _scope));
+    for (NestedNameSpecifierListAST *it = nested_name_specifier_list; it; it = it->next) {
+        NestedNameSpecifierAST *nested_name_specifier = it->value;
+        names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
     }
-    _name = control()->qualifiedNameId(&names[0], names.size());
+
+    if (! names.empty())
+        _name = control()->qualifiedNameId(&names[0], names.size());
 
     (void) switchScope(previousScope);
     return switchName(previousName);
@@ -137,9 +139,9 @@ Scope *CheckName::switchScope(Scope *scope)
 bool CheckName::visit(QualifiedNameAST *ast)
 {
     std::vector<Name *> names;
-    for (NestedNameSpecifierAST *it = ast->nested_name_specifier;
-            it; it = it->next) {
-        names.push_back(semantic()->check(it->class_or_namespace_name, _scope));
+    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier; it; it = it->next) {
+        NestedNameSpecifierAST *nested_name_specifier = it->value;
+        names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
     }
     names.push_back(semantic()->check(ast->unqualified_name, _scope));
     _name = control()->qualifiedNameId(&names[0], names.size(),
diff --git a/src/shared/cplusplus/CheckName.h b/src/shared/cplusplus/CheckName.h
index ec2b97beea074292e3e97e311374a20a6b443430..7f86d751671bef6d880e655f45c7a2f6f99076c6 100644
--- a/src/shared/cplusplus/CheckName.h
+++ b/src/shared/cplusplus/CheckName.h
@@ -62,7 +62,7 @@ public:
     virtual ~CheckName();
 
     Name *check(NameAST *name, Scope *scope);
-    Name *check(NestedNameSpecifierAST *name, Scope *scope);
+    Name *check(NestedNameSpecifierListAST *name, Scope *scope);
     Name *check(ObjCSelectorAST *args, Scope *scope);
     void check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope);
 
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index d9b3635e4b73a1a57023b6ec5f16001998797bc4..904a5c76f045ca6b51a776476338e1de1ed8c372 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -348,28 +348,30 @@ bool Parser::parseTemplateId(NameAST *&node)
     return false;
 }
 
-bool Parser::parseNestedNameSpecifier(NestedNameSpecifierAST *&node,
+bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node,
                                       bool /*acceptTemplateId*/)
 {
     DEBUG_THIS_RULE();
-    NestedNameSpecifierAST **nested_name_specifier = &node;
+    NestedNameSpecifierListAST **nested_name_specifier = &node;
     NameAST *class_or_namespace_name = 0;
-    if (parseClassOrNamespaceName(class_or_namespace_name) &&
-            LA() == T_COLON_COLON) {
+    if (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) {
         unsigned scope_token = consumeToken();
-        *nested_name_specifier = new (_pool) NestedNameSpecifierAST;
-        (*nested_name_specifier)->class_or_namespace_name
-                = class_or_namespace_name;
-        (*nested_name_specifier)->scope_token = scope_token;
 
+        NestedNameSpecifierAST *name = new (_pool) NestedNameSpecifierAST;
+        name->class_or_namespace_name = class_or_namespace_name;
+        name->scope_token = scope_token;
+
+        *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name);
         nested_name_specifier = &(*nested_name_specifier)->next;
 
-        while (parseClassOrNamespaceName(class_or_namespace_name) &&
-               LA() == T_COLON_COLON) {
+        while (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) {
             scope_token = consumeToken();
-            *nested_name_specifier = new (_pool) NestedNameSpecifierAST;
-            (*nested_name_specifier)->class_or_namespace_name = class_or_namespace_name;
-            (*nested_name_specifier)->scope_token = scope_token;
+
+            name = new (_pool) NestedNameSpecifierAST;
+            name->class_or_namespace_name = class_or_namespace_name;
+            name->scope_token = scope_token;
+
+            *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name);
             nested_name_specifier = &(*nested_name_specifier)->next;
         }
 
@@ -382,8 +384,7 @@ bool Parser::parseNestedNameSpecifier(NestedNameSpecifierAST *&node,
     return false;
 }
 
-bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name,
-        bool acceptTemplateId)
+bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId)
 {
     DEBUG_THIS_RULE();
     unsigned start = cursor();
@@ -399,7 +400,7 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
     if (LA() == T_COLON_COLON)
         global_scope_token = consumeToken();
 
-    NestedNameSpecifierAST *nested_name_specifier = 0;
+    NestedNameSpecifierListAST *nested_name_specifier = 0;
     parseNestedNameSpecifierOpt(nested_name_specifier,
                                 /*acceptTemplateId=*/ true);
 
@@ -976,13 +977,12 @@ bool Parser::parsePtrOperator(PtrOperatorAST *&node)
         if (LA() == T_COLON_COLON)
             global_scope_token = consumeToken();
 
-        NestedNameSpecifierAST *nested_name_specifier = 0;
-        bool has_nested_name_specifier = parseNestedNameSpecifier(
-                nested_name_specifier, true);
+        NestedNameSpecifierListAST *nested_name_specifiers = 0;
+        bool has_nested_name_specifier = parseNestedNameSpecifier(nested_name_specifiers, true);
         if (has_nested_name_specifier && LA() == T_STAR) {
             PointerToMemberAST *ast = new (_pool) PointerToMemberAST;
             ast->global_scope_token = global_scope_token;
-            ast->nested_name_specifier = nested_name_specifier;
+            ast->nested_name_specifier = nested_name_specifiers;
             ast->star_token = consumeToken();
             parseCvQualifiers(ast->cv_qualifier_seq);
             node = ast;
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index 39f42ba0bbcbbe71565e047f5a891e885881a395..2ab563f09a3e48d9ea1e31656688a99fb775de0a 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -142,8 +142,8 @@ public:
     bool parseClassOrNamespaceName(NameAST *&node);
     bool parseNameId(NameAST *&node);
     bool parseName(NameAST *&node, bool acceptTemplateId = true);
-    bool parseNestedNameSpecifier(NestedNameSpecifierAST *&node, bool acceptTemplateId);
-    bool parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name, bool acceptTemplateId);
+    bool parseNestedNameSpecifier(NestedNameSpecifierListAST *&node, bool acceptTemplateId);
+    bool parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId);
     bool parseNamespace(DeclarationAST *&node);
     bool parseNamespaceAliasDefinition(DeclarationAST *&node);
     bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node);
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index e3b4b0b7ca4e4de0ac01f14fcf57494a72e7a5a2..c2dfa42ff7c9f58580861d0b832707c5b63a0f85 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -152,7 +152,7 @@ void Semantic::check(StatementAST *statement, Scope *scope)
 Name *Semantic::check(NameAST *name, Scope *scope)
 { return d->checkName->check(name, scope); }
 
-Name *Semantic::check(NestedNameSpecifierAST *name, Scope *scope)
+Name *Semantic::check(NestedNameSpecifierListAST *name, Scope *scope)
 { return d->checkName->check(name, scope); }
 
 Name *Semantic::check(ObjCSelectorAST *args, Scope *scope)
diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h
index b07883e8473d854b597d4e9b6c9f67df95c3d7e3..b42b13efed5387aeeb03bca1350407ff45446152 100644
--- a/src/shared/cplusplus/Semantic.h
+++ b/src/shared/cplusplus/Semantic.h
@@ -84,7 +84,7 @@ public:
 
     Name *check(NameAST *name, Scope *scope);
 
-    Name *check(NestedNameSpecifierAST *name, Scope *scope);
+    Name *check(NestedNameSpecifierListAST *name, Scope *scope);
 
     Name *check(ObjCSelectorAST *args, Scope *scope);
     FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope);