diff --git a/languages/cpp/cppduchain/CMakeLists.txt b/languages/cpp/cppduchain/CMakeLists.txt
index 7eba67f..5f27b8f 100644
--- a/languages/cpp/cppduchain/CMakeLists.txt
+++ b/languages/cpp/cppduchain/CMakeLists.txt
@@ -26,6 +26,7 @@ set(kdevcppduchain_LIB_SRCS
     cppeditorintegrator.cpp
     dumpchain.cpp
     cpptypes.cpp
+    ptrtomembertype.cpp
     dumptypes.cpp
     environmentmanager.cpp
     cppduchain.cpp
diff --git a/languages/cpp/cppduchain/cpptypes.h b/languages/cpp/cppduchain/cpptypes.h
index 87645e9..ccf4848 100644
--- a/languages/cpp/cppduchain/cpptypes.h
+++ b/languages/cpp/cppduchain/cpptypes.h
@@ -36,6 +36,7 @@
 #include "cppduchainexport.h"
 #include <language/duchain/types/alltypes.h>
 #include <language/duchain/types/typesystem.h>
+#include "ptrtomembertype.h"
 
 namespace KDevelop
 {
diff --git a/languages/cpp/cppduchain/expressionvisitor.cpp b/languages/cpp/cppduchain/expressionvisitor.cpp
index 7e73477..40290b0 100644
--- a/languages/cpp/cppduchain/expressionvisitor.cpp
+++ b/languages/cpp/cppduchain/expressionvisitor.cpp
@@ -1178,6 +1178,8 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
       if(fail || !constructedType) {
         DefaultVisitor::visitInitDeclarator(node);
         return;
+      } else {
+        visitNodes(this,node->declarator->ptr_ops);
       }
 
       DeclarationPointer chosenFunction;
@@ -1225,7 +1227,7 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
 
     visit(node->parameter_declaration_clause);
     visit(node->exception_spec);
-
+    {
     LOCKDUCHAIN;
     if( node->array_dimensions && oldLastType ) {
       ArrayType::Ptr p( new ArrayType() );
@@ -1237,7 +1239,7 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
       m_lastType = oldLastType;
       m_lastInstance = oldLastInstance;
     }
-
+    }
     visitNodes(this, node->ptr_ops);
   }
 
@@ -1262,7 +1264,6 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
     m_lastType = lastType;
     m_lastInstance = instance;
 
-    LOCKDUCHAIN;
     visit(node->ptr_op);
   }
 
@@ -1294,17 +1295,22 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
   void ExpressionVisitor::visitPtrOperator(PtrOperatorAST* node) {
     PushPositiveContext pushContext( m_currentContext, node->ducontext );
 
-    if( !m_lastType ) {
+    if( !m_lastType )
       problem(node, "Pointer-operator used without type");
-      return;
-    }
 
-    if( m_lastInstance ) {
+    if( m_lastInstance )
       problem(node, "Pointer-operator used on an instance instead of a type");
-      return;
-    }
 
-    LOCKDUCHAIN;
+
+    ///pointer-to-member
+    if(node->op==0){
+      PtrToMemberType::Ptr p( new PtrToMemberType() );
+      p->setBaseType( m_lastType );
+      p->setModifiers(TypeBuilder::parseConstVolatile(m_session, node->cv));
+      visit( node->mem_ptr->class_type );
+      p->setClassType( m_lastType );
+      m_lastType = p.cast<AbstractType>();
+    } else {
 
     static IndexedString ref("&");
     static IndexedString ptr("*");
@@ -1326,6 +1332,7 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
 
       m_lastType = p.cast<AbstractType>();
     }
+    }
     m_lastInstance = Instance(false);
   }
 
diff --git a/languages/cpp/cppduchain/tests/test_duchain.cpp b/languages/cpp/cppduchain/tests/test_duchain.cpp
index 327e6d0..0f24a53 100644
--- a/languages/cpp/cppduchain/tests/test_duchain.cpp
+++ b/languages/cpp/cppduchain/tests/test_duchain.cpp
@@ -499,6 +499,7 @@ void TestDUChain::testIntegralTypes()
   //Even if reference/pointer types have an invalid target, they should still preserve the pointer
   QVERIFY(AbstractType::Ptr(new ReferenceType)->toString().endsWith("&"));
   QVERIFY(AbstractType::Ptr(new PointerType)->toString().endsWith("*"));
