pointer to member support

floris flo.ruijt at hotmail.com
Thu Dec 23 17:23:30 GMT 2010


it annoyed me that kdevelop couldn't highlight uses in pointer to member declarations like this:
struct AA {};
int AA::* b;// AA not highlighted
these patches fix that. I new to kdevelop-hacking so i may have made some errors.
 


diff --git a/languages/cpp/cppduchain/expressionvisitor.cpp b/languages/cpp/cppduchain/expressionvisitor.cpp
index 099b76e..1159540 100644
--- a/languages/cpp/cppduchain/expressionvisitor.cpp
+++ b/languages/cpp/cppduchain/expressionvisitor.cpp
@@ -1305,26 +1305,37 @@ void ExpressionVisitor::createDelayedType( AST* node , bool expression ) {
     }
 
     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("*");
 
-    static IndexedString ref("&");
-    static IndexedString ptr("*");
-
-    IndexedString op = m_session->token_stream->token(node->op).symbol();
+      IndexedString op = m_session->token_stream->token(node->op).symbol();
 
 
-    if(op == ptr) {
+      if(op == ptr) {
 
-      PointerType::Ptr p( new PointerType() );
-      p->setBaseType( m_lastType );
-      p->setModifiers(TypeBuilder::parseConstVolatile(m_session, node->cv));
+        PointerType::Ptr p( new PointerType() );
+        p->setBaseType( m_lastType );
+        p->setModifiers(TypeBuilder::parseConstVolatile(m_session, node->cv));
 
-      m_lastType = p.cast<AbstractType>();
-    }else{
-      ReferenceType::Ptr p( new ReferenceType() );
-      p->setBaseType( m_lastType );
-      p->setModifiers(TypeBuilder::parseConstVolatile(m_session, node->cv));
+        m_lastType = p.cast<AbstractType>();
+      }else{
+        ReferenceType::Ptr p( new ReferenceType() );
+        p->setBaseType( m_lastType );
+        p->setModifiers(TypeBuilder::parseConstVolatile(m_session, node->cv));
 
-      m_lastType = p.cast<AbstractType>();
+        m_lastType = p.cast<AbstractType>();
+      }
     }
     m_lastInstance = Instance(false);
   }
diff --git a/languages/cpp/cppduchain/type_visitor.cpp b/languages/cpp/cppduchain/type_visitor.cpp
index cf00e6c..9cae305 100644
--- a/languages/cpp/cppduchain/type_visitor.cpp
+++ b/languages/cpp/cppduchain/type_visitor.cpp
@@ -28,6 +28,8 @@
 #include "typebuilder.h"
 #include <language/duchain/duchainlock.h>
 
+#include <language/duchain/types/ptrtomembertype.h>
+
 using namespace Cpp;
 
 #include <QtCore/QString>
@@ -58,22 +60,32 @@ void TypeASTVisitor::run(TypeIdAST *node)
         do
           {
             PtrOperatorAST* ptrOp = it->element;
-            if (ptrOp && 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("*");
-              if (!op.isEmpty()) {
-                if (op == ref) {
-                  ReferenceType::Ptr pointer(new ReferenceType());
-                  pointer->setModifiers(TypeBuilder::parseConstVolatile(m_session, ptrOp->cv));
-                  pointer->setBaseType(m_type);
-                  m_type = pointer.cast<AbstractType>();
-                } else if (op == ptr) {
-                  PointerType::Ptr pointer(new PointerType());
-                  pointer->setModifiers(TypeBuilder::parseConstVolatile(m_session, ptrOp->cv));
-                  pointer->setBaseType(m_type);
-                  m_type = pointer.cast<AbstractType>();
+            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("*");
+                if (!op.isEmpty()) {
+                  if (op == ref) {
+                    ReferenceType::Ptr pointer(new ReferenceType());
+                    pointer->setModifiers(TypeBuilder::parseConstVolatile(m_session, ptrOp->cv));
+                    pointer->setBaseType(m_type);
+                    m_type = pointer.cast<AbstractType>();
+                  } else if (op == ptr) {
+                    PointerType::Ptr pointer(new PointerType());
+                    pointer->setModifiers(TypeBuilder::parseConstVolatile(m_session, ptrOp->cv));
+                    pointer->setBaseType(m_type);
+                    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->class_type);
+                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/cppduchain/usebuilder.cpp b/languages/cpp/cppduchain/usebuilder.cpp
index 68b08fb..1f75fae 100644
--- a/languages/cpp/cppduchain/usebuilder.cpp
+++ b/languages/cpp/cppduchain/usebuilder.cpp
@@ -233,9 +233,8 @@ void UseBuilder::visitSimpleDeclaration(SimpleDeclarationAST* node)
       }
       it = it->next;
     } while (it != end);
-  }else{
-    DefaultVisitor::visitSimpleDeclaration(node);    
   }
+  DefaultVisitor::visitSimpleDeclaration(node);    
 }
 
 void UseBuilder::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST* node)
