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
|
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef LUPDATEPREPROCESSORACTION_H
#define LUPDATEPREPROCESSORACTION_H
#include "cpp_clang.h"
#include "synchronized.h"
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4100)
QT_WARNING_DISABLE_MSVC(4146)
QT_WARNING_DISABLE_MSVC(4267)
QT_WARNING_DISABLE_MSVC(4624)
QT_WARNING_DISABLE_GCC("-Wnonnull")
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/Tooling.h>
#include <clang/Lex/PPCallbacks.h>
#include <clang/Lex/Preprocessor.h>
QT_WARNING_POP
#include <memory>
QT_BEGIN_NAMESPACE
class LupdatePPCallbacks : public clang::PPCallbacks
{
public:
LupdatePPCallbacks(WriteSynchronizedRef<TranslationRelatedStore> *stores, clang::Preprocessor &pp)
: m_preprocessor(pp)
, m_stores(stores)
{
const auto &sm = m_preprocessor.getSourceManager();
m_inputFile = sm.getFileEntryRefForID(sm.getMainFileID())->getName();
}
~LupdatePPCallbacks() override
{
m_stores->emplace_bulk(std::move(m_ppStores));
}
private:
void MacroExpands(const clang::Token &token, const clang::MacroDefinition ¯oDefinition,
clang::SourceRange sourceRange, const clang::MacroArgs *macroArgs) override;
void storeMacroArguments(const std::vector<QString> &args, TranslationRelatedStore *store);
void SourceRangeSkipped(clang::SourceRange sourceRange, clang::SourceLocation endifLoc) override;
#if (LUPDATE_CLANG_VERSION < LUPDATE_CLANG_VERSION_CHECK(14,0,0))
void InclusionDirective(clang::SourceLocation /*hashLoc*/, const clang::Token &/*includeTok*/,
clang::StringRef /*fileName*/, bool /*isAngled*/,
clang::CharSourceRange /*filenameRange*/,
#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(16,0,0))
const clang::OptionalFileEntryRef file,
#elif (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(15,0,0))
const clang::Optional<clang::FileEntryRef> file,
#else
const clang::FileEntry *file,
#endif
clang::StringRef /*searchPath*/, clang::StringRef /*relativePath*/,
const clang::Module */*imported*/,
clang::SrcMgr::CharacteristicKind /*fileType*/) override;
#endif
std::string m_inputFile;
clang::Preprocessor &m_preprocessor;
TranslationStores m_ppStores;
WriteSynchronizedRef<TranslationRelatedStore> *m_stores { nullptr };
};
class LupdatePreprocessorAction : public clang::PreprocessOnlyAction
{
public:
LupdatePreprocessorAction(WriteSynchronizedRef<TranslationRelatedStore> *stores)
: m_stores(stores)
{}
private:
void ExecuteAction() override
{
auto &preprocessor = getCompilerInstance().getPreprocessor();
preprocessor.SetSuppressIncludeNotFoundError(true);
auto callbacks = new LupdatePPCallbacks(m_stores, preprocessor);
preprocessor.addPPCallbacks(std::unique_ptr<clang::PPCallbacks>(callbacks));
clang::PreprocessOnlyAction::ExecuteAction();
}
private:
WriteSynchronizedRef<TranslationRelatedStore> *m_stores { nullptr };
};
class LupdatePreprocessorActionFactory : public clang::tooling::FrontendActionFactory
{
public:
explicit LupdatePreprocessorActionFactory(WriteSynchronizedRef<TranslationRelatedStore> *stores)
: m_stores(stores)
{}
#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(10,0,0))
std::unique_ptr<clang::FrontendAction> create() override
{
return std::make_unique<LupdatePreprocessorAction>(m_stores);
}
#else
clang::FrontendAction *create() override
{
return new LupdatePreprocessorAction(m_stores);
}
#endif
private:
WriteSynchronizedRef<TranslationRelatedStore> *m_stores { nullptr };
};
QT_END_NAMESPACE
#endif
|