Blob Blame History Raw
diff --git a/languages/cpp/cppduchain/cppduchain.cpp b/languages/cpp/cppduchain/cppduchain.cpp
index 7fd51fb..874cefd 100644
--- a/languages/cpp/cppduchain/cppduchain.cpp
+++ b/languages/cpp/cppduchain/cppduchain.cpp
@@ -426,17 +426,17 @@ QString preprocess( const QString& text, Cpp::EnvironmentFile* file, int line, Q
       DUChainReadLocker lock(DUChain::lock());
     //Copy in all macros from the file
     for( Cpp::ReferenceCountedMacroSet::Iterator it( file->definedMacros().iterator() ); it; ++it ) {
-      if( line == -1 || line > it.ref().sourceLine || file->url() != it.ref().file ) {
-        if(!disableMacros.contains( it.ref().name ))
+      if( line == -1 || line > (*it).sourceLine || file->url() != (*it).file ) {
+        if(!disableMacros.contains( (*it).name ))
         {
-          pp.environment()->setMacro( new rpp::pp_macro(it.ref()) );
+          pp.environment()->setMacro( *it );
         }
       }
     }
     for( Cpp::ReferenceCountedMacroSet::Iterator it( file->usedMacros().iterator() ); it; ++it ) {
-      if( line == -1 || line > it.ref().sourceLine || file->url() != it.ref().file ) {
-        if(!disableMacros.contains( it.ref().name ))
-          pp.environment()->setMacro( new rpp::pp_macro(it.ref()) );
+      if( line == -1 || line > (*it).sourceLine || file->url() != (*it).file ) {
+        if(!disableMacros.contains( (*it).name ))
+          pp.environment()->setMacro( *it );
       }
     }
   }
diff --git a/languages/cpp/cppduchain/cpppreprocessenvironment.cpp b/languages/cpp/cppduchain/cpppreprocessenvironment.cpp
index bb5f72e..774ca2e 100644
--- a/languages/cpp/cppduchain/cpppreprocessenvironment.cpp
+++ b/languages/cpp/cppduchain/cpppreprocessenvironment.cpp
@@ -47,9 +47,9 @@ void CppPreprocessEnvironment::finishEnvironment(bool leaveEnvironmentFile) {
 
 void CppPreprocessEnvironment::removeMacro(const KDevelop::IndexedString& macroName) {
   m_macroNameSet.remove(macroName);
-  rpp::pp_macro* m = new rpp::pp_macro;
-  m->name = macroName;
-  m->defined = false;
+  rpp::pp_macro m;
+  m.name = macroName;
+  m.defined = false;
   rpp::Environment::setMacro(m);
 }
 
@@ -57,20 +57,20 @@ void CppPreprocessEnvironment::removeString(const KDevelop::IndexedString& str)
   m_strings.erase(str.index());
 }
 
-rpp::pp_macro* CppPreprocessEnvironment::retrieveMacro(const KDevelop::IndexedString& name, bool isImportant) const {
+rpp::pp_macro CppPreprocessEnvironment::retrieveMacro(const KDevelop::IndexedString& name, bool isImportant) const {
     //note all strings that can be affected by macros
     if( !m_environmentFile || (onlyRecordImportantMacroUses && !isImportant) )
         return rpp::Environment::retrieveMacro(name, isImportant);
 
   //kDebug() << "retrieving macro" << name.str();
 
-    rpp::pp_macro* ret = rpp::Environment::retrieveMacro(name, isImportant);
+    const rpp::pp_macro& ret = rpp::Environment::retrieveMacro(name, isImportant);
 
-    if( !ret || (!m_environmentFile->definedMacroNames().contains(name) && !m_environmentFile->unDefinedMacroNames().contains(name)) )
+    if( !ret.isValid() || (!m_environmentFile->definedMacroNames().contains(name) && !m_environmentFile->unDefinedMacroNames().contains(name)) )
         m_strings.insert(name.index());
 
-    if( ret )
-        m_environmentFile->usingMacro(*ret);
+    if( ret.isValid() )
+        m_environmentFile->usingMacro(ret);
 
     return ret;
 }
@@ -98,12 +98,13 @@ void CppPreprocessEnvironment::swapMacros( rpp::Environment* parentEnvironment )
   * */
 void CppPreprocessEnvironment::merge( const Cpp::ReferenceCountedMacroSet& macros ) {
     for( Cpp::ReferenceCountedMacroSet::Iterator it(macros.iterator()); it; ++it ) {
-        rpp::Environment::setMacro(const_cast<rpp::pp_macro*>(&it.ref())); //Do not use our overridden setMacro(..), because addDefinedMacro(..) is not needed(macro-sets should be merged separately)
+        const auto& macro = *it;
+        rpp::Environment::setMacro(macro); //Do not use our overridden setMacro(..), because addDefinedMacro(..) is not needed(macro-sets should be merged separately)
 
-        if( !it.ref().isUndef() )
-          m_macroNameSet.insert(it.ref().name);
+        if( !macro.isUndef() )
+          m_macroNameSet.insert(macro.name);
         else
-          m_macroNameSet.remove(it.ref().name);
+          m_macroNameSet.remove(macro.name);
     }
 }
 
@@ -114,7 +115,7 @@ void CppPreprocessEnvironment::merge( const Cpp::EnvironmentFile* file, bool mer
       m_environmentFile->merge(*file);
     
     for( Cpp::ReferenceCountedMacroSet::Iterator it(addedMacros.iterator()); it; ++it )
-      rpp::Environment::setMacro(const_cast<rpp::pp_macro*>(&it.ref())); //Do not use our overridden setMacro(..), because addDefinedMacro(..) is not needed(macro-sets should be merged separately)
+      rpp::Environment::setMacro(*it); //Do not use our overridden setMacro(..), because addDefinedMacro(..) is not needed(macro-sets should be merged separately)
 
     for( Cpp::ReferenceCountedStringSet::Iterator it = file->definedMacroNames().iterator(); it; ++it ) {
       m_macroNameSet.insert(*it);
@@ -122,47 +123,47 @@ void CppPreprocessEnvironment::merge( const Cpp::EnvironmentFile* file, bool mer
 
     //We don't have to care about efficiency too much here, unDefinedMacros should be a rather small set
     for( Cpp::ReferenceCountedStringSet::Iterator it = file->unDefinedMacroNames().iterator(); it; ++it ) {
-        rpp::pp_macro* m = new rpp::pp_macro(*it);
-        m->defined = false;
-        m->m_valueHashValid = false;
+        rpp::pp_macro m(*it);
+        m.defined = false;
+        m.m_valueHashValid = false;
         rpp::Environment::setMacro(m); //Do not use our overridden setMacro(..), because addDefinedMacro(..) is not needed(macro-sets should be merged separately)
         m_macroNameSet.remove(*it);
     }
 }
 
-void CppPreprocessEnvironment::setMacro(rpp::pp_macro* macro) {
-    rpp::pp_macro* hadMacro = retrieveStoredMacro(macro->name);
+void CppPreprocessEnvironment::setMacro(const rpp::pp_macro& macro) {
+    const rpp::pp_macro& hadMacro = retrieveStoredMacro(macro.name);
 
-    if(hadMacro && hadMacro->fixed) {
-      if(hadMacro->defineOnOverride && (hadMacro->file.isEmpty() ||
-          (macro->file.length() >= hadMacro->file.length() &&
-           memcmp(macro->file.c_str() + (macro->file.length() - hadMacro->file.length()), 
-                         hadMacro->file.c_str(),
-                         hadMacro->file.length()) == 0)))
+    if(hadMacro.isValid() && hadMacro.fixed) {
+      if(hadMacro.defineOnOverride && (hadMacro.file.isEmpty() ||
+          (macro.file.length() >= hadMacro.file.length() &&
+           memcmp(macro.file.c_str() + (macro.file.length() - hadMacro.file.length()),
+                         hadMacro.file.c_str(),
+                         hadMacro.file.length()) == 0)))
       {
         // We have to define the macro now, as it is being overridden
-        rpp::pp_macro* definedMacro = new rpp::pp_macro(*hadMacro);
-        definedMacro->defined = true;
-        if(!macro->isRepositoryMacro())
-          delete macro;
-        macro = definedMacro;
+        rpp::pp_macro definedMacro = hadMacro;
+        definedMacro.defined = true;
+        setMacro(definedMacro, hadMacro);
       }else{
         // A fixed macro exists, simply ignore the added macro
-        if(!macro->isRepositoryMacro())
-          delete macro;
         return;
       }
     }
 
+    setMacro(macro, hadMacro);
+}
+
+void CppPreprocessEnvironment::setMacro(const rpp::pp_macro& macro, const rpp::pp_macro& hadMacro) {
   //kDebug() << "setting macro" << macro->name.str() << "with body" << macro->definition << "is undef:" << macro->isUndef();
     //Note defined macros
     if( m_environmentFile )
-      m_environmentFile->addDefinedMacro(*macro, hadMacro);
+      m_environmentFile->addDefinedMacro(macro, hadMacro);
 
-    if( !macro->isUndef() )
-      m_macroNameSet.insert(macro->name);
+    if( !macro.isUndef() )
+      m_macroNameSet.insert(macro.name);
     else
-      m_macroNameSet.remove(macro->name);
+      m_macroNameSet.remove(macro.name);
 
     rpp::Environment::setMacro(macro);
 }
diff --git a/languages/cpp/cppduchain/cpppreprocessenvironment.h b/languages/cpp/cppduchain/cpppreprocessenvironment.h
index 21fe915..14e0c01 100644
--- a/languages/cpp/cppduchain/cpppreprocessenvironment.h
+++ b/languages/cpp/cppduchain/cpppreprocessenvironment.h
@@ -37,7 +37,7 @@ public:
   ///@param leaveEnvironmentFile Whether the environment-file should be left untouched
   void finishEnvironment(bool leaveEnvironmentFile = false);
 
-  virtual rpp::pp_macro* retrieveMacro( const KDevelop::IndexedString& name, bool isImportant ) const;
+  virtual rpp::pp_macro retrieveMacro( const KDevelop::IndexedString& name, bool isImportant ) const;
 
   void setEnvironmentFile( const KSharedPtr<Cpp::EnvironmentFile>& environmentFile );
   KSharedPtr<Cpp::EnvironmentFile> environmentFile() const;
@@ -53,7 +53,7 @@ public:
   ///@param mergeEnvironments Whether the environment-files should also be merged using Cpp::EnvironmentFile::merge
   void merge( const Cpp::EnvironmentFile* file, bool mergeEnvironments = false );
 
-  virtual void setMacro(rpp::pp_macro* macro);
+  virtual void setMacro(const rpp::pp_macro& macro);
 
   virtual int type() const;
 
@@ -83,6 +83,8 @@ public:
   static void setRecordOnlyImportantString(bool);
   
 private:
+    void setMacro(const rpp::pp_macro& macro, const rpp::pp_macro& hadMacro);
+
     uint m_identityOffsetRestriction;
     bool m_identityOffsetRestrictionEnabled;
     bool m_finished;
diff --git a/languages/cpp/cppduchain/environmentmanager.cpp b/languages/cpp/cppduchain/environmentmanager.cpp
index f881420..51f51a4 100644
--- a/languages/cpp/cppduchain/environmentmanager.cpp
+++ b/languages/cpp/cppduchain/environmentmanager.cpp
@@ -170,7 +170,7 @@ QString print(const Cpp::ReferenceCountedMacroSet& set) {
       ret += ", ";
     first = false;
     
-    ret += it.ref().toString();
+    ret += (*it).toString();
     ++it;
   }
   return ret;
@@ -235,12 +235,12 @@ bool EnvironmentFile::matchEnvironment(const ParsingEnvironment* _environment) c
     if (!environmentMacroNames.contains( *it )) {
       continue;
     }
-    rpp::pp_macro* m = cppEnvironment->retrieveStoredMacro( *it );
-    if(m && !m->isUndef()) {
+    const rpp::pp_macro& m = cppEnvironment->retrieveStoredMacro( *it );
+    if(m.isValid() && !m.isUndef()) {
       
 #ifdef DEBUG_LEXERCACHE
       if(debugging()) {
-        kDebug(9007) << "The environment contains a macro that can affect the cached file, but that should not exist:" << m->name.str();
+        kDebug(9007) << "The environment contains a macro that can affect the cached file, but that should not exist:" << m.name.str();
       }
 #endif
       return false;
@@ -254,19 +254,20 @@ bool EnvironmentFile::matchEnvironment(const ParsingEnvironment* _environment) c
   ifDebug( kDebug(9007) << "Count of used macros that need to be verified:" << d_func()->m_usedMacros.set().count() );
 
   for ( ReferenceCountedMacroSet::Iterator it( d_func()->m_usedMacros.iterator() ); it; ++it ) {
-    rpp::pp_macro* m = cppEnvironment->retrieveStoredMacro( it.ref().name );
-    if ( !m || !(*m == it.ref()) ) {
-      if( !m && it.ref().isUndef() ) {
-        ifDebug( kDebug( 9007 ) << "Undef-macro" << it.ref().name.str() << "is ok" << m );
+    const auto& macro = *it;
+    const auto& m = cppEnvironment->retrieveStoredMacro( macro.name );
+    if ( !m.isValid() || m != macro ) {
+      if( !m.isValid() && macro.isUndef() ) {
+        ifDebug( kDebug( 9007 ) << "Undef-macro" << macro.name.str() << "is ok" << m );
         //It is okay, we did not find a macro, but the used macro is an undef macro
         //Q_ASSERT(0); //Undef-macros should not be marked as used
       } else {
-        ifDebug( kDebug( 9007 ) << "The cached file " << url().str() << " used a macro called \"" << it.ref().name.str() << "\"(from" << it.ref().file.str() << "), but the environment" << (m ? "contains differing macro of that name" : "does not contain that macro") << ", the cached file is not used"  );
-        ifDebug( if(m) { kDebug() << "Used macro: " << it.ref().toString()  << "from" << it.ref().file.str() << "found:" << m->toString() << "from" << m->file.str(); } );
+        ifDebug( kDebug( 9007 ) << "The cached file " << url().str() << " used a macro called \"" << macro.name.str() << "\"(from" << macro.file.str() << "), but the environment" << (m ? "contains differing macro of that name" : "does not contain that macro") << ", the cached file is not used"  );
+        ifDebug( if(m) { kDebug() << "Used macro: " << macro.toString()  << "from" << macro.file.str() << "found:" << m->toString() << "from" << m->file.str(); } );
         return false;
       }
     }else{
-      ifDebug( kDebug( 9007 ) << it.ref().name.str() << "match" );
+      ifDebug( kDebug( 9007 ) << macro.name.str() << "match" );
     }
   }
 
@@ -329,22 +330,24 @@ int EnvironmentFile::contentStartLine() const {
   return d_func()->m_contentStartLine;
 }
 
-void EnvironmentFile::addDefinedMacro( const rpp::pp_macro& macro, const rpp::pp_macro* previousOfSameName ) {
+void EnvironmentFile::addDefinedMacro( const rpp::pp_macro& macro, const rpp::pp_macro& previousOfSameName ) {
   ENSURE_WRITE_LOCKED
 #ifdef DEBUG_LEXERCACHE
   if(debugging()) {
   kDebug( 9007 )  << id(this) << "defined macro" << macro.name.str();
   }
 #endif
-  if( previousOfSameName && d_func()->m_definedMacros.contains(*previousOfSameName) )
-    d_func_dynamic()->m_definedMacros.remove( *previousOfSameName );
+  if( previousOfSameName.isValid() && d_func()->m_definedMacros.contains(previousOfSameName) )
+    d_func_dynamic()->m_definedMacros.remove( previousOfSameName );
   else if( d_func()->m_definedMacroNames.contains(macro.name) ) {
     //Search if there is already a macro of the same name in the set, and remove it
     //This is slow, but should not happen too often
     ///@todo maybe give a warning, and find out how this can happen
-    for( ReferenceCountedMacroSet::Iterator it( d_func()->m_definedMacros.iterator() ); it; ++it )
-      if( macro.name == it.ref().name )
-        d_func_dynamic()->m_definedMacros.remove(it.ref());
+    for( ReferenceCountedMacroSet::Iterator it( d_func()->m_definedMacros.iterator() ); it; ++it ) {
+      const auto& m = *it;
+      if( macro.name == m.name )
+        d_func_dynamic()->m_definedMacros.remove(m);
+    }
   }
   
   if(macro.isUndef()) {
@@ -520,7 +523,7 @@ void EnvironmentFile::merge( const EnvironmentFile& file ) {
     Q_ASSERT(backup.set().setIndex() == file.d_func()->m_usedMacros.set().setIndex());
     
     for(ReferenceCountedMacroSet::Iterator it( file.d_func()->m_usedMacros.iterator() ); it; ++it) {
-      const rpp::pp_macro& macro(it.ref());
+      const auto& macro = *it;
       if( !definedMacroNamesSet.contains(macro.name.index()) && !unDefinedMacroNamesSet.contains(macro.name.index()) )
         addUsedMacros.insert(it.index());
     }
@@ -563,8 +566,7 @@ void EnvironmentFile::merge( const EnvironmentFile& file ) {
     if(!affectedMacros.isEmpty()) {
       //We have to iterate through all potentially removed macros
       for( ReferenceCountedMacroSet::Iterator it( potentiallyRemoveMacros.iterator() ); it; ++it ) {
-        const rpp::pp_macro& macro(it.ref());
-        if( affectedMacros.contains( macro.name ) )
+        if( affectedMacros.contains( (*it).name ) )
           removeDefinedMacros.insert(it.index());
       }
     }
diff --git a/languages/cpp/cppduchain/environmentmanager.h b/languages/cpp/cppduchain/environmentmanager.h
index 0ed17ca..213eb6c 100644
--- a/languages/cpp/cppduchain/environmentmanager.h
+++ b/languages/cpp/cppduchain/environmentmanager.h
@@ -103,7 +103,6 @@ The good things:
 
 namespace rpp {
   class pp_macro;
-  class pp_macro;
   class Environment;
 }
 
@@ -217,7 +216,7 @@ class KDEVCPPDUCHAIN_EXPORT EnvironmentFile : public KDevelop::ParsingEnvironmen
     void addStrings( const std::set<Utils::BasicSetRepository::Index>& strings );
 
     ///If there previously was a macro defined of the same name, it must be given through previousOfSameName, else it can be zero.
-    void addDefinedMacro( const rpp::pp_macro& macro, const rpp::pp_macro* previousOfSameName );
+    void addDefinedMacro( const rpp::pp_macro& macro, const rpp::pp_macro& previousOfSameName );
 
     ///the given macro will only make it into usedMacros() if it was not defined in this file
     void usingMacro( const rpp::pp_macro& macro );
diff --git a/languages/cpp/cppduchain/tests/testenvironment.cpp b/languages/cpp/cppduchain/tests/testenvironment.cpp
index 00d0a34..5f0c410 100644
--- a/languages/cpp/cppduchain/tests/testenvironment.cpp
+++ b/languages/cpp/cppduchain/tests/testenvironment.cpp
@@ -57,16 +57,16 @@ void TestEnvironment::benchMerge()
     rpp::pp_macro m1(IndexedString(QString("my1Macro%1").arg(i)));
     rpp::pp_macro m2(IndexedString(QString("my2Macro%1").arg(i)));
     // define the two in the files
-    f1.addDefinedMacro(m1, 0);
-    f2.addDefinedMacro(m2, 0);
+    f1.addDefinedMacro(m1, {});
+    f2.addDefinedMacro(m2, {});
     // undef them in the other file
     m1.defined = false;
     m2.defined = false;
-    f1.addDefinedMacro(m2, 0);
-    f2.addDefinedMacro(m1, 0);
+    f1.addDefinedMacro(m2, {});
+    f2.addDefinedMacro(m1, {});
     // and add some other macros
-    f1.addDefinedMacro(rpp::pp_macro(IndexedString(QString("my1UntouchedMacro%1").arg(i))), 0);
-    f2.addDefinedMacro(rpp::pp_macro(IndexedString(QString("my2UntouchedMacro%1").arg(i))), 0);
+    f1.addDefinedMacro(rpp::pp_macro(IndexedString(QString("my1UntouchedMacro%1").arg(i))), {});
+    f2.addDefinedMacro(rpp::pp_macro(IndexedString(QString("my2UntouchedMacro%1").arg(i))), {});
   }
   const IndexedString file(QLatin1String("f3"));
   QBENCHMARK {
diff --git a/languages/cpp/cpplanguagesupport.cpp b/languages/cpp/cpplanguagesupport.cpp
index afa2dc8..c308148 100644
--- a/languages/cpp/cpplanguagesupport.cpp
+++ b/languages/cpp/cpplanguagesupport.cpp
@@ -722,12 +722,12 @@ QPair<TopDUContextPointer, SimpleRange> CppLanguageSupport::importedContextForPo
   return qMakePair(TopDUContextPointer(), SimpleRange::invalid());
 }
 
-QPair<SimpleRange, const rpp::pp_macro*> CppLanguageSupport::usedMacroForPosition(const KUrl& url, const SimpleCursor& position) {
+QPair<SimpleRange, rpp::pp_macro> CppLanguageSupport::usedMacroForPosition(const KUrl& url, const SimpleCursor& position) {
   //Extract the word under the cursor
 
   QPair<QPair<QString, SimpleRange>, QString> found = cursorIdentifier(url, position);
   if(!found.first.second.isValid())
-    return qMakePair(SimpleRange::invalid(), (const rpp::pp_macro*)0);
+    return qMakePair(SimpleRange::invalid(), rpp::pp_macro());
 
   IndexedString word(found.first.first);
   SimpleRange wordRange(found.first.second);
@@ -736,38 +736,40 @@ QPair<SimpleRange, const rpp::pp_macro*> CppLanguageSupport::usedMacroForPositio
   DUChainReadLocker lock(DUChain::lock(), 100);
   if(!lock.locked()) {
     kDebug(9007) << "Failed to lock the du-chain in time";
-    return qMakePair(SimpleRange::invalid(), (const rpp::pp_macro*)0);
+    return qMakePair(SimpleRange::invalid(), rpp::pp_macro());
   }
 
   TopDUContext* ctx = standardContext(url, true);
   if(word.str().isEmpty() || !ctx || !ctx->parsingEnvironmentFile())
-    return qMakePair(SimpleRange::invalid(), (const rpp::pp_macro*)0);
+    return qMakePair(SimpleRange::invalid(), rpp::pp_macro());
 
   Cpp::EnvironmentFilePointer p(dynamic_cast<Cpp::EnvironmentFile*>(ctx->parsingEnvironmentFile().data()));
 
   Q_ASSERT(p);
 
   if(!p->usedMacroNames().contains(word) && !p->definedMacroNames().contains(word))
-    return qMakePair(SimpleRange::invalid(), (const rpp::pp_macro*)0);
+    return qMakePair(SimpleRange::invalid(), rpp::pp_macro());
 
   //We need to do a flat search through all macros here, which really hurts
 
   Cpp::ReferenceCountedMacroSet::Iterator it = p->usedMacros().iterator();
 
   while(it) {
-    if(it.ref().name == word && !it.ref().isUndef())
-      return qMakePair(wordRange, &it.ref());
+    const auto& macro = *it;
+    if(macro.name == word && !macro.isUndef())
+      return qMakePair(wordRange, macro);
     ++it;
   }
 
   it = p->definedMacros().iterator();
   while(it) {
-    if(it.ref().name == word && !it.ref().isUndef())
-      return qMakePair(wordRange, &it.ref());
+    const auto& macro = *it;
+    if(macro.name == word && !macro.isUndef())
+      return qMakePair(wordRange, macro);
     ++it;
   }
 
-  return qMakePair(SimpleRange::invalid(), (const rpp::pp_macro*)0);
+  return qMakePair(SimpleRange::invalid(), rpp::pp_macro());
 }
 
 SimpleRange CppLanguageSupport::specialLanguageObjectRange(const KUrl& url, const SimpleCursor& position) {
@@ -788,12 +790,12 @@ QPair<KUrl, KDevelop::SimpleCursor> CppLanguageSupport::specialLanguageObjectJum
         return qMakePair(KUrl(import.first->url().str()), SimpleCursor(0,0));
     }
 
-    QPair<SimpleRange, const rpp::pp_macro*> m = usedMacroForPosition(url, position);
+    const QPair<SimpleRange, rpp::pp_macro>& m = usedMacroForPosition(url, position);
 
     if(!m.first.isValid())
       return qMakePair(KUrl(), SimpleCursor::invalid());
 
-    return qMakePair(KUrl(m.second->file.str()), SimpleCursor(m.second->sourceLine, 0));
+    return qMakePair(KUrl(m.second.file.str()), SimpleCursor(m.second.sourceLine, 0));
 }
 
 QWidget* CppLanguageSupport::specialLanguageObjectNavigationWidget(const KUrl& url, const SimpleCursor& position) {
@@ -814,7 +816,7 @@ QWidget* CppLanguageSupport::specialLanguageObjectNavigationWidget(const KUrl& u
       }
     }
 
-    QPair<SimpleRange, const rpp::pp_macro*> m = usedMacroForPosition(url, position);
+    const QPair<SimpleRange, rpp::pp_macro>& m = usedMacroForPosition(url, position);
     if(!m.first.isValid())
       return 0;
 
@@ -862,12 +864,12 @@ QWidget* CppLanguageSupport::specialLanguageObjectNavigationWidget(const KUrl& u
       preprocessedBody = i->formatSourceWithStyle(style, preprocessedBody, KUrl(), mime);
     }
 
-    return new Cpp::NavigationWidget(*m.second, preprocessedBody);
+    return new Cpp::NavigationWidget(m.second, preprocessedBody);
 }
 
-bool CppLanguageSupport::isFunctionLike(const rpp::pp_macro* pm, const KUrl& url)
+bool CppLanguageSupport::isFunctionLike(const rpp::pp_macro& pm, const KUrl& url)
 {
-  if(pm->function_like)
+  if(pm.function_like)
     return true;
 
   DUChainReadLocker lock(DUChain::lock(), 100);
@@ -883,7 +885,7 @@ bool CppLanguageSupport::isFunctionLike(const rpp::pp_macro* pm, const KUrl& url
   Cpp::EnvironmentFilePointer p(dynamic_cast<Cpp::EnvironmentFile*>(ctx->parsingEnvironmentFile().data()));
 
   Q_ASSERT(p);
-  QByteArray strdef = stringFromContents((uint*)pm->definition(), pm->definitionSize()).trimmed();
+  QByteArray strdef = stringFromContents((uint*)pm.definition(), pm.definitionSize()).trimmed();
 
   Cpp::ReferenceCountedMacroSet::Iterator it = p->usedMacros().iterator();
 
diff --git a/languages/cpp/cpplanguagesupport.h b/languages/cpp/cpplanguagesupport.h
index 92cbd7c..43d1571 100644
--- a/languages/cpp/cpplanguagesupport.h
+++ b/languages/cpp/cpplanguagesupport.h
@@ -150,7 +150,7 @@ private:
 
     QPair<KDevelop::TopDUContextPointer, KDevelop::SimpleRange> importedContextForPosition(const KUrl& url, const KDevelop::SimpleCursor& position);
 
-    QPair<KDevelop::SimpleRange, const rpp::pp_macro*> usedMacroForPosition(const KUrl& url, const KDevelop::SimpleCursor& position);
+    QPair<KDevelop::SimpleRange, rpp::pp_macro> usedMacroForPosition(const KUrl& url, const KDevelop::SimpleCursor& position);
 
     virtual KDevelop::SimpleRange specialLanguageObjectRange(const KUrl& url, const KDevelop::SimpleCursor& position);
 
@@ -158,7 +158,7 @@ private:
 
     virtual QWidget* specialLanguageObjectNavigationWidget(const KUrl& url, const KDevelop::SimpleCursor& position);
 
-    bool isFunctionLike(const rpp::pp_macro* pm, const KUrl& url);
+    bool isFunctionLike(const rpp::pp_macro& pm, const KUrl& url);
 
     static CppLanguageSupport* m_self;
 
diff --git a/languages/cpp/cppparsejob.cpp b/languages/cpp/cppparsejob.cpp
index 380722f..381eb43 100644
--- a/languages/cpp/cppparsejob.cpp
+++ b/languages/cpp/cppparsejob.cpp
@@ -229,8 +229,8 @@ void CPPParseJob::mergeDefines(CppPreprocessEnvironment& env) const
   
   for(QHash<QString, QString>::const_iterator it = defines.constBegin(); it != defines.constEnd(); ++it)
   {
-    rpp::pp_macro* m = new rpp::pp_macro(IndexedString(it.key()));
-    m->setDefinitionText( *it );
+    rpp::pp_macro m(IndexedString(it.key()));
+    m.setDefinitionText( *it );
     
     //Call rpp::Environment::setMacro directly, so we don't add the macro to the environment-file.
     //It should be only part of the environment.
diff --git a/languages/cpp/parser/rpp/pp-engine.cpp b/languages/cpp/parser/rpp/pp-engine.cpp
index d0e9b73..93caed1 100644
--- a/languages/cpp/parser/rpp/pp-engine.cpp
+++ b/languages/cpp/parser/rpp/pp-engine.cpp
@@ -310,16 +310,16 @@ void pp::createProblem(Stream& input, const QString& description) {
 
 void pp::handle_define (Stream& input)
 {
-  pp_macro* macro = new pp_macro;
-  macro->file = currentFileName();
-  macro->sourceLine = input.originalInputPosition().line;
+  pp_macro macro;
+  macro.file = currentFileName();
+  macro.sourceLine = input.originalInputPosition().line;
 
   skip_blanks (input, devnull());
-  macro->name = KDevelop::IndexedString::fromIndex(skip_identifier(input, true)); //@todo make macros utf8 too
+  macro.name = KDevelop::IndexedString::fromIndex(skip_identifier(input, true)); //@todo make macros utf8 too
 
   if (!input.atEnd() && input == '(')
   {
-    macro->function_like = true;
+    macro.function_like = true;
 
     skip_blanks (++input, devnull()); // skip '('
     uint formal = skip_identifier(input);
@@ -327,15 +327,15 @@ void pp::handle_define (Stream& input)
     skip_blanks(input, devnull());
 
     if (input == '.') {
-      macro->variadics = true;
+      macro.variadics = true;
 
       do {
         ++input;
 
       } while (input == '.');
     }
-    if (formal && !macro->variadics)
-      macro->formalsList().append( KDevelop::IndexedString::fromIndex(formal) );
+    if (formal && !macro.variadics)
+      macro.formalsList().append( KDevelop::IndexedString::fromIndex(formal) );
 
 
     while (!input.atEnd() && input == ',')
@@ -347,7 +347,7 @@ void pp::handle_define (Stream& input)
       skip_blanks (input, devnull());
 
       if (input == '.') {
-        macro->variadics = true;
+        macro.variadics = true;
 
         do {
           ++input;
@@ -355,8 +355,8 @@ void pp::handle_define (Stream& input)
         } while (input == '.');
       }
 
-      if (formal && !macro->variadics)
-        macro->formalsList().append( KDevelop::IndexedString::fromIndex(formal) );
+      if (formal && !macro.variadics)
+        macro.formalsList().append( KDevelop::IndexedString::fromIndex(formal) );
     }
 
     RETURN_ON_FAIL(input == ')');
@@ -381,7 +381,7 @@ void pp::handle_define (Stream& input)
       if (!input.atEnd() && input == '\n')
       {
         skip_blanks(++input, devnull());
-        macro->definitionList().append(KDevelop::IndexedString::fromIndex(indexFromCharacter(' ')));
+        macro.definitionList().append(KDevelop::IndexedString::fromIndex(indexFromCharacter(' ')));
         continue;
 
       } else {
@@ -394,24 +394,24 @@ void pp::handle_define (Stream& input)
       do {
         if (input == '\\' && input.peekNextCharacter() == '"') {
           // skip escaped close quote
-          macro->definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
+          macro.definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
           ++input;
           if(input.atEnd())
             break;
         }
-        macro->definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
+        macro.definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
         ++input;
       } while (!input.atEnd() && input != '"' && input != '\n');
 
       if(!input.atEnd())
       {
-        macro->definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
+        macro.definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
         ++input;
       }
       continue;
     }
 
-    macro->definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
+    macro.definitionList().append(KDevelop::IndexedString::fromIndex(input.current()));
     ++input;
   }
 
@@ -505,8 +505,8 @@ Value pp::eval_primary(Stream& input)
       }
 
       {
-        pp_macro* m = m_environment->retrieveMacro(token_text, true);
-        result.set_long( (m && !m->isUndef()) ? 1 : 0);
+        const pp_macro& m = m_environment->retrieveMacro(token_text, true);
+        result.set_long(m.isUndef() ? 0 : 1);
       }
 
       token = next_token(input); // skip '('
@@ -1009,9 +1009,9 @@ void pp::handle_ifdef (bool check_undefined, Stream& input)
   
   if (test_if_level())
   {
-    pp_macro* macro = m_environment->retrieveMacro(macro_name, true);
+    const pp_macro& macro = m_environment->retrieveMacro(macro_name, true);
     bool value = false;
-    if( macro && macro->defined && !(macro->file == currentFileName() && macro->sourceLine > input.originalInputPosition().line))
+    if( macro.isValid() && macro.defined && !(macro.file == currentFileName() && macro.sourceLine > input.originalInputPosition().line))
       value = true;
 
     if (check_undefined)
@@ -1030,12 +1030,12 @@ void pp::handle_undef(Stream& input)
   KDevelop::IndexedString macro_name = KDevelop::IndexedString::fromIndex(skip_identifier(input));
   RETURN_ON_FAIL(!macro_name.isEmpty());
 
-  pp_macro* macro = new pp_macro;
-  macro->file = currentFileName();
-  macro->name = macro_name;
-  macro->sourceLine = input.originalInputPosition().line;
+  pp_macro macro;
+  macro.file = currentFileName();
+  macro.name = macro_name;
+  macro.sourceLine = input.originalInputPosition().line;
 
-  macro->defined = false;
+  macro.defined = false;
 
   m_environment->setMacro(macro);
 }
diff --git a/languages/cpp/parser/rpp/pp-environment.cpp b/languages/cpp/parser/rpp/pp-environment.cpp
index 4d84eb5..b11fd73 100644
--- a/languages/cpp/parser/rpp/pp-environment.cpp
+++ b/languages/cpp/parser/rpp/pp-environment.cpp
@@ -40,8 +40,6 @@ Environment::Environment()
 Environment::~Environment()
 {
   delete m_locationTable;
-  foreach(pp_macro* macro, m_ownedMacros)
-    delete macro;
 }
 
 LocationTable* Environment::locationTable() const
@@ -58,8 +56,6 @@ LocationTable* Environment::takeLocationTable()
 
 void Environment::swapMacros( Environment* parentEnvironment ) {
   qSwap(m_environment, parentEnvironment->m_environment);
-
-  qSwap(m_ownedMacros, parentEnvironment->m_ownedMacros);
 }
 
 void Environment::clearMacro(const KDevelop::IndexedString& name)
@@ -67,34 +63,31 @@ void Environment::clearMacro(const KDevelop::IndexedString& name)
   m_environment.remove(name);
 }
 
-void Environment::setMacro(pp_macro* macro)
+void Environment::setMacro(const pp_macro& macro)
 {
-  if(!macro->isRepositoryMacro())
-    m_ownedMacros.append(macro);
-
-  m_environment.insert(macro->name, macro);
+  m_environment.insert(macro.name, macro);
 }
 
-void Environment::insertMacro(pp_macro* macro)
+void Environment::insertMacro(const pp_macro& macro)
 {
-  m_environment.insert(macro->name, macro);
+  m_environment.insert(macro.name, macro);
 }
 
 const Environment::EnvironmentMap& Environment::environment() const {
   return m_environment;
 }
 
-pp_macro* Environment::retrieveStoredMacro(const KDevelop::IndexedString& name) const
+pp_macro Environment::retrieveStoredMacro(const KDevelop::IndexedString& name) const
 {
-  return m_environment.value(name, nullptr);
+  return m_environment.value(name);
 }
 
-pp_macro* Environment::retrieveMacro(const KDevelop::IndexedString& name, bool /*isImportant*/) const
+pp_macro Environment::retrieveMacro(const KDevelop::IndexedString& name, bool /*isImportant*/) const
 {
   return retrieveStoredMacro(name);
 }
 
-QList<pp_macro*> Environment::allMacros() const
+QList<pp_macro> Environment::allMacros() const
 {
   return m_environment.values();
 }
diff --git a/languages/cpp/parser/rpp/pp-environment.h b/languages/cpp/parser/rpp/pp-environment.h
index 328dc70..33cea66 100644
--- a/languages/cpp/parser/rpp/pp-environment.h
+++ b/languages/cpp/parser/rpp/pp-environment.h
@@ -27,7 +27,7 @@
 
 #include <QStack>
 #include <cppparserexport.h>
-// #include "pp-macro.h"
+#include "pp-macro.h"
 
 namespace KDevelop {
   class IndexedString;
@@ -35,13 +35,12 @@ namespace KDevelop {
 
 namespace rpp {
 
-class pp_macro;
 class LocationTable;
 
 class KDEVCPPRPP_EXPORT Environment
 {
 public:
-  typedef QHash<KDevelop::IndexedString, pp_macro*> EnvironmentMap;
+  typedef QHash<KDevelop::IndexedString, pp_macro> EnvironmentMap;
 
   Environment();
   virtual ~Environment();
@@ -50,19 +49,19 @@ public:
 
   //The macro will be owned by the environment object
   //Note: Undef-macros are allowed too
-  virtual void setMacro(pp_macro* macro);
+  virtual void setMacro(const pp_macro& macro);
 
   //Inserts a macro that will not be explicitly owned by the Environment,
   //without notifying subclasses etc.
-  void insertMacro(pp_macro* macro);
+  void insertMacro(const pp_macro& macro);
   
-  virtual pp_macro* retrieveMacro(const KDevelop::IndexedString& name, bool isImportant) const;
+  virtual pp_macro retrieveMacro(const KDevelop::IndexedString& name, bool isImportant) const;
   
   //Returns macros that are really stored locally(retrieveMacro may be overridden to perform more complex actions)
-  pp_macro* retrieveStoredMacro(const KDevelop::IndexedString& name) const;
+  pp_macro retrieveStoredMacro(const KDevelop::IndexedString& name) const;
   
   //Returns all currently visible macros
-  QList<pp_macro*> allMacros() const;
+  QList<pp_macro> allMacros() const;
 
   //Swap the macros with the given environment, includign ownership
   virtual void swapMacros( Environment* parentEnvironment );
@@ -76,7 +75,6 @@ public:
 private:
   EnvironmentMap m_environment;
 
-  QVector<pp_macro*> m_ownedMacros;
   LocationTable* m_locationTable;
 };
 
diff --git a/languages/cpp/parser/rpp/pp-macro-expander.cpp b/languages/cpp/parser/rpp/pp-macro-expander.cpp
index a1cce4e..6460a79 100644
--- a/languages/cpp/parser/rpp/pp-macro-expander.cpp
+++ b/languages/cpp/parser/rpp/pp-macro-expander.cpp
@@ -79,7 +79,7 @@ void trim(QVector<uint>& array) {
 
 using namespace rpp;              
 
-pp_frame::pp_frame(pp_macro* __expandingMacro, const QList<pp_actual>& __actuals)
+pp_frame::pp_frame(const pp_macro& __expandingMacro, const QList<pp_actual>& __actuals)
   : depth(0)
   , expandingMacro(__expandingMacro)
   , actuals(__actuals)
@@ -91,10 +91,8 @@ pp_actual pp_macro_expander::resolve_formal(const IndexedString& name, Stream& i
   if (!m_frame)
     return pp_actual();
 
-  Q_ASSERT(m_frame->expandingMacro != 0);
-
-  const IndexedString* formals = m_frame->expandingMacro->formals();
-  uint formalsSize = m_frame->expandingMacro->formalsSize();
+  const IndexedString* formals = m_frame->expandingMacro.formals();
+  uint formalsSize = m_frame->expandingMacro.formalsSize();
 
   if(name.isEmpty()) {
     KDevelop::ProblemPointer problem(new KDevelop::Problem);
@@ -122,7 +120,7 @@ pp_actual pp_macro_expander::resolve_formal(const IndexedString& name, Stream& i
   return pp_actual();
 }
 
-#define RETURN_IF_INPUT_BROKEN    if(input.atEnd()) { kDebug() << "too early end while expanding" << macro->name.str(); return; }
+#define RETURN_IF_INPUT_BROKEN    if(input.atEnd()) { kDebug() << "too early end while expanding" << macro.name.str(); return; }
 
 
 pp_macro_expander::pp_macro_expander(pp* engine, pp_frame* frame, bool inHeaderSection, bool has_if)
@@ -170,18 +168,20 @@ struct EnableMacroExpansion {
 //A helper class that temporary hides a macro in the environment
 class MacroHider {
   public:
-  MacroHider(pp_macro* macro, Environment* environment) : m_macro(macro), m_environment(environment) {
-    
-    m_hideMacro.name = macro->name;
+  MacroHider(const pp_macro& macro, Environment* environment)
+    : m_macro(macro), m_environment(environment)
+  {
+    m_hideMacro.name = macro.name;
     m_hideMacro.hidden = true;
-    environment->insertMacro(&m_hideMacro);
+    environment->insertMacro(m_hideMacro);
   }
-  ~MacroHider() {
+  ~MacroHider()
+  {
     m_environment->insertMacro(m_macro);
   }
   private:
     pp_macro m_hideMacro;
-    pp_macro* m_macro;
+    const pp_macro& m_macro;
     Environment* m_environment;
 };
 
@@ -368,18 +368,18 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
           continue;
         }
         if(m_has_if && m_has_defined){
-          pp_macro* macro = m_engine->environment()->retrieveMacro(name, true);
+          const pp_macro& macro = m_engine->environment()->retrieveMacro(name, false);
           unsigned int value = 0;
-          if(macro && macro->defined)
+          if( macro.isValid() && macro.defined )
             value = 1;
           output.appendString(inputPosition, convertFromByteArray(QByteArray::number(value)));
           m_has_defined = false;
           continue;
         }
 
-        pp_macro* macro = m_engine->environment()->retrieveMacro(name, false);
+        const pp_macro& macro = m_engine->environment()->retrieveMacro(name, false);
 
-        if (!macro || !macro->defined || macro->hidden || macro->function_like || m_engine->hideNextMacro())
+        if (!macro.isValid() || !macro.defined || macro.hidden || macro.function_like || m_engine->hideNextMacro())
         {
           static const IndexedString lineIndex = IndexedString("__LINE__");
           static const IndexedString fileIndex = IndexedString("__FILE__");
@@ -416,13 +416,13 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
         
         EnableMacroExpansion enable(output, input.inputPosition()); //Configure the output-stream so it marks all stored input-positions as transformed through a macro
 
-          if (macro->definitionSize()) {
+          if (macro.definitionSize()) {
             //Hide the expanded macro to prevent endless expansion
             MacroHider hideMacro(macro, m_engine->environment());
             
             pp_macro_expander expand_macro(m_engine);
             ///@todo UGLY conversion
-            Stream ms((uint*)macro->definition(), macro->definitionSize(), Anchor(input.inputPosition(), true));
+            Stream ms((uint*)macro.definition(), macro.definitionSize(), Anchor(input.inputPosition(), true));
             ms.setOriginalInputPosition(input.originalInputPosition());
             PreprocessedContents expanded;
             {
@@ -451,8 +451,8 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
           previous = IndexedString::fromIndex(output.peekLastOutput(stepsBack));
           ++stepsBack;
         }
-        pp_macro* macro = m_engine->environment()->retrieveMacro(previous, false);
-        if(!macro || !macro->function_like || !macro->defined || macro->hidden) {
+        const pp_macro& macro = m_engine->environment()->retrieveMacro(previous, false);
+        if(!macro.isValid() || !macro.function_like || !macro.defined || macro.hidden) {
           output << input;
           ++input;
           continue;
@@ -476,12 +476,12 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
             ++input;
           }
           
-          kDebug() << "too early end while expanding" << macro->name.str();
+          kDebug() << "too early end while expanding" << macro.name.str();
           return;
         }
 
         pp_macro_expander expand_actual(m_engine, m_frame);
-        skip_actual_parameter(input, *macro, actuals, expand_actual);
+        skip_actual_parameter(input, macro, actuals, expand_actual);
 
         while (!input.atEnd() && input == ',')
         {
@@ -498,11 +498,11 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
               ++input;
             }
             
-            kDebug() << "too early end while expanding" << macro->name.str();
+            kDebug() << "too early end while expanding" << macro.name.str();
             return;
           }
           
-          skip_actual_parameter(input, *macro, actuals, expand_actual);
+          skip_actual_parameter(input, macro, actuals, expand_actual);
         }
 
         if( input != ')' ) {
@@ -540,7 +540,7 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
         
         if(frame.depth >= maxMacroExpansionDepth) 
         {
-          kDebug() << "reached maximum macro-expansion depth while expanding" << macro->name.str();
+          kDebug() << "reached maximum macro-expansion depth while expanding" << macro.name.str();
           RETURN_IF_INPUT_BROKEN
           
           output << input;
@@ -552,7 +552,7 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
           MacroHider hideMacro(macro, m_engine->environment());
           
           ///@todo UGLY conversion
-          Stream ms((uint*)macro->definition(), macro->definitionSize(), Anchor(input.inputPosition(), true));
+          Stream ms((uint*)macro.definition(), macro.definitionSize(), Anchor(input.inputPosition(), true));
 
           PreprocessedContents expansion_text;
           rpp::LocationTable table;
@@ -573,14 +573,14 @@ void pp_macro_expander::operator()(Stream& input, Stream& output, bool substitut
   }
 }
 
-void pp_macro_expander::skip_actual_parameter(Stream& input, rpp::pp_macro& macro, QList< pp_actual >& actuals, pp_macro_expander& expander)
+void pp_macro_expander::skip_actual_parameter(Stream& input, const pp_macro& macro, QList< pp_actual >& actuals, pp_macro_expander& expander)
 {
   PreprocessedContents actualText;
   skip_whitespaces(input, devnull());
   Anchor actualStart = input.inputPosition();
   {
     Stream as(&actualText);
-    skip_argument_variadics(actuals, &macro, input, as);
+    skip_argument_variadics(actuals, macro, input, as);
   }
   trim(actualText);
 
@@ -603,7 +603,7 @@ void pp_macro_expander::skip_actual_parameter(Stream& input, rpp::pp_macro& macr
   actuals.append(newActual);
 }
 
-void pp_macro_expander::skip_argument_variadics (const QList<pp_actual>& __actuals, pp_macro *__macro, Stream& input, Stream& output)
+void pp_macro_expander::skip_argument_variadics (const QList<pp_actual>& __actuals, const pp_macro& __macro, Stream& input, Stream& output)
 {
   int first;
 
@@ -611,9 +611,9 @@ void pp_macro_expander::skip_argument_variadics (const QList<pp_actual>& __actua
     first = input.offset();
     skip_argument(input, output);
 
-  } while ( __macro->variadics
+  } while ( __macro.variadics
             && first != input.offset()
             && !input.atEnd()
             && input == '.'
-            && (__actuals.size() + 1) == (int)__macro->formalsSize());
+            && (__actuals.size() + 1) == (int)__macro.formalsSize());
 }
diff --git a/languages/cpp/parser/rpp/pp-macro-expander.h b/languages/cpp/parser/rpp/pp-macro-expander.h
index b16b0c2..b981b12 100644
--- a/languages/cpp/parser/rpp/pp-macro-expander.h
+++ b/languages/cpp/parser/rpp/pp-macro-expander.h
@@ -64,10 +64,10 @@ public:
 class pp_frame
 {
 public:
-  pp_frame (pp_macro* __expandingMacro, const QList<pp_actual>& __actuals);
+  pp_frame (const pp_macro& __expandingMacro, const QList<pp_actual>& __actuals);
 
   int depth;
-  pp_macro* expandingMacro;
+  pp_macro expandingMacro;
   QList<pp_actual> actuals;
 };
 
@@ -83,7 +83,7 @@ public:
   /// If substitute == true, perform only macro parameter substitution and # token processing
   void operator()(Stream& input, Stream& output, bool substitute = false, LocationTable* table = 0);
 
-  void skip_argument_variadics (const QList<pp_actual>& __actuals, pp_macro *__macro,
+  void skip_argument_variadics (const QList<pp_actual>& __actuals, const pp_macro& __macro,
                                 Stream& input, Stream& output);
 
   bool in_header_section() const {
@@ -101,7 +101,7 @@ public:
 private:
   /// Read actual parameter of @ref macro value from @ref input and append it to @ref actuals
   /// @ref expander is a reusable macro expander
-  void skip_actual_parameter(rpp::Stream& input, rpp::pp_macro& macro, QList< rpp::pp_actual >& actuals, rpp::pp_macro_expander& expander);
+  void skip_actual_parameter(rpp::Stream& input, const rpp::pp_macro& macro, QList< rpp::pp_actual >& actuals, rpp::pp_macro_expander& expander);
 
   pp* m_engine;
   pp_frame* m_frame;
diff --git a/languages/cpp/parser/rpp/pp-macro.cpp b/languages/cpp/parser/rpp/pp-macro.cpp
index 6209c83..27c8e85 100644
--- a/languages/cpp/parser/rpp/pp-macro.cpp
+++ b/languages/cpp/parser/rpp/pp-macro.cpp
@@ -53,6 +53,16 @@ bool pp_macro::operator==(const pp_macro& rhs) const {
          listsEqual(rhs);
 }
 
+bool pp_macro::operator!=(const pp_macro& rhs) const
+{
+  return !(*this == rhs);
+}
+
+bool pp_macro::isValid() const
+{
+    return *this != pp_macro();
+}
+
 void pp_macro::invalidateHash() {
   m_valueHashValid = false;
 }
@@ -88,18 +98,28 @@ pp_macro::pp_macro(const pp_macro& rhs, bool dynamic) :
   copyListsFrom(rhs);
 }
 
-pp_macro::pp_macro(const char* nm) : name(KDevelop::IndexedString(nm, strlen(nm)))
-  , sourceLine(-1)
-  , defined(true)
-  , hidden(false)
-  , function_like(false)
-  , variadics(false)
-  , fixed(false)
-  , defineOnOverride(false)
-  , m_valueHashValid(false)
-  , m_valueHash(0)
+pp_macro& pp_macro::operator=(const pp_macro& rhs)
+{
+  name = rhs.name;
+  file = rhs.file;
+  sourceLine = rhs.sourceLine;
+  defined = rhs.defined;
+  hidden = rhs.hidden;
+  function_like = rhs.function_like;
+  variadics = rhs.variadics;
+  fixed = rhs.fixed;
+  defineOnOverride = rhs.defineOnOverride;
+  m_valueHashValid = true;
+  m_valueHash = rhs.valueHash();
+
+  copyListsFrom(rhs);
+
+  return *this;
+}
+
+pp_macro::pp_macro(const char* nm)
+  : pp_macro(IndexedString(nm))
 {
-  initializeAppendedLists();
 }
 
 QString pp_macro::toString() const {
diff --git a/languages/cpp/parser/rpp/pp-macro.h b/languages/cpp/parser/rpp/pp-macro.h
index 9998dc9..c1f8aa2 100644
--- a/languages/cpp/parser/rpp/pp-macro.h
+++ b/languages/cpp/parser/rpp/pp-macro.h
@@ -44,10 +44,12 @@ public:
 
    ///@todo enable structure packing
   pp_macro(const KDevelop::IndexedString& name = KDevelop::IndexedString());
-  pp_macro(const char* name);
+  explicit pp_macro(const char* name);
   pp_macro(const pp_macro& rhs, bool dynamic = true);
   ~pp_macro();
-  
+
+  pp_macro& operator=(const pp_macro& rhs);
+
   uint classSize() const {
     return sizeof(pp_macro);
   }
@@ -78,6 +80,8 @@ public:
   mutable HashType m_valueHash; //Hash that represents the values of all macros
   
   bool operator==(const pp_macro& rhs) const;
+  bool operator!=(const pp_macro& rhs) const;
+  bool isValid() const;
   
   bool isUndef() const  {
     return !defined;
@@ -171,8 +175,7 @@ public:
     return !appendedListsDynamic();
   }
 
-  private:
-    pp_macro& operator=(const pp_macro& rhs);
+private:
     void computeHash() const;
 };