1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef LUPDATEPREPROCESSORACTION_H
5#define LUPDATEPREPROCESSORACTION_H
6
7#include "cpp_clang.h"
8#include "synchronized.h"
9
10QT_WARNING_PUSH
11QT_WARNING_DISABLE_MSVC(4100)
12QT_WARNING_DISABLE_MSVC(4146)
13QT_WARNING_DISABLE_MSVC(4267)
14QT_WARNING_DISABLE_MSVC(4624)
15QT_WARNING_DISABLE_GCC("-Wnonnull")
16
17#include <clang/Frontend/CompilerInstance.h>
18#include <clang/Frontend/FrontendActions.h>
19#include <clang/Tooling/Tooling.h>
20#include <clang/Lex/PPCallbacks.h>
21#include <clang/Lex/Preprocessor.h>
22
23QT_WARNING_POP
24
25#include <memory>
26
27QT_BEGIN_NAMESPACE
28
29class LupdatePPCallbacks : public clang::PPCallbacks
30{
31public:
32 LupdatePPCallbacks(WriteSynchronizedRef<TranslationRelatedStore> *stores, clang::Preprocessor &pp)
33 : m_preprocessor(pp)
34 , m_stores(stores)
35 {
36 const auto &sm = m_preprocessor.getSourceManager();
37 m_inputFile = sm.getFileEntryRefForID(FID: sm.getMainFileID())->getName();
38 }
39
40 ~LupdatePPCallbacks() override
41 {
42 m_stores->emplace_bulk(values: std::move(m_ppStores));
43 }
44
45private:
46 void MacroExpands(const clang::Token &token, const clang::MacroDefinition &macroDefinition,
47 clang::SourceRange sourceRange, const clang::MacroArgs *macroArgs) override;
48
49 void storeMacroArguments(const std::vector<QString> &args, TranslationRelatedStore *store);
50
51 void SourceRangeSkipped(clang::SourceRange sourceRange, clang::SourceLocation endifLoc) override;
52#if (LUPDATE_CLANG_VERSION < LUPDATE_CLANG_VERSION_CHECK(14,0,0))
53 void InclusionDirective(clang::SourceLocation /*hashLoc*/, const clang::Token &/*includeTok*/,
54 clang::StringRef /*fileName*/, bool /*isAngled*/,
55 clang::CharSourceRange /*filenameRange*/,
56#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(16,0,0))
57 const clang::OptionalFileEntryRef file,
58#elif (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(15,0,0))
59 const clang::Optional<clang::FileEntryRef> file,
60#else
61 const clang::FileEntry *file,
62#endif
63 clang::StringRef /*searchPath*/, clang::StringRef /*relativePath*/,
64 const clang::Module */*imported*/,
65 clang::SrcMgr::CharacteristicKind /*fileType*/) override;
66#endif
67
68 std::string m_inputFile;
69 clang::Preprocessor &m_preprocessor;
70
71 TranslationStores m_ppStores;
72 WriteSynchronizedRef<TranslationRelatedStore> *m_stores { nullptr };
73};
74
75class LupdatePreprocessorAction : public clang::PreprocessOnlyAction
76{
77public:
78 LupdatePreprocessorAction(WriteSynchronizedRef<TranslationRelatedStore> *stores)
79 : m_stores(stores)
80 {}
81
82private:
83 void ExecuteAction() override
84 {
85 auto &preprocessor = getCompilerInstance().getPreprocessor();
86 preprocessor.SetSuppressIncludeNotFoundError(true);
87 auto callbacks = new LupdatePPCallbacks(m_stores, preprocessor);
88 preprocessor.addPPCallbacks(C: std::unique_ptr<clang::PPCallbacks>(callbacks));
89
90 clang::PreprocessOnlyAction::ExecuteAction();
91 }
92
93private:
94 WriteSynchronizedRef<TranslationRelatedStore> *m_stores { nullptr };
95};
96
97class LupdatePreprocessorActionFactory : public clang::tooling::FrontendActionFactory
98{
99public:
100 explicit LupdatePreprocessorActionFactory(WriteSynchronizedRef<TranslationRelatedStore> *stores)
101 : m_stores(stores)
102 {}
103
104#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(10,0,0))
105 std::unique_ptr<clang::FrontendAction> create() override
106 {
107 return std::make_unique<LupdatePreprocessorAction>(args&: m_stores);
108 }
109#else
110 clang::FrontendAction *create() override
111 {
112 return new LupdatePreprocessorAction(m_stores);
113 }
114#endif
115
116private:
117 WriteSynchronizedRef<TranslationRelatedStore> *m_stores { nullptr };
118};
119
120QT_END_NAMESPACE
121
122#endif
123

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qttools/src/linguist/lupdate/lupdatepreprocessoraction.h