diff options
Diffstat (limited to 'lib/cppparser/lexercache.h')
-rw-r--r-- | lib/cppparser/lexercache.h | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/lib/cppparser/lexercache.h b/lib/cppparser/lexercache.h new file mode 100644 index 00000000..c32d5406 --- /dev/null +++ b/lib/cppparser/lexercache.h @@ -0,0 +1,162 @@ +/*************************************************************************** + copyright : (C) 2006 by David Nolden + email : [email protected] +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef LEXERCACHE_H +#define LEXERCACHE_H +#include <hashedstring.h> +#include <ext/hash_map> +#include <ksharedptr.h> +#include "macro.h" +#include <kdebug.h> +#include <qdatetime.h> +#include <qfileinfo.h> +#include <ext/hash_set> +#include "cachemanager.h" + +//#define LEXERCACHE_DEBUG + +class LexerCache; + +class CachedLexedFile : public KShared, public CacheNode { + public: + ///@todo add and manage the set of included files + CachedLexedFile( const HashedString& fileName, LexerCache* manager ); + + inline void addString( const HashedString& string ) { + if( !m_definedMacroNames[ string ] ) { + m_strings.insert( string ); + } + } + + void addDefinedMacro( const Macro& macro ); + + void addUsedMacro( const Macro& macro ); + + void addIncludeFile( const HashedString& file, const QDateTime& modificationTime ); + + inline bool hasString( const HashedString& string ) const { + return m_strings[string]; + } + + QDateTime modificationTime() const; + + void addProblem( const Problem& p ); + + QValueList<Problem> problems() const; + + //The parameter should be a CachedLexedFile that was lexed AFTER the content of this file + void merge( const CachedLexedFile& file ); + + bool operator < ( const CachedLexedFile& rhs ) const { + return m_fileName < rhs.m_fileName; + } + + size_t hash() const; + + HashedString fileName() const { + return m_fileName; + } + + const HashedStringSet& includeFiles() const { + return m_includeFiles; + } + + const MacroSet& definedMacros() const { + return m_definedMacros; + } + + const MacroSet& usedMacros() const { + return m_usedMacros; + } + + ///Should contain a modification-time for each include-file + const QMap<HashedString, QDateTime>& allModificationTimes() const { + return m_allModificationTimes; + } + + private: + friend class LexerCache; + HashedString m_fileName; + QDateTime m_modificationTime; + HashedStringSet m_strings; //Set of all strings that can be affected by macros from outside + HashedStringSet m_includeFiles; //Set of all files + MacroSet m_usedMacros; //Set of all macros that were used, and were defined outside of this file + MacroSet m_definedMacros; //Set of all macros that were defined while lexing this file + HashedStringSet m_definedMacroNames; + QValueList<Problem> m_problems; + QMap<HashedString, QDateTime> m_allModificationTimes; + /* + Needed data: + 1. Set of all strings that appear in this file(For memory-reasons they should be taken from a global string-repository, because many will be the same) + 2. Set of all macros that were defined outside of, but affected the file + + Algorithm: + Iterate over all available macros, and check whether they affect the file. If it does, make sure that the macro is in the macro-set and has the same body. + If the check fails: We need to reparse. + */ +}; + +typedef KSharedPtr<CachedLexedFile> CachedLexedFilePointer; + +struct CachedLexedFilePointerCompare { + bool operator() ( const CachedLexedFilePointer& lhs, const CachedLexedFilePointer& rhs ) const { + return (*lhs) < (*rhs ); + } +}; + +class Driver; + +class LexerCache : public CacheManager { + public: + LexerCache( Driver* d ); + + void addLexedFile( const CachedLexedFilePointer& file ); + + ///Returns zero if no fitting file is available for the current context + CachedLexedFilePointer lexedFile( const HashedString& fileName ); + + void clear(); + + const HashedString& unifyString( const HashedString& str ) { + __gnu_cxx::hash_set<HashedString>::const_iterator it = m_totalStringSet.find( str ); + if( it != m_totalStringSet.end() ) { + return *it; + } else { + m_totalStringSet.insert( str ); + return str; + } + } + virtual void saveMemory(); + private: + ///before this can be called, initFileModificationCache should be called once + QDateTime fileModificationTimeCached( const HashedString& fileName ); + void initFileModificationCache(); + virtual void erase( const CacheNode* node ); + bool sourceChanged( const CachedLexedFile& file );///Returns true if the file itself, or any of its dependencies was modified. + //typedef __gnu_cxx::hash_multimap<HashedString, CachedLexedFilePointer> CachedLexedFileMap; + typedef std::multimap<HashedString, CachedLexedFilePointer> CachedLexedFileMap; + CachedLexedFileMap m_files; + __gnu_cxx::hash_set<HashedString> m_totalStringSet; ///This is used to reduce memory-usage: Most strings appear again and again. Because QString is reference-counted, this set contains a unique copy of each string to used for each appearance of the string + struct FileModificationCache { + QDateTime m_readTime; + QDateTime m_modificationTime; + }; + typedef __gnu_cxx::hash_map<HashedString, FileModificationCache> FileModificationMap; + FileModificationMap m_fileModificationCache; + Driver* m_driver; + QDateTime m_currentDateTime; +}; + + +#endif |