summaryrefslogtreecommitdiff
path: root/src/plugins/clangcodemodel/unit.h
blob: a19e6ab85d232cb6ecce8aae2118818767fd2bd0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://www.qt.io/licensing.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#ifndef UNIT_H
#define UNIT_H

#include "utils.h"
#include "raii/scopedclangoptions.h"
#include "cxraii.h"

#include <QtCore/QDateTime>
#include <QSharedPointer>
#include <QMetaType>
#include <QString>
#include <QStringList>
#include <QVarLengthArray>

QT_BEGIN_NAMESPACE
class QDateTime;
QT_END_NAMESPACE

namespace ClangCodeModel {
namespace Internal {

class UnitData;

/*
 * This is a minimal wrapper around clang's translation unit functionality.
 * It should should contain only the very basic primitives which allow other
 * components such as code completion, code navigation, and others to access
 * data which directly depends on the translation unit.
 *
 * In other words, what's wrapped here is only the functions that receive a
 * CXTranslationUnit as a parameter. And this class itself is then the corresponding
 * abstraction of the CXTranslationUnit.
 *
 * Notes:
 *  - This class is not thread-safe.
 *  - It's responsibility of the client to make sure that the wrapped translation
 *    unit is consistent with the other data such as cursor and locations being used.
 *
 * @TODO: This is similar but not exactly the same as the current ClangWrapper class.
 * That class is now tuned to specific features, so it's not generic enough to be used
 * an underlying component and aslo don't provide the data in a fine granularity as
 * needed here. At some point we should split ClangWrapper into its different logical
 * components and use this is the underlying structure.
 */
class Unit
{
    Q_DISABLE_COPY(Unit)

    Unit();
    explicit Unit(const QString &fileName);

public:
    ~Unit();

    typedef QSharedPointer<Unit> Ptr;
    static Ptr create();
    static Ptr create(const QString &fileName);

    bool isLoaded() const;

    const QString fileName() const;

    const QDateTime &timeStamp() const;

    QStringList compilationOptions() const;
    void setCompilationOptions(const QStringList &compOptions);

    UnsavedFiles unsavedFiles() const;
    void setUnsavedFiles(const UnsavedFiles &unsavedFiles);

    unsigned managementOptions() const;
    void setManagementOptions(unsigned managementOptions);

    // Methods for generating the TU. Name mappings are direct, for example:
    //   - parse corresponds to clang_parseTranslationUnit
    //   - createFromSourceFile corresponds to clang_createTranslationUnitFromSourceFile
    void parse();
    void reparse();
    int save(const QString &unitFileName);
    void unload();

    // Simple forwarding methods, separated by clang categories for convenience.
    // As above, the names are directly mapped. Separated by categories as clang for convenience.
    // Note that only methods that take the TU as a parameter should be wrapped.

    // - Diagnostic reporting
    unsigned getNumDiagnostics() const;
    CXDiagnostic getDiagnostic(unsigned index) const;

    // - Translation unit manipulation
    CXString getTranslationUnitSpelling() const;

    // - File manipulation routines
    CXFile getFile() const;

    // - Mapping between cursors and source code
    CXCursor getCursor(const CXSourceLocation &location) const;

    // - Miscellaneous utility functions
    void getInclusions(CXInclusionVisitor visitor, CXClientData clientData) const;

    // - Cursor manipulations
    CXCursor getTranslationUnitCursor() const;

    // - Physical source locations
    CXSourceLocation getLocation(const CXFile &file, unsigned line, unsigned column) const;

    void codeCompleteAt(unsigned line, unsigned column, ScopedCXCodeCompleteResults &results);

    void tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const;
    void disposeTokens(CXToken *tokens, unsigned tokenCount) const;
    CXSourceRange getTokenExtent(const CXToken &token) const;
    void annotateTokens(CXToken *tokens, unsigned tokenCount, CXCursor *cursors) const;

    CXTranslationUnit clangTranslationUnit() const;
    CXIndex clangIndex() const;

    QString getTokenSpelling(const CXToken &tok) const;

private:
    void updateTimeStamp();

    CXIndex m_index;
    CXTranslationUnit m_tu;
    QByteArray m_fileName;
    QStringList m_compOptions;
    SharedClangOptions m_sharedCompOptions;
    unsigned m_managementOptions;
    UnsavedFiles m_unsaved;
    QDateTime m_timeStamp;
};

class IdentifierTokens
{
    Q_DISABLE_COPY(IdentifierTokens)

public:
    IdentifierTokens(const Unit &m_unit, unsigned firstLine, unsigned lastLine);
    ~IdentifierTokens();

    unsigned count() const
    { return m_tokenCount; }

    const CXToken &token(unsigned nr) const
    { Q_ASSERT(nr < count()); return m_tokens[nr]; }

    const CXCursor &cursor(unsigned nr) const
    { Q_ASSERT(nr < count()); return m_cursors[nr]; }

    const CXSourceRange &extent(unsigned nr) const
    { Q_ASSERT(nr < count()); return m_extents[nr]; }

private:
    void dispose();

private:
    const Unit &m_unit;
    unsigned m_tokenCount;
    CXToken *m_tokens;

    CXCursor *m_cursors;
    CXSourceRange *m_extents;
};

} // Internal
} // Clang

Q_DECLARE_METATYPE(ClangCodeModel::Internal::Unit::Ptr)

#endif // UNIT_H