File indexing completed on 2024-05-12 04:39:13

0001 /*
0002     SPDX-FileCopyrightText: 2013 Olivier de Gaalon <olivier.jg@gmail.com>
0003     SPDX-FileCopyrightText: 2013 Milian Wolff <mail@milianw.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef PARSESESSION_H
0009 #define PARSESESSION_H
0010 
0011 #include <QList>
0012 #include <QTemporaryFile>
0013 
0014 #include <clang-c/Index.h>
0015 
0016 #include <serialization/indexedstring.h>
0017 
0018 #include <util/path.h>
0019 
0020 #include <language/duchain/problem.h>
0021 #include <language/interfaces/iastcontainer.h>
0022 
0023 #include "clangprivateexport.h"
0024 #include "clangproblem.h"
0025 #include "clangparsingenvironment.h"
0026 #include "unsavedfile.h"
0027 
0028 class ClangIndex;
0029 
0030 class KDEVCLANGPRIVATE_EXPORT ParseSessionData : public KDevelop::IAstContainer
0031 {
0032 public:
0033     using Ptr = QExplicitlySharedDataPointer<ParseSessionData>;
0034 
0035     enum Option {
0036         NoOption = 0,                     ///< No special options
0037         SkipFunctionBodies = 1 << 0,      ///< Pass CXTranslationUnit_SkipFunctionBodies (likely unwanted)
0038         PrecompiledHeader = 1 << 1,       ///< Pass CXTranslationUnit_PrecompiledPreamble and others to cache precompiled headers
0039         OpenedInEditor = 1 << 2,          ///< File is currently opened in the editor
0040     };
0041     Q_DECLARE_FLAGS(Options, Option)
0042 
0043     /**
0044      * Parse the given @p contents.
0045      *
0046      * @param unsavedFiles Optional unsaved document contents from the editor.
0047      */
0048     ParseSessionData(const QVector<UnsavedFile>& unsavedFiles, ClangIndex* index,
0049                      const ClangParsingEnvironment& environment, Options options = Options());
0050 
0051     ~ParseSessionData() override;
0052 
0053     ClangParsingEnvironment environment() const;
0054 
0055 private:
0056     friend class ParseSession;
0057     void setUnit(CXTranslationUnit unit);
0058     QByteArray writeDefinesFile(const QMap<QString, QString>& defines);
0059 
0060     QMutex m_mutex;
0061 
0062     CXFile m_file = nullptr;
0063     CXTranslationUnit m_unit = nullptr;
0064     ClangParsingEnvironment m_environment;
0065     /// TODO: share this file for all TUs that use the same defines (probably most in a project)
0066     ///       best would be a PCH, if possible
0067     QTemporaryFile m_definesFile;
0068     // cached ProblemPointer representation for diagnostics
0069     QVector<ClangProblem::Ptr> m_diagnosticsCache;
0070 };
0071 
0072 /**
0073  * Thread-safe utility class around a CXTranslationUnit.
0074  *
0075  * It will lock the mutex of the currently set ParseSessionData and thereby ensure
0076  * only one ParseSession can operate on a given CXTranslationUnit stored therein.
0077  */
0078 class KDEVCLANGPRIVATE_EXPORT ParseSession
0079 {
0080 public:
0081     /**
0082      * @return a unique identifier for Clang documents.
0083      */
0084     static KDevelop::IndexedString languageString();
0085 
0086     /**
0087      * Initialize a parse session with the given data and, if that data is valid, lock its mutex.
0088      */
0089     explicit ParseSession(const ParseSessionData::Ptr& data);
0090     /**
0091      * Unlocks the mutex of the currently set ParseSessionData.
0092      */
0093     ~ParseSession();
0094 
0095     /**
0096      * Unlocks the mutex of the currently set ParseSessionData, and instead acquire the lock in @p data.
0097      */
0098     void setData(const ParseSessionData::Ptr& data);
0099     ParseSessionData::Ptr data() const;
0100 
0101     /**
0102      * @return find the CXFile for the given path.
0103      */
0104     CXFile file(const QByteArray& path) const;
0105 
0106     /**
0107      * @return the CXFile for the first file in this translation unit.
0108      */
0109     CXFile mainFile() const;
0110 
0111     QList<KDevelop::ProblemPointer> problemsForFile(CXFile file) const;
0112 
0113     CXTranslationUnit unit() const;
0114 
0115     bool reparse(const QVector<UnsavedFile>& unsavedFiles, const ClangParsingEnvironment& environment);
0116 
0117     ClangParsingEnvironment environment() const;
0118 
0119 private:
0120     Q_DISABLE_COPY(ParseSession)
0121 
0122     ClangProblem::Ptr getOrCreateProblem(int indexInTU, CXDiagnostic diagnostic) const;
0123     
0124     ClangProblem::Ptr createExternalProblem(int indexInTU,
0125                                             CXDiagnostic diagnostic,
0126                                             const KLocalizedString& descriptionTemplate,
0127                                             int childProblemFinalLocationIndex = -1) const;
0128     
0129     QList<ClangProblem::Ptr> createRequestedHereProblems(int indexInTU, CXDiagnostic diagnostic, CXFile file) const;
0130 
0131     ParseSessionData::Ptr d;
0132 
0133 };
0134 
0135 #endif // PARSESESSION_H