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 explicit LupdateVisitor(clang::ASTContext *context, Stores *stores)
34 : m_context(context)
35 , m_stores(stores)
36 {
37 m_inputFile = m_context->getSourceManager().getFileEntryForID(
38 FID: m_context->getSourceManager().getMainFileID())->getName();
39 }
40
41 bool VisitCallExpr(clang::CallExpr *callExpression);
42 void processPreprocessorCalls();
43 bool VisitNamedDecl(clang::NamedDecl *namedDeclaration);
44 void findContextForTranslationStoresFromPP(clang::NamedDecl *namedDeclaration);
45 void generateOutput();
46
47private:
48 std::vector<QString> rawCommentsForCallExpr(const clang::CallExpr *callExpr) const;
49 std::vector<QString> rawCommentsFromSourceLocation(clang::SourceLocation sourceLocation) const;
50
51 void setInfoFromRawComment(const QString &commentString, TranslationRelatedStore *store);
52
53 void processPreprocessorCall(TranslationRelatedStore store);
54 void processIsolatedComments();
55 void processIsolatedComments(const clang::FileID file);
56
57 clang::ASTContext *m_context = nullptr;
58 std::string m_inputFile;
59
60 Stores *m_stores = nullptr;
61
62 TranslationStores m_trCalls;
63 TranslationStores m_qDeclareTrMacroAll;
64 TranslationStores m_noopTranslationMacroAll;
65 bool m_macro = false;
66};
67
68class LupdateASTConsumer : public clang::ASTConsumer
69{
70public:
71 explicit LupdateASTConsumer(clang::ASTContext *context, Stores *stores)
72 : m_visitor(context, stores)
73 {}
74
75 // This method is called when the ASTs for entire translation unit have been
76 // parsed.
77 void HandleTranslationUnit(clang::ASTContext &context) override
78 {
79 m_visitor.processPreprocessorCalls();
80 bool traverse = m_visitor.TraverseAST(AST&: context);
81 qCDebug(lcClang) << "TraverseAST: " << traverse;
82 m_visitor.generateOutput();
83 }
84
85private:
86 LupdateVisitor m_visitor;
87};
88
89class LupdateFrontendAction : public clang::ASTFrontendAction
90{
91public:
92 LupdateFrontendAction(Stores *stores)
93 : m_stores(stores)
94 {}
95
96 std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
97 clang::CompilerInstance &compiler, llvm::StringRef /* inFile */) override
98 {
99 auto consumer = new LupdateASTConsumer(&compiler.getASTContext(), m_stores);
100 return std::unique_ptr<clang::ASTConsumer>(consumer);
101 }
102
103private:
104 Stores *m_stores = nullptr;
105};
106
107class LupdateToolActionFactory : public clang::tooling::FrontendActionFactory
108{
109public:
110 LupdateToolActionFactory(Stores *stores)
111 : m_stores(stores)
112 {}
113
114#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(10,0,0))
115 std::unique_ptr<clang::FrontendAction> create() override
116 {
117 return std::make_unique<LupdateFrontendAction>(args&: m_stores);
118 }
119#else
120 clang::FrontendAction *create() override
121 {
122 return new LupdateFrontendAction(m_stores);
123 }
124#endif
125
126private:
127 Stores *m_stores = nullptr;
128};
129
130QT_END_NAMESPACE
131
132#endif
133

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