+  QVERIFY(AbstractType::Ptr(new PtrToMemberType)->toString().endsWith("::*"));
 
 }
 
@@ -5861,5 +5862,69 @@ void TestDUChain::testCommentAfterFunctionCall()
   QVERIFY(top->childContexts().last()->localDeclarations().isEmpty());
   QCOMPARE(m_view->uses().size(), 1);
 }
+void TestDUChain::testPointerToMember()
+{
+  //                                         1         2         3
+  //                                123456789012345678901234567890
+  LockedTopDUContext top = parse(  "struct AA {"
+                                 "\n  int j;"
+                                 "\n};"
+                                 "\nstruct BB{"
+                                 "\n  int AA::* pj;"
+                                 "\n};"
+                                 "\nvoid f(int AA::* par){"
+                                 "\n  BB b;"
+                                 "\n  int AA::* BB::* ppj=&BB::pj;"
+                                 "\n  b.*ppj=par;"
+                                 "\n}",DumpAll
+                           );
+  QVERIFY(top);
+  DUChainReadLocker lock;
+  QVERIFY(top->problems().isEmpty());
+  QCOMPARE(top->childContexts().size(),4);
+  QCOMPARE(top->localDeclarations().size(),3);
+
+  QCOMPARE(top->localDeclarations().at(0)->uses().begin()->size(),3);
+  QCOMPARE(top->localDeclarations().at(1)->uses().begin()->size(),3);
+
+  QCOMPARE(top->localDeclarations().at(0)->uses().begin()->at(0),RangeInRevision(4,6,4,8));
+  QCOMPARE(top->localDeclarations().at(0)->uses().begin()->at(1),RangeInRevision(6,11,6,13));
+  QCOMPARE(top->localDeclarations().at(0)->uses().begin()->at(2),RangeInRevision(8,6,8,8));
+
+  QCOMPARE(top->localDeclarations().at(1)->uses().begin()->at(0),RangeInRevision(7,2,7,4));
+  QCOMPARE(top->localDeclarations().at(1)->uses().begin()->at(1),RangeInRevision(8,12,8,14));
+  QCOMPARE(top->localDeclarations().at(1)->uses().begin()->at(2),RangeInRevision(8,23,8,25));
+
+  {
+    DUContext* ctx = top->childContexts().at(1);
+    Declaration* dec = ctx->localDeclarations().first();
+    PtrToMemberType::Ptr type = dec->abstractType().cast<PtrToMemberType>();
+    QVERIFY(type);
+    StructureType::Ptr structType = type->classType().cast<StructureType>();
+    QVERIFY(structType);
+    QCOMPARE(structType->qualifiedIdentifier().toString(), QString("AA"));
+  }
+  {
+    DUContext* ctx = top->childContexts().at(3);
+    Declaration* dec = ctx->localDeclarations().at(1);
+    PtrToMemberType::Ptr type = dec->abstractType().cast<PtrToMemberType>();
+
+    {
+      QVERIFY(type);
+      StructureType::Ptr structType = type->classType().cast<StructureType>();
+      QVERIFY(structType);
+      QCOMPARE(structType->qualifiedIdentifier().toString(), QString("BB"));
+    }
+
+    PtrToMemberType::Ptr ptype = type->baseType().cast<PtrToMemberType>();
+    {
+      QVERIFY(ptype);
+      StructureType::Ptr structType = ptype->classType().cast<StructureType>();
+      QVERIFY(structType);
+      QCOMPARE(structType->qualifiedIdentifier().toString(), QString("AA"));
+    }
+  }
+
+}
 
 #include "test_duchain.moc"
diff --git a/languages/cpp/cppduchain/tests/test_duchain.h b/languages/cpp/cppduchain/tests/test_duchain.h
index 4cd7d05..23efbb0 100644
--- a/languages/cpp/cppduchain/tests/test_duchain.h
+++ b/languages/cpp/cppduchain/tests/test_duchain.h
@@ -190,6 +190,7 @@ private slots:
   void testAutoTypes();
 
   void testCommentAfterFunctionCall();
+  void testPointerToMember();
 private:
   void assertNoMemberFunctionModifiers(KDevelop::ClassFunctionDeclaration* memberFun);
 