diff --git a/languages/cpp/parser/ast.h b/languages/cpp/parser/ast.h
index cd896f7..9369ff7 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/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 b07910a..c38527f 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,42 +2640,25 @@ 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)
+  TypeSpecifierAST* type_ast = 0;
+  
+  if(parseTypeSpecifier(type_ast)){
+    if (session->token_stream->lookAhead() == Token_scope
+      && session->token_stream->lookAhead(1) == '*')
     {
-      global_scope = session->token_stream->cursor();
       advance();
+      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;
     }
-
-  UnqualifiedNameAST *name = 0;
-  while (session->token_stream->lookAhead() == Token_identifier)
-    {
-      if (!parseUnqualifiedName(name))
-        break;
-
-      if (session->token_stream->lookAhead() == Token_scope
-          && session->token_stream->lookAhead(1) == '*')
-        {
-          advance();
-          advance();
-
-          PtrToMemberAST *ast = CreateNode<PtrToMemberAST>(session->mempool);
-          UPDATE_POS(ast, start, _M_last_valid_token+1);
-          node = ast;
-
-          return true;
-        }
-
-      if (session->token_stream->lookAhead() == Token_scope)
-        advance();
-    }
-
+  }
+  
   rewind(start);
   return false;
 }




####here comes the second pathch####


diff --git a/kdevplatform.kdev4 b/kdevplatform.kdev4
index f5f408c..d8cb86e 100644
--- a/kdevplatform.kdev4
+++ b/kdevplatform.kdev4
@@ -1,3 +1,3 @@
 [Project]
-Name=KDevPlatform
 Manager=KDevCMakeManager
