1// Copyright (C) 2019 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 CLANG_TOOL_AST_READER_H
5#define CLANG_TOOL_AST_READER_H
6
7#include "cpp_clang.h"
8
9QT_WARNING_PUSH
10QT_WARNING_DISABLE_MSVC(4100)
11QT_WARNING_DISABLE_MSVC(4146)
12QT_WARNING_DISABLE_MSVC(4267)
13QT_WARNING_DISABLE_MSVC(4624)
14QT_WARNING_DISABLE_GCC("-Wnonnull")
15
16#include <clang/AST/RecursiveASTVisitor.h>
17#include <clang/Frontend/CompilerInstance.h>
18#include <clang/Frontend/FrontendActions.h>
19#include <clang/Tooling/Tooling.h>
20
21QT_WARNING_POP
22
23#include <iostream>
24#include <memory>
25
26QT_BEGIN_NAMESPACE
27
28class Translator;
29
30class LupdateVisitor : public clang::RecursiveASTVisitor<LupdateVisitor>
31{
32public:
33#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(14,0,0))
34 explicit LupdateVisitor(clang::ASTContext *context,
35 clang::Preprocessor *preprocessor, Stores *stores)
36 : m_context(context)
37 , m_preprocessor(preprocessor)
38 , m_stores(stores)
39#else
40 explicit LupdateVisitor(clang::ASTContext *context, Stores *stores)
41 : m_context(context)
42 , m_stores(stores)
43#endif
44 {
45 m_inputFile = m_context->getSourceManager().getFileEntryRefForID(
46 FID: m_context->getSourceManager().getMainFileID())->getName();
47 }
48
49 bool VisitCallExpr(clang::CallExpr *callExpression);
50 void processPreprocessorCalls();
51 bool VisitNamedDecl(clang::NamedDecl *namedDeclaration);
52 void findContextForTranslationStoresFromPP(clang::NamedDecl *namedDeclaration);
53 void generateOutput();
54
55private:
56 std::vector<QString> rawCommentsForCallExpr(const clang::CallExpr *callExpr) const;
57 std::vector<QString> rawCommentsFromSourceLocation(clang::SourceLocation sourceLocation) const;
58
59 void setInfoFromRawComment(const QString &commentString, TranslationRelatedStore *store);
60
61 void processPreprocessorCall(TranslationRelatedStore store);
62 void processIsolatedComments();
63 void processIsolatedComments(const clang::FileID file);
64
65 clang::ASTContext *m_context = nullptr;
66#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(14,0,0))
67 clang::Preprocessor *m_preprocessor = nullptr;
68#endif
69 std::string m_inputFile;
70
71 Stores *m_stores = nullptr;
72
73 TranslationStores m_trCalls;
74 TranslationStores m_qDeclareTrMacroAll;
75 TranslationStores m_noopTranslationMacroAll;
76 bool m_macro = false;
77};
78
79class LupdateASTConsumer : public clang::ASTConsumer
80{
81public:
82#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(14,0,0))
83 explicit LupdateASTConsumer(clang::ASTContext *context, clang::Preprocessor *preprocessor,
84 Stores *stores)
85 : m_visitor(context, preprocessor, stores)
86#else
87 explicit LupdateASTConsumer(clang::ASTContext *context, Stores *stores)
88 : m_visitor(context, stores)
89#endif
90 {}
91
92 // This method is called when the ASTs for entire translation unit have been
93 // parsed.
94 void HandleTranslationUnit(clang::ASTContext &context) override
95 {
96 m_visitor.processPreprocessorCalls();
97 bool traverse = m_visitor.TraverseAST(AST&: context);
98 qCDebug(lcClang) << "TraverseAST: " << traverse;
99 m_visitor.generateOutput();
100 }
101
102private:
103 LupdateVisitor m_visitor;
104};
105
106class LupdateFrontendAction : public clang::ASTFrontendAction
107{
108public:
109 LupdateFrontendAction(Stores *stores)
110 : m_stores(stores)
111 {}
112
113 std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
114 clang::CompilerInstance &compiler, llvm::StringRef /* inFile */) override
115 {
116 #if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(14,0,0))
117 auto consumer = new LupdateASTConsumer(&compiler.getASTContext(),
118 &compiler.getPreprocessor(), m_stores);
119 #else
120 auto consumer = new LupdateASTConsumer(&compiler.getASTContext(), m_stores);
121 #endif
122 return std::unique_ptr<clang::ASTConsumer>(consumer);
123 }
124
125private:
126 Stores *m_stores = nullptr;
127};
128
129class LupdateToolActionFactory : public clang::tooling::FrontendActionFactory
130{
131public:
132 LupdateToolActionFactory(Stores *stores)
133 : m_stores(stores)
134 {}
135
136#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(10,0,0))
137 std::unique_ptr<clang::FrontendAction> create() override
138 {
139 return std::make_unique<LupdateFrontendAction>(args&: m_stores);
140 }
141#else
142 clang::FrontendAction *create() override
143 {
144 return new LupdateFrontendAction(m_stores);
145 }
146#endif
147
148private:
149 Stores *m_stores = nullptr;
150};
151
152QT_END_NAMESPACE
153
154#endif
155

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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