diff --git a/languages/cpp/cppduchain/type_visitor.cpp b/languages/cpp/cppduchain/type_visitor.cpp
index cf00e6c..c49baf0 100644
--- a/languages/cpp/cppduchain/type_visitor.cpp
+++ b/languages/cpp/cppduchain/type_visitor.cpp
@@ -58,7 +58,8 @@ void TypeASTVisitor::run(TypeIdAST *node)
         do
           {
             PtrOperatorAST* ptrOp = it->element;
-            if (ptrOp && ptrOp->op) { ///@todo check ordering, eventually walk the chain in reversed order
+            if (ptrOp){
+              if(ptrOp->op) { ///@todo check ordering, eventually walk the chain in reversed order
               IndexedString op = m_session->token_stream->token(ptrOp->op).symbol();
               static IndexedString ref("&");
               static IndexedString ptr("*");
@@ -75,6 +76,15 @@ void TypeASTVisitor::run(TypeIdAST *node)
                   m_type = pointer.cast<AbstractType>();
                 }
               }
+              } else{ ///ptr-to-member
+                PtrToMemberType::Ptr pointer(new PtrToMemberType);
+                pointer->setModifiers(TypeBuilder::parseConstVolatile(m_session, ptrOp->cv));
+                pointer->setBaseType(m_type);
+                PtrToMemberAST * ast=ptrOp->mem_ptr;
+                visit(ast);
+                pointer->setClassType(m_type);
+                m_type=pointer.cast<AbstractType>();
+              }
             }
             it = it->next;
           }
diff --git a/languages/cpp/cppduchain/typebuilder.cpp b/languages/cpp/cppduchain/typebuilder.cpp
index 73723b2..994cc3d 100644
--- a/languages/cpp/cppduchain/typebuilder.cpp
+++ b/languages/cpp/cppduchain/typebuilder.cpp
@@ -594,6 +594,16 @@ void TypeBuilder::visitPtrOperator(PtrOperatorAST* node)
     closeType();
 }
 
+void TypeBuilder::visitPtrToMember(PtrToMemberAST *node)
+{
+  PtrToMemberType::Ptr pointer(new PtrToMemberType);
+  pointer->setBaseType(lastType());
+  ContextBuilder::visitPtrToMember(node);
+  pointer->setClassType(lastType());
+  openType(pointer);
+  closeType();
+}
+
 FunctionType* TypeBuilder::openFunction(DeclaratorAST *node)
 {
   FunctionType* functionType = new FunctionType();
diff --git a/languages/cpp/cppduchain/typebuilder.h b/languages/cpp/cppduchain/typebuilder.h
index 7fff507..b81c853 100644
--- a/languages/cpp/cppduchain/typebuilder.h
+++ b/languages/cpp/cppduchain/typebuilder.h
@@ -60,6 +60,7 @@ protected:
   virtual void visitTypedef(TypedefAST*);
   virtual void visitFunctionDeclaration(FunctionDefinitionAST*);
   virtual void visitPtrOperator(PtrOperatorAST*);
+  virtual void visitPtrToMember(PtrToMemberAST*);
   virtual void visitUsing(UsingAST *);
   virtual void visitParameterDeclaration(ParameterDeclarationAST*);
   virtual void visitTemplateParameter(TemplateParameterAST *);
diff --git a/languages/cpp/parser/ast.h b/languages/cpp/parser/ast.h
index cd896f7..0281c6b 100644
--- a/languages/cpp/parser/ast.h
+++ b/languages/cpp/parser/ast.h
@@ -833,6 +833,8 @@ class PtrToMemberAST : public AST
 public:
 
   DECLARE_AST_NODE(PtrToMember)
+
+  TypeSpecifierAST *class_type;
 };
 
 class JumpStatementAST : public StatementAST
diff --git a/languages/cpp/parser/codegenerator.cpp b/languages/cpp/parser/codegenerator.cpp
index fcdb04c..a65b010 100644
--- a/languages/cpp/parser/codegenerator.cpp
+++ b/languages/cpp/parser/codegenerator.cpp
@@ -612,8 +612,7 @@ void CodeGenerator::visitPtrOperator(PtrOperatorAST* node)
 
 void CodeGenerator::visitPtrToMember(PtrToMemberAST* node)
 {
-  // TODO fix AST
-  Q_UNUSED(node);
+  visit(node->class_type);
   printToken(Token_scope);
   m_output << "*";
 }