+Name=kdevplatform
diff --git a/language/CMakeLists.txt b/language/CMakeLists.txt
index 67985db..6f55f1c 100644
--- a/language/CMakeLists.txt
+++ b/language/CMakeLists.txt
@@ -62,6 +62,7 @@ set(kdevplatformlanguage_LIB_SRCS
     duchain/types/structuretype.cpp
     duchain/types/pointertype.cpp
     duchain/types/referencetype.cpp
+    duchain/types/ptrtomembertype.cpp
     duchain/types/delayedtype.cpp
     duchain/types/arraytype.cpp
     duchain/types/indexedtype.cpp
@@ -252,6 +253,7 @@ install(FILES
     duchain/types/functiontype.h
     duchain/types/structuretype.h
     duchain/types/pointertype.h
+    duchain/types/ptrtomembertype.h
     duchain/types/referencetype.h
     duchain/types/delayedtype.h
     duchain/types/arraytype.h
diff --git a/language/duchain/types/alltypes.h b/language/duchain/types/alltypes.h
index e233985..fd368ed 100644
--- a/language/duchain/types/alltypes.h
+++ b/language/duchain/types/alltypes.h
@@ -22,6 +22,7 @@
 #include "integraltype.h"
 #include "functiontype.h"
 #include "pointertype.h"
+#include "ptrtomembertype.h"
 #include "referencetype.h"
 #include "structuretype.h"
 #include "delayedtype.h"
diff --git a/language/duchain/types/pointertype.h b/language/duchain/types/pointertype.h
index deb40ed..b66c374 100644
--- a/language/duchain/types/pointertype.h
+++ b/language/duchain/types/pointertype.h
@@ -37,7 +37,8 @@ class KDEVPLATFORMLANGUAGE_EXPORT PointerType: public AbstractType
 {
 public:
   typedef TypePtr<PointerType> Ptr;
-
+  typedef AbstractType BaseType;
+  
   /// Default constructor
   PointerType ();
   /// Copy constructor. \param rhs type to copy
diff --git a/language/duchain/types/ptrtomembertype.cpp b/language/duchain/types/ptrtomembertype.cpp
new file mode 100644
index 0000000..44fb025
--- /dev/null
+++ b/language/duchain/types/ptrtomembertype.cpp
@@ -0,0 +1,115 @@
+/* This file is part of KDevelop
+ *    Copyright 2006 Roberto Raggi <roberto at kdevelop.org>
+ *    Copyright 2006-2008 Hamish Rodda <rodda at kde.org>
+ *    Copyright 2007-2008 David Nolden <david.nolden.kdevelop at art-master.de>
+ *    Copyright 2010 Floris Ruijter <flo.ruijt at hotmail.com> , adaption of pointertype by above-mentioned authors
+ * 
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Library General Public
+ *   License version 2 as published by the Free Software Foundation.
+ * 
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Library General Public License for more details.
+ * 
+ *   You should have received a copy of the GNU Library General Public License
+ *   along with this library; see the file COPYING.LIB.  If not, write to
+ *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *   Boston, MA 02110-1301, USA.
+ */
+
+#include "ptrtomembertype.h"
+
+#include "../indexedstring.h"
+#include "../repositories/typerepository.h"
+#include "typesystemdata.h"
+#include "typeregister.h"
+#include "typesystem.h"
+
+#include <iostream>
+
+namespace KDevelop
+{
+  
+  REGISTER_TYPE(PtrToMemberType);
+  
+  PtrToMemberType::PtrToMemberType(const PtrToMemberType& rhs) : PointerType(copyData<PtrToMemberType>(*rhs.d_func())) {
+  }
+  
+  PtrToMemberType::PtrToMemberType(PtrToMemberTypeData& data) : PointerType(data) {
+    std::cout << "/|\ ptr-to-member-type constructed FLOW\n";
+  }
+  
+  AbstractType* PtrToMemberType::clone() const {
+    return new PtrToMemberType(*this);
+  }
+  
+  bool PtrToMemberType::equals(const AbstractType* _rhs) const
+  {
+    if( this == _rhs )
+      return true;
+    
+    if (!PointerType::equals(_rhs))
+      return false;
+    
+    Q_ASSERT(fastCast<const PtrToMemberType*>(_rhs));
+    
+    const PtrToMemberType* rhs = static_cast<const PtrToMemberType*>(_rhs);
+    
+    return d_func()->m_classType == rhs->d_func()->m_classType;
+  }
+  
+  PtrToMemberType::PtrToMemberType()
+  : PointerType(createData<PtrToMemberType>())
+  { 
+    std::cout << "ptr-to-member-type constructed FLOW\n";
+  }
+  
+  void PtrToMemberType::accept0 (TypeVisitor *v) const
+  {
+    BaseType::accept0(v);
+    if (v->visit (this))
+      acceptType (d_func()->m_classType.abstractType(), v);
+    v->endVisit (this);
+  }
+  
+  void PtrToMemberType::exchangeTypes( TypeExchanger* exchanger ) {
+    BaseType::exchangeTypes(exchanger);
+    d_func_dynamic()->m_classType = exchanger->exchange( d_func()->m_classType.abstractType() )->indexed();
+  }
+  
+  PtrToMemberType::~PtrToMemberType()
+  {
+  }
+  
+  AbstractType::Ptr PtrToMemberType::ClassType () const
+  {
+    return d_func()->m_classType.abstractType();
+  }
+  
+  void PtrToMemberType::setClassType(AbstractType::Ptr type)
+  {
+    d_func_dynamic()->m_classType = type->indexed();
+  }
+  
+  QString PtrToMemberType::toString() const
+  {
+    QString baseString = (baseType() ? baseType()->toString() : "<notype>");
+    QString classString= (ClassType() ? ClassType()->toString() : "<notype>");
+    return QString("%1 %2::*").arg(baseString).arg(classString) + AbstractType::toString(true);
+  }
+  
+  AbstractType::WhichType PtrToMemberType::whichType() const
+  {
+    return TypePointer; ///FIXME is this okay? didn't seem to fit the other categories.
+  }
+  
+  uint PtrToMemberType::hash() const
+  {
+    return PointerType::hash() + d_func()->m_classType.hash() * 17  ;
+  }
+  
+}
+
+// kate: space-indent on; indent-width 2; tab-width 4; replace-tabs on; auto-insert-doxygen on
diff --git a/language/duchain/types/ptrtomembertype.h b/language/duchain/types/ptrtomembertype.h
new file mode 100644
index 0000000..69d9c8f
--- /dev/null
+++ b/language/duchain/types/ptrtomembertype.h
@@ -0,0 +1,81 @@
+/* This file is part of KDevelop
+ *    Copyright 2006 Roberto Raggi <roberto at kdevelop.org>
+ *    Copyright 2006-2008 Hamish Rodda <rodda at kde.org>
+ *    Copyright 2007-2008 David Nolden <david.nolden.kdevelop at art-master.de>
+ *    Copyright 2010 Floris Ruijter <flo.ruijt at hotmail.com> , adaption of pointertype by above-mentioned authors
+ * 
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Library General Public
+ *   License version 2 as published by the Free Software Foundation.
+ * 
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Library General Public License for more details.
+ * 
+ *   You should have received a copy of the GNU Library General Public License
+ *   along with this library; see the file COPYING.LIB.  If not, write to
+ *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *   Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef PTRTOMEMBERTYPE_H
+#define PTRTOMEMBERTYPE_H
+
+#include "pointertype.h"
+#include "structuretype.h"
+
+namespace KDevelop{
+  class PtrToMemberTypeData;
+  class KDEVPLATFORMLANGUAGE_EXPORT PtrToMemberType : public PointerType
+  {
+  public:
+    typedef TypePtr<PtrToMemberType> Ptr;
+    typedef PointerType BaseType;
+    
+    /// Default constructor
+    PtrToMemberType ();
+    /// Copy constructor. \param rhs type to copy
+    PtrToMemberType(const PtrToMemberType& rhs);
+    /// Constructor using raw data. \param data internal data.
+    PtrToMemberType(PtrToMemberTypeData& data);
+    /// Destructor
+    virtual ~PtrToMemberType();
+    
+    /**
+     * sets the class type, ie. the B of A B::* foo
+     *
+     * \param ClassType : B
+     */
+    void setClassType(AbstractType::Ptr type);
+    
+    AbstractType::Ptr ClassType () const;
+    
+    virtual QString toString() const;
+    
+    virtual uint hash() const;
+    
+    virtual WhichType whichType() const;
+    
+    virtual AbstractType* clone() const;
+    
+    virtual bool equals(const AbstractType* rhs) const;
+    
+    virtual void exchangeTypes( TypeExchanger* exchanger );
+    
+    enum {
+      Identity = 42 ///TODO check uniqueness
+    };
+    
+    typedef PtrToMemberTypeData Data;
+    
+  protected:
+    virtual void accept0 (TypeVisitor *v) const;
+    
+    TYPE_DECLARE_DATA(PtrToMemberType)
+    
+  };
+
+}
+#endif // PTRTOMEMBERTYPE_H
diff --git a/language/duchain/types/typesystem.cpp b/language/duchain/types/typesystem.cpp
index 941e541..05bb203 100644
--- a/language/duchain/types/typesystem.cpp
+++ b/language/duchain/types/typesystem.cpp
@@ -88,6 +88,15 @@ PointerTypeData::PointerTypeData( const PointerTypeData& rhs )
 {
 }
 
+PtrToMemberTypeData::PtrToMemberTypeData() : m_classType(0)
+{
+}
+
+PtrToMemberTypeData::PtrToMemberTypeData( const PtrToMemberTypeData& rhs )
+: PointerTypeData(rhs), m_classType( rhs.m_classType)
+{
+}
+
 ReferenceTypeData::ReferenceTypeData() : m_baseType(0)
 {
 }
diff --git a/language/duchain/types/typesystemdata.h b/language/duchain/types/typesystemdata.h
index 5bf470c..e65e924 100644
--- a/language/duchain/types/typesystemdata.h
+++ b/language/duchain/types/typesystemdata.h
@@ -124,6 +124,18 @@ public:
   IndexedType m_baseType;
 };
 
+/// Private data structure for PtrToMemberType
+class KDEVPLATFORMLANGUAGE_EXPORT PtrToMemberTypeData : public PointerTypeData
+{
+public:
+  /// Constructor
+  PtrToMemberTypeData();
+  /// Copy constructor. \param rhs data to copy
+  PtrToMemberTypeData( const PtrToMemberTypeData& rhs );
+  /// Type of data at which the pointer points
+  IndexedType m_classType;
+};
+
 /// Private data structure for ReferenceType
 class KDEVPLATFORMLANGUAGE_EXPORT ReferenceTypeData : public AbstractTypeData
 {







More information about the KDevelop mailing list