Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
lupdatepreprocessoraction.cpp
Go to the documentation of this file.
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
6
7#include <clang/Lex/MacroArgs.h>
8#include <clang/Basic/TokenKinds.h>
9
10QT_BEGIN_NAMESPACE
11
12void LupdatePPCallbacks::MacroExpands(const clang::Token &token,
13 const clang::MacroDefinition &macroDefinition, clang::SourceRange sourceRange,
14 const clang::MacroArgs *macroArgs)
15{
16 Q_UNUSED(macroDefinition);
17
18 const auto &sm = m_preprocessor.getSourceManager();
19 llvm::StringRef fileName = sm.getFilename(sourceRange.getBegin());
20 if (!LupdatePrivate::isFileSignificant(fileName.str()))
21 return;
22
23 const QString funcName = QString::fromStdString(m_preprocessor.getSpelling(token));
24 switch (trFunctionAliasManager.trFunctionByName(funcName)) {
25 default:
26 return;
27 case TrFunctionAliasManager::Function_Q_DECLARE_TR_FUNCTIONS:
28 case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP:
29 case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP3:
30 case TrFunctionAliasManager::Function_QT_TRID_NOOP:
31 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP:
32 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3:
33 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP_UTF8:
34 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3_UTF8:
35 case TrFunctionAliasManager::Function_QT_TR_NOOP:
36 case TrFunctionAliasManager::Function_QT_TR_NOOP_UTF8:
37 case TrFunctionAliasManager::Function_QT_TR_N_NOOP:
38 qCDebug(lcClang) << "MacroExpands: Function name:" << funcName;
39 break;
40 }
41
43 store.callType = QStringLiteral("MacroExpands");
44 store.funcName = funcName;
45 store.lupdateLocationFile = toQt(fileName);
46 store.lupdateInputFile = toQt(m_inputFile);
47 store.lupdateLocationLine = sm.getExpansionLineNumber(sourceRange.getBegin());
48 store.locationCol = sm.getExpansionColumnNumber(sourceRange.getBegin());
49
50 if (macroArgs) {
51 std::vector<QString> arguments(macroArgs->getNumMacroArguments());
52 for (unsigned i = 0; i < macroArgs->getNumMacroArguments(); i++) {
53 auto preExpArguments = const_cast<clang::MacroArgs*>(macroArgs)->getPreExpArgument(i,
54 m_preprocessor);
55 QString temp;
56 bool errorArgument = false;
57 for (const auto &preExpArgument : preExpArguments) {
58 const auto kind = preExpArgument.getKind();
59 switch (trFunctionAliasManager.trFunctionByName(funcName)) {
60 default:
61 break;
62 case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP:
63 case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP3:
64 case TrFunctionAliasManager::Function_QT_TRID_NOOP:
65 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP:
66 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3:
67 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP_UTF8:
68 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3_UTF8:
69 case TrFunctionAliasManager::Function_QT_TR_NOOP_UTF8:
70 case TrFunctionAliasManager::Function_QT_TR_NOOP:
71 case TrFunctionAliasManager::Function_QT_TR_N_NOOP:
72 if (!clang::tok::isStringLiteral(kind))
73 errorArgument = true;
74 break;
75 }
76 if (errorArgument)
77 break;
78 if (clang::tok::isStringLiteral(kind))
79 temp += LupdatePrivate::cleanQuote(m_preprocessor.getSpelling(preExpArgument));
80 else
81 temp += QString::fromStdString(m_preprocessor.getSpelling(preExpArgument));
82 }
83 arguments[i] = temp;
84 qCDebug(lcClang) << "*********** macro argument : " << temp;
85 }
86 storeMacroArguments(arguments, &store);
87 }
88 if (store.isValid())
89 m_ppStores.emplace_back(std::move(store));
90}
91
92void LupdatePPCallbacks::storeMacroArguments(const std::vector<QString> &args,
94{
95 switch (trFunctionAliasManager.trFunctionByName(store->funcName)) {
96 // only one argument: the context with no "
97 case TrFunctionAliasManager::Function_Q_DECLARE_TR_FUNCTIONS:
98 if (args.size() == 1)
99 store->contextArg = args[0];
100 break;
101 case TrFunctionAliasManager::Function_QT_TR_NOOP_UTF8:
102 case TrFunctionAliasManager::Function_QT_TR_NOOP:
103 case TrFunctionAliasManager::Function_QT_TR_N_NOOP:
104 if (args.size() >= 1)
105 store->lupdateSource = args[0];
106 break;
107 case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP:
108 case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP3:
109 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP:
110 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP_UTF8:
111 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3:
112 case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3_UTF8:
113 if (args.size() >= 2) {
114 store->contextArg = args[0];
115 store->lupdateSource = args[1];
116 }
117 if (args.size() == 3)
118 store->lupdateComment = args[2];
119 break;
120 // only one argument (?) the message Id
121 case TrFunctionAliasManager::Function_QT_TRID_N_NOOP:
122 case TrFunctionAliasManager::Function_qtTrId:
123 case TrFunctionAliasManager::Function_QT_TRID_NOOP:
124 if (args.size() == 1)
125 store->lupdateId = args[0];
126 break;
127 }
128}
129
130// Hook called when a source range is skipped.
131// Emit a warning if translation information is found within this range.
132void LupdatePPCallbacks::SourceRangeSkipped(clang::SourceRange sourceRange,
133 clang::SourceLocation endifLoc)
134{
135 Q_UNUSED(endifLoc);
136
137 const auto &sm = m_preprocessor.getSourceManager();
138 llvm::StringRef fileName = sm.getFilename(sourceRange.getBegin());
139
140 if (!LupdatePrivate::isFileSignificant(fileName.str()))
141 return;
142
143 const char *begin = sm.getCharacterData(sourceRange.getBegin());
144 const char *end = sm.getCharacterData(sourceRange.getEnd());
145 llvm::StringRef skippedText = llvm::StringRef(begin, end - begin);
147 qCDebug(lcClang) << "SourceRangeSkipped: skipped text:" << QString::fromStdString(skippedText.str());
148 unsigned int beginLine = sm.getExpansionLineNumber(sourceRange.getBegin());
149 unsigned int endLine = sm.getExpansionLineNumber(sourceRange.getEnd());
150 qWarning("%s Code with translation information has been skipped "
151 "between lines %d and %d",
152 fileName.str().c_str(), beginLine, endLine);
153 }
154}
155
156// To list the included files
158void LupdatePPCallbacks::InclusionDirective(clang::SourceLocation /*hashLoc*/,
159 const clang::Token & /*includeTok*/, clang::StringRef /*fileName*/, bool /*isAngled*/,
160 clang::CharSourceRange /*filenameRange*/,
165#else
166 const clang::FileEntry *file,
167#endif
168 clang::StringRef /*searchPath*/, clang::StringRef /*relativePath*/,
169 const clang::Module */*imported*/, clang::SrcMgr::CharacteristicKind /*fileType*/)
170{
171 if (!file)
172 return;
173
174 clang::StringRef fileNameRealPath = file->
176 getFileEntry().
177#endif
178 tryGetRealPathName();
179 if (!LupdatePrivate::isFileSignificant(fileNameRealPath.str()))
180 return;
181
183 store.callType = QStringLiteral("InclusionDirective");
184 store.lupdateLocationFile = toQt(fileNameRealPath);
185 store.lupdateLocationLine = 1;
186 store.locationCol = 1;
187 store.lupdateInputFile = toQt(m_inputFile);
188 // do not fill the store.funcName. There is no function at this point
189 // the information is retrieved here to look for TRANSLATOR comments in header files
190 // when traversing the AST
191
192 if (store.isValid())
193 m_ppStores.emplace_back(std::move(store));
194}
195#endif
196
197QT_END_NAMESPACE
void InclusionDirective(clang::SourceLocation, const clang::Token &, clang::StringRef, bool, clang::CharSourceRange, const clang::FileEntry *file, clang::StringRef, clang::StringRef, const clang::Module *, clang::SrcMgr::CharacteristicKind) override
void SourceRangeSkipped(clang::SourceRange sourceRange, clang::SourceLocation endifLoc) override
#define LUPDATE_CLANG_VERSION
Definition cpp_clang.h:42
#define LUPDATE_CLANG_VERSION_CHECK(major, minor, patch)
Definition cpp_clang.h:41
bool stringContainsTranslationInformation(llvm::StringRef ba)
bool isFileSignificant(const std::string &filePath)