diff --git a/languages/cpp/parser/default_visitor.cpp b/languages/cpp/parser/default_visitor.cpp
index 3d061ff..73c66ce 100644
--- a/languages/cpp/parser/default_visitor.cpp
+++ b/languages/cpp/parser/default_visitor.cpp
@@ -320,9 +320,9 @@ void DefaultVisitor::visitPtrOperator(PtrOperatorAST *node)
   visit(node->mem_ptr);
 }
 
-void DefaultVisitor::visitPtrToMember(PtrToMemberAST *)
+void DefaultVisitor::visitPtrToMember(PtrToMemberAST *node)
 {
-  // nothing to do
+  visit(node->class_type);
 }
 
 void DefaultVisitor::visitReturnStatement(ReturnStatementAST *node)
diff --git a/languages/cpp/parser/parser.cpp b/languages/cpp/parser/parser.cpp
index 1d4c644..281ad8d 100644
--- a/languages/cpp/parser/parser.cpp
+++ b/languages/cpp/parser/parser.cpp
@@ -561,8 +561,11 @@ bool Parser::parseName(NameAST*& node, ParseNameAcceptTemplate acceptTemplateId)
       if (!ast) 
         ast = CreateNode<NameAST>(session->mempool);
 
-      if (session->token_stream->lookAhead() == Token_scope)
+      if (session->token_stream->lookAhead() == Token_scope &&
+        //ptr-to-member
+        session->token_stream->lookAhead(1) != '*')
         {
+
           advance();
 
           ast->qualified_names
@@ -2637,25 +2640,11 @@ bool Parser::parseInitializerClause(InitializerClauseAST *&node)
 
 bool Parser::parsePtrToMember(PtrToMemberAST *&node)
 {
-#if defined(__GNUC__)
-#warning "implemente me (AST)"
-#endif
-
   uint start = session->token_stream->cursor();
 
-  uint global_scope = 0;
-  if (session->token_stream->lookAhead() == Token_scope)
-    {
-      global_scope = session->token_stream->cursor();
-      advance();
-    }
-
-  UnqualifiedNameAST *name = 0;
-  while (session->token_stream->lookAhead() == Token_identifier)
-    {
-      if (!parseUnqualifiedName(name))
-        break;
+  TypeSpecifierAST* type_ast = 0;
 
+  if(parseTypeSpecifier(type_ast)){
       if (session->token_stream->lookAhead() == Token_scope
           && session->token_stream->lookAhead(1) == '*')
         {
@@ -2663,14 +2652,11 @@ bool Parser::parsePtrToMember(PtrToMemberAST *&node)
           advance();
 
           PtrToMemberAST *ast = CreateNode<PtrToMemberAST>(session->mempool);
+      ast->class_type=type_ast;
           UPDATE_POS(ast, start, _M_last_valid_token+1);
           node = ast;
-
           return true;
         }
-
-      if (session->token_stream->lookAhead() == Token_scope)
-        advance();
     }
 
   rewind(start);
diff --git a/languages/cpp/parser/tests/test_parser.cpp b/languages/cpp/parser/tests/test_parser.cpp
index e35a804..dfb7a90 100644
--- a/languages/cpp/parser/tests/test_parser.cpp
+++ b/languages/cpp/parser/tests/test_parser.cpp
@@ -685,6 +685,27 @@ private slots:
     QVERIFY(hasKind(funcAst, AST::Kind_InitDeclarator));
   }
 
+  void testPtrToMemberAst() {
+    pool memPool;
+    TranslationUnitAST* ast = parse("\nstruct AA {"
+                                    "\n  int j;"
+                                    "\n};"
+                                    "\nstruct BB{"
+                                    "\n  int AA::* pj;"
+                                    "\n};"
+                                    "\nvoid f(){"
+                                    "\n  int AA::* BB::* ppj=&BB::pj;"
+                                    "\n}"
+                                    , &memPool);
+    QVERIFY(ast!=0);
+    QCOMPARE(ast->declarations->count(), 3);
+    QVERIFY(hasKind(ast,AST::Kind_PtrToMember));
+    FunctionDefinitionAST* f_ast=static_cast<FunctionDefinitionAST*>(getAST(ast,AST::Kind_FunctionDefinition));
+    QVERIFY(hasKind(f_ast,AST::Kind_PtrToMember));
+    DeclaratorAST* d_ast=static_cast<DeclaratorAST*>(getAST(f_ast->function_body,AST::Kind_Declarator));
+    QCOMPARE(d_ast-> ptr_ops->count(),2);
+  }
+
   void testSwitchStatement()
   {
     int problemCount = control.problems().count();
