summaryrefslogtreecommitdiffstats
path: root/lib/cppparser/driver.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cppparser/driver.h')
-rw-r--r--lib/cppparser/driver.h460
1 files changed, 460 insertions, 0 deletions
diff --git a/lib/cppparser/driver.h b/lib/cppparser/driver.h
new file mode 100644
index 00000000..31f62443
--- /dev/null
+++ b/lib/cppparser/driver.h
@@ -0,0 +1,460 @@
+/* This file is part of KDevelop
+ Copyright (C) 2002,2003 Roberto Raggi <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+#include "ast.h"
+
+#include "macro.h"
+#include <qpair.h>
+#include <qvaluestack.h>
+#include <qstringlist.h>
+#include <qcstring.h>
+#include <qdatastream.h>
+#include <qmap.h>
+#include <qdatetime.h>
+#include <qvaluelist.h>
+#include <map>
+#include <set>
+#include <hashedstring.h>
+#include <ksharedptr.h>
+#include <codemodel.h>
+#include <ext/hash_map>
+#include "lexercache.h"
+
+
+class Lexer;
+class Parser;
+
+enum
+{
+ Dep_Global,
+ Dep_Local
+};
+
+typedef QPair<QString, int> Dependence;
+
+class ParsedFile;
+typedef KSharedPtr< ParsedFile > ParsedFilePointer;
+
+class ParsedFile : public AbstractParseResult {
+ public:
+ struct IncludeDesc {
+ bool local; //Whether it is a local include(#include "local.h", not #include <global.h>)
+ QString includePath;
+ ParsedFilePointer parsed; //May be zero!
+ };
+// ParsedFile() {
+// }
+ ParsedFile( QDataStream& s ) {
+ read( s );
+ }
+
+ ParsedFile( const QString& fileName, const QDateTime& timeStamp );
+
+ ///Deserializes the ParsedFile from a previous call to serialize(). AST will always be zero after a call to this.
+ ParsedFile( const QByteArray& array );
+
+ /**
+ * @return All Macros that were used while processing this translation-unit. May be modified.
+ */
+ MacroSet& usedMacros();
+ const MacroSet& usedMacros() const;
+
+ /**
+ * @return the count of lines that were skipped while preprocessing the file
+ * */
+ int skippedLines() const;
+
+ void setSkippedLines( int lines );
+ /**
+ * @return Absolutely all files included by this one(no matter through how many other files they were included)
+ */
+// HashedStringSet& includeFiles();
+
+ const HashedStringSet& includeFiles() const;
+
+ void addIncludeFiles( const HashedStringSet& includeFiles );
+
+ void addIncludeFile( const QString& includePath, const ParsedFilePointer& parsed, bool localInclude );
+
+ ///If this file was parsed while resolving the dependencies of another file, this returns the file this one was included from. Else returns an empty string.
+ QString includedFrom() const;
+
+ void setIncludedFrom( const QString& str );
+ /**
+ * @return Reference to the internal list of all directly included files(without those included indirectly)
+ */
+ const QValueList<IncludeDesc>& directIncludeFiles() const;
+
+ operator TranslationUnitAST* () const; //May be zero!
+
+ TranslationUnitAST* operator -> () const {
+ if( !this ) return 0;
+ return m_translationUnit;
+ }
+
+ void setTranslationUnit( const TranslationUnitAST::Node& trans );
+
+ QString fileName() const;
+
+ QDateTime timeStamp() const;
+
+ ///Serializes the content of this class into a byte-array. Note that this does not serialize the AST.
+ QByteArray serialize() const;
+
+ /*void read( QDataStream& stream );
+ void write( QDataStream& stream ) const;*/
+
+ virtual void read( QDataStream& stream ) {
+ int directIncludeFilesCount;
+ stream >> directIncludeFilesCount;
+ m_directIncludeFiles.clear();
+ for( int a = 0; a < directIncludeFilesCount; a++ ) {
+ IncludeDesc i;
+ Q_INT8 in;
+ stream >> in;
+ i.local = in;
+ stream >> i.includePath;
+ //"parsed" will not be reconstructed
+ m_directIncludeFiles.push_back( i );
+ }
+ stream >> m_skippedLines;
+ stream >> m_fileName;
+ stream >> m_timeStamp;
+ stream >> m_includedFrom;
+ m_usedMacros.read( stream );
+ m_translationUnit = 0;
+ m_includeFiles.read( stream );
+ }
+
+ virtual void write( QDataStream& stream ) const {
+ int i = m_directIncludeFiles.size();
+ stream << i;
+ for( QValueList<IncludeDesc>::const_iterator it = m_directIncludeFiles.begin(); it != m_directIncludeFiles.end(); ++it ) {
+ Q_INT8 i = (*it).local;
+ stream << i;
+ stream << (*it).includePath;
+ }
+ stream << m_skippedLines;
+ stream << m_fileName;
+ stream << m_timeStamp;
+ stream << m_includedFrom;
+ m_usedMacros.write( stream );
+ m_includeFiles.write( stream );
+ }
+
+ virtual ParsedFileType type() const {
+ return CppParsedFile;
+ }
+
+ private:
+ QValueList<IncludeDesc> m_directIncludeFiles;
+ MacroSet m_usedMacros;
+ TranslationUnitAST::Node m_translationUnit;
+ HashedStringSet m_includeFiles;
+ int m_skippedLines;
+ QString m_fileName;
+ QDateTime m_timeStamp;
+ QString m_includedFrom;
+};
+
+/**
+ * An interface that provides source code to the Driver
+ */
+class SourceProvider {
+ public:
+ SourceProvider() {}
+ virtual ~SourceProvider() {}
+
+ /**
+ * Get the contents of a file
+ * \param fileName The name of the file to get the contents for. An absolute
+ * path should be used.
+ * \return A QString that contains the contents of the file
+ */
+ virtual QString contents( const QString& fileName ) = 0;
+
+ /**
+ * Check to see if a file has been modified
+ * \param fileName The name of hte file to get the modification state of. An
+ * absolute path should be used.
+ * \return true if the file has been modified
+ * \return false if the file has not been modified
+ */
+ virtual bool isModified( const QString& fileName ) = 0;
+
+ private:
+ SourceProvider( const SourceProvider& source );
+ void operator = ( const SourceProvider& source );
+};
+
+class Driver {
+ public:
+ Driver();
+ virtual ~Driver();
+
+ typedef std::multimap< HashedString, Macro > MacroMap;
+
+ /**
+ * Get the source provider for this driver. This would be useful for
+ * getting the text the driver is working with.
+ */
+ SourceProvider* sourceProvider();
+ /**
+ * Sets the source provider the driver will use
+ * @param sourceProvider the SourceProvider the driver will use
+ */
+ void setSourceProvider( SourceProvider* sourceProvider );
+
+ /**
+ * @brief Resets the driver
+ *
+ * Clears the driver of all problems, dependencies, macros, and include paths and
+ * removes any translation units that have been parsed
+ */
+ virtual void reset();
+
+ /**
+ * Tells the driver to start parsing a file
+ * @param fileName The name of the file to parse
+ * @param onlyPreProcesss Tells the driver to only run the file through the preprocessor. Defaults to false
+ * @param force Force the parsing of the file. Defaults to false
+ * @param macrosGlobal Should the macros be global? (Global macros are not deleted once a new translation-unit is parsed)
+ */
+ virtual void parseFile( const QString& fileName, bool onlyPreProcesss = false, bool force = false, bool macrosGlobal = false );
+
+ /**
+ * Indicates that the file has been parsed
+ * @param fileName The name of the file parsed. It is legal to create a ParsedFilePointer on the given item.
+ */
+ virtual void fileParsed( ParsedFile& fileName );
+
+ /**
+ * Removes the file specified by @p fileName from the driver
+ * @param fileName The name of the file to remove
+ */
+ virtual void remove
+ ( const QString& fileName );
+
+ /**
+ * Add a dependency on another header file for @p fileName
+ * @param fileName The file name to add the dependency for
+ * @param dep The dependency to add
+ */
+ virtual void addDependence( const QString& fileName, const Dependence& dep );
+
+ /**
+ * Add a macro to the driver
+ * @param macro The macro to add to the driver
+ */
+ virtual void addMacro( const Macro& macro );
+
+ /**
+ * Add a problem to the driver
+ * @param fileName The file name to add the problem for
+ * @param problem The problem to add
+ */
+ virtual void addProblem( const QString& fileName, const Problem& problem );
+
+ /**
+ * The current file name the driver is working with
+ */
+ QString currentFileName() const {
+ return m_currentFileName;
+ }
+ ParsedFilePointer takeTranslationUnit( const QString& fileName );
+
+ void takeTranslationUnit( const ParsedFile& file );
+ /**
+ * Get the translation unit contained in the driver for @p fileName.
+ * @param fileName The name of the file to get the translation unit for
+ * @return The TranslationUnitAST pointer that represents the translation unit
+ * @return 0 if no translation unit exists for the file
+ */
+ ParsedFilePointer translationUnit( const QString& fileName ) const;
+ /**
+ * Get the dependencies for a file
+ * @param fileName The file name to get dependencies for
+ * @return The dependencies for the file
+ */
+ QMap<QString, Dependence> dependences( const QString& fileName ) const;
+ /**
+ * Get all the macros the driver contains
+ * @return The macros
+ */
+ const MacroMap& macros() const;
+
+ /**
+ * Take all macros from the given map(forgetting own macros) */
+ void insertMacros( const MacroSet& macros );
+ /**
+ * Get the list of problem areas the driver contains
+ * @param fileName The filename to get problems for
+ * @return The list of problems for @p fileName
+ */
+ QValueList<Problem> problems( const QString& fileName ) const;
+
+ void usingString( const HashedString& str );
+ /**
+ * Check if we have a macro in the driver
+ * If the last stacked macro of that name is an undef-macro, false is returned.
+ * @param name The name of the macro to check for
+ * @return true if we have the macro in the driver
+ * @return false if we don't have the macro in the driver
+ */
+ bool hasMacro( const HashedString& name ) ;
+ /**
+ * Get the macro identified by @p name
+ * @param name The name of the macro to get
+ * @return A const reference of the macro object represented by @p name
+ */
+ const Macro& macro( const HashedString& name ) const;
+ /**
+ * Get the last inserted macro identified by @p name
+ * @override
+ * @param name The name of the macro to get
+ * @return A non-const reference of the macro object represented by @p name
+ *
+ */
+ Macro& macro( const HashedString& name );
+
+ /**
+ * Remove the last inserted Macro of that name
+ * @param macroName The name of the macro to remove
+ */
+ virtual void removeMacro( const HashedString& macroName );
+
+ /**
+ * Remove all macros from the driver for a certain file
+ * @param fileName The file name
+ */
+ virtual void removeAllMacrosInFile( const QString& fileName ); ///Check when this is called. It may be wrong.
+
+ QStringList includePaths() const {
+ return m_includePaths;
+ }
+
+ virtual QStringList getCustomIncludePath( const QString& );
+
+
+ virtual void addIncludePath( const QString &path );
+
+ virtual void clearIncludePaths();
+
+ /// @todo remove
+ const QMap<QString, ParsedFilePointer> &parsedUnits() const {
+ return m_parsedUnits;
+ }
+
+ /**
+ * Set whether or not to enable dependency resolving for files added to the driver
+ */
+ virtual void setResolveDependencesEnabled( bool enabled );
+ /**
+ * Check if dependency resolving is enabled
+ * \return true if dependency resolving is enabled
+ * \return false if dependency resolving is disabled
+ */
+ bool isResolveDependencesEnabled() const {
+ return depresolv;
+ }
+
+ void setMaxDependenceDepth( int depth );
+
+ /**
+ * Used by the Lexer to indicate that a Macro was used
+ * @param macro The used macro
+ * */
+ void usingMacro( const Macro& macro );
+
+ /**
+ * Returns the local instance of the lexer-cache, can be used from outside to control the cache-behavior.
+ * */
+ LexerCache* lexerCache();
+
+ ///This uses getCustomIncludePath(..) to resolve the include-path internally
+ QString findIncludeFile( const Dependence& dep, const QString& fromFile );
+
+ protected:
+ ///This uses the state of the parser to find the include-file
+ QString findIncludeFile( const Dependence& dep ) const;
+
+ /**
+ * Set up the lexer.
+ */
+ virtual void setupLexer( Lexer* lexer );
+ /**
+ * Setup the parser
+ */
+ virtual void setupParser( Parser* parser );
+ /**
+ * Set up the preprocessor
+ */
+ virtual void setupPreProcessor();
+
+ /**
+ * Is code-information for this file already available? If false is returned, the file will be parsed.
+ * Code-model and static repository should be checked to find out whether the file is already available.
+ * This function is only used when dependency-resolving is activated.
+ * @arg file absolute path to the file
+ */
+ virtual bool shouldParseIncludedFile( const ParsedFilePointer& /*file*/ );
+
+ void clearMacros();
+
+ void clearParsedMacros();
+
+ private:
+ QMap<QString, Dependence>& findOrInsertDependenceList( const QString& fileName );
+ QValueList<Problem>& findOrInsertProblemList( const QString& fileName );
+
+
+ private:
+ QString m_currentFileName;
+ QString m_currentMasterFileName;
+ typedef QMap<QString, Dependence> DependenceMap;
+ typedef QMap< QString, DependenceMap> DependencesMap;
+ DependencesMap m_dependences;
+ MacroMap m_macros;
+ QMap< QString, QValueList<Problem> > m_problems;
+ QMap<QString, ParsedFilePointer> m_parsedUnits;
+ QStringList m_includePaths;
+ uint depresolv :
+ 1;
+ Lexer *lexer;
+ SourceProvider* m_sourceProvider;
+
+ ParsedFilePointer m_currentParsedFile;
+ CachedLexedFilePointer m_currentLexerCache;
+ LexerCache m_lexerCache;
+
+ int m_dependenceDepth;
+ int m_maxDependenceDepth;
+
+ class ParseHelper;
+ friend class ParseHelper;
+
+ private:
+ Driver( const Driver& source );
+ void operator = ( const Driver& source );
+};
+
+#endif