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
QualTypeNames.h
Go to the documentation of this file.
1//===------- QualTypeNames.cpp - Generate Complete QualType Names ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11// Those directives indirectly includes "clang/AST/Attrs.h" which
12// includes "clang/AST/Attrs.inc".
13// "clang/AST/Attrs.inc", produces some "C4267" warnings specifically
14// on MSVC 2019.
15// This in turn blocks CI integrations for configuration with that
16// compiler that treats warnings as errors.
17// As that header is not under our control, we disable the warning
18// completely when going through those includes.
19#include <QtCore/qcompilerdetection.h>
20
21QT_WARNING_PUSH
22QT_WARNING_DISABLE_MSVC(4267)
23
24#include "clang/AST/DeclTemplate.h"
25#include "clang/AST/DeclarationName.h"
26#include "clang/AST/GlobalDecl.h"
27#include "clang/AST/Mangle.h"
28
29QT_WARNING_POP
30
31#include <stdio.h>
32#include <memory>
33
34namespace clang {
35
36namespace TypeName {
37
38inline QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
39 bool WithGlobalNsPrefix);
40
41/// Create a NestedNameSpecifier for Namesp and its enclosing
42/// scopes.
43///
44/// \param[in] Ctx - the AST Context to be used.
45/// \param[in] Namesp - the NamespaceDecl for which a NestedNameSpecifier
46/// is requested.
47/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
48/// specifier "::" should be prepended or not.
49static inline NestedNameSpecifier *createNestedNameSpecifier(
50 const ASTContext &Ctx,
51 const NamespaceDecl *Namesp,
52 bool WithGlobalNsPrefix);
53
54/// Create a NestedNameSpecifier for TagDecl and its enclosing
55/// scopes.
56///
57/// \param[in] Ctx - the AST Context to be used.
58/// \param[in] TD - the TagDecl for which a NestedNameSpecifier is
59/// requested.
60/// \param[in] FullyQualify - Convert all template arguments into fully
61/// qualified names.
62/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
63/// specifier "::" should be prepended or not.
64static inline NestedNameSpecifier *createNestedNameSpecifier(
65 const ASTContext &Ctx, const TypeDecl *TD,
66 bool FullyQualify, bool WithGlobalNsPrefix);
67
68static inline NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
69 const ASTContext &Ctx, const Decl *decl,
70 bool FullyQualified, bool WithGlobalNsPrefix);
71
72static inline NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
73 const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix);
74
75static inline bool getFullyQualifiedTemplateName(const ASTContext &Ctx,
76 TemplateName &TName,
77 bool WithGlobalNsPrefix) {
78 bool Changed = false;
79 NestedNameSpecifier *NNS = nullptr;
80
81 TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
82 // ArgTDecl won't be NULL because we asserted that this isn't a
83 // dependent context very early in the call chain.
84 assert(ArgTDecl != nullptr);
85 QualifiedTemplateName *QTName = TName.getAsQualifiedTemplateName();
86
87 if (QTName &&
88 !QTName->hasTemplateKeyword() &&
89 (NNS = QTName->getQualifier())) {
90 NestedNameSpecifier *QNNS = getFullyQualifiedNestedNameSpecifier(
91 Ctx, NNS, WithGlobalNsPrefix);
92 if (QNNS != NNS) {
93 Changed = true;
94 NNS = QNNS;
95 } else {
96 NNS = nullptr;
97 }
98 } else {
99 NNS = createNestedNameSpecifierForScopeOf(
100 Ctx, ArgTDecl, true, WithGlobalNsPrefix);
101 }
102 if (NNS) {
103 TemplateName UnderlyingTN(ArgTDecl);
104 if (UsingShadowDecl *USD = TName.getAsUsingShadowDecl())
105 UnderlyingTN = TemplateName(USD);
106 TName =
107 Ctx.getQualifiedTemplateName(NNS,
108 /*TemplateKeyword=*/false, UnderlyingTN);
109 Changed = true;
110 }
111 return Changed;
112}
113
114static inline bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx,
115 TemplateArgument &Arg,
116 bool WithGlobalNsPrefix) {
117 bool Changed = false;
118
119 // Note: we do not handle TemplateArgument::Expression, to replace it
120 // we need the information for the template instance decl.
121
122 if (Arg.getKind() == TemplateArgument::Template) {
123 TemplateName TName = Arg.getAsTemplate();
124 Changed = getFullyQualifiedTemplateName(Ctx, TName, WithGlobalNsPrefix);
125 if (Changed) {
126 Arg = TemplateArgument(TName);
127 }
128 } else if (Arg.getKind() == TemplateArgument::Type) {
129 QualType SubTy = Arg.getAsType();
130 // Check if the type needs more desugaring and recurse.
131 QualType QTFQ = getFullyQualifiedType(SubTy, Ctx, WithGlobalNsPrefix);
132 if (QTFQ != SubTy) {
133 Arg = TemplateArgument(QTFQ);
134 Changed = true;
135 }
136 }
137 return Changed;
138}
139
140static inline const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx,
141 const Type *TypePtr,
142 bool WithGlobalNsPrefix) {
143 // DependentTemplateTypes exist within template declarations and
144 // definitions. Therefore we shouldn't encounter them at the end of
145 // a translation unit. If we do, the caller has made an error.
146 assert(!isa<DependentTemplateSpecializationType>(TypePtr));
147 // In case of template specializations, iterate over the arguments
148 // and fully qualify them as well.
149 if (const auto *TST = dyn_cast<const TemplateSpecializationType>(TypePtr)) {
150 bool MightHaveChanged = false;
151 SmallVector<TemplateArgument, 4> FQArgs;
152 // Cheap to copy and potentially modified by
153 // getFullyQualifedTemplateArgument.
154 for (TemplateArgument Arg : TST->template_arguments()) {
155 MightHaveChanged |= getFullyQualifiedTemplateArgument(
156 Ctx, Arg, WithGlobalNsPrefix);
157 FQArgs.push_back(Arg);
158 }
159
160 // If a fully qualified arg is different from the unqualified arg,
161 // allocate new type in the AST.
162 if (MightHaveChanged) {
163 QualType QT = Ctx.getTemplateSpecializationType(
164 TST->getTemplateName(), FQArgs,
165 TST->getCanonicalTypeInternal());
166 // getTemplateSpecializationType returns a fully qualified
167 // version of the specialization itself, so no need to qualify
168 // it.
169 return QT.getTypePtr();
170 }
171 } else if (const auto *TSTRecord = dyn_cast<const RecordType>(TypePtr)) {
172 // We are asked to fully qualify and we have a Record Type,
173 // which can point to a template instantiation with no sugar in any of
174 // its template argument, however we still need to fully qualify them.
175
176 if (const auto *TSTDecl =
177 dyn_cast<ClassTemplateSpecializationDecl>(TSTRecord->getDecl())) {
178 const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
179
180 bool MightHaveChanged = false;
181 SmallVector<TemplateArgument, 4> FQArgs;
182 for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
183 // cheap to copy and potentially modified by
184 // getFullyQualifedTemplateArgument
185 TemplateArgument Arg(TemplateArgs[I]);
186 MightHaveChanged |= getFullyQualifiedTemplateArgument(
187 Ctx, Arg, WithGlobalNsPrefix);
188 FQArgs.push_back(Arg);
189 }
190
191 // If a fully qualified arg is different from the unqualified arg,
192 // allocate new type in the AST.
193 if (MightHaveChanged) {
194 TemplateName TN(TSTDecl->getSpecializedTemplate());
195 QualType QT = Ctx.getTemplateSpecializationType(
196 TN, FQArgs,
197 TSTRecord->getCanonicalTypeInternal());
198 // getTemplateSpecializationType returns a fully qualified
199 // version of the specialization itself, so no need to qualify
200 // it.
201 return QT.getTypePtr();
202 }
203 }
204 }
205 return TypePtr;
206}
207
208static inline NestedNameSpecifier *createOuterNNS(const ASTContext &Ctx, const Decl *D,
209 bool FullyQualify,
210 bool WithGlobalNsPrefix) {
211 const DeclContext *DC = D->getDeclContext();
212 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
213 while (NS && NS->isInline()) {
214 // Ignore inline namespace;
215 NS = dyn_cast<NamespaceDecl>(NS->getDeclContext());
216 }
217 if (NS && NS->getDeclName()) {
218 return createNestedNameSpecifier(Ctx, NS, WithGlobalNsPrefix);
219 }
220 return nullptr; // no starting '::', no anonymous
221 } else if (const auto *TD = dyn_cast<TagDecl>(DC)) {
222 return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
223 } else if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC)) {
224 return createNestedNameSpecifier(
225 Ctx, TDD, FullyQualify, WithGlobalNsPrefix);
226 } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
227 return NestedNameSpecifier::GlobalSpecifier(Ctx);
228 }
229 return nullptr; // no starting '::' if |WithGlobalNsPrefix| is false
230}
231
232/// Return a fully qualified version of this name specifier.
233static inline NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
234 const ASTContext &Ctx, NestedNameSpecifier *Scope,
235 bool WithGlobalNsPrefix) {
236 switch (Scope->getKind()) {
237 case NestedNameSpecifier::Global:
238 // Already fully qualified
239 return Scope;
240 case NestedNameSpecifier::Namespace:
242 Ctx, Scope->getAsNamespace(), WithGlobalNsPrefix);
243 case NestedNameSpecifier::NamespaceAlias:
244 // Namespace aliases are only valid for the duration of the
245 // scope where they were introduced, and therefore are often
246 // invalid at the end of the TU. So use the namespace name more
247 // likely to be valid at the end of the TU.
249 Ctx,
250 Scope->getAsNamespaceAlias()->getNamespace()->getCanonicalDecl(),
251 WithGlobalNsPrefix);
252 case NestedNameSpecifier::Identifier:
253 // A function or some other construct that makes it un-namable
254 // at the end of the TU. Skip the current component of the name,
255 // but use the name of it's prefix.
257 Ctx, Scope->getPrefix(), WithGlobalNsPrefix);
258 case NestedNameSpecifier::Super:
259 case NestedNameSpecifier::TypeSpec:
260 case NestedNameSpecifier::TypeSpecWithTemplate: {
261 const Type *Type = Scope->getAsType();
262 // Find decl context.
263 const TagDecl *TD = nullptr;
264 if (const TagType *TagDeclType = Type->getAs<TagType>()) {
265 TD = TagDeclType->getDecl();
266 } else {
267 TD = Type->getAsCXXRecordDecl();
268 }
269 if (TD) {
270 return TypeName::createNestedNameSpecifier(Ctx, TD,
271 true /*FullyQualified*/,
272 WithGlobalNsPrefix);
273 } else if (const auto *TDD = dyn_cast<TypedefType>(Type)) {
274 return TypeName::createNestedNameSpecifier(Ctx, TDD->getDecl(),
275 true /*FullyQualified*/,
276 WithGlobalNsPrefix);
277 }
278 return Scope;
279 }
280 }
281 llvm_unreachable("bad NNS kind");
282}
283
284/// Create a nested name specifier for the declaring context of
285/// the type.
286static inline NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
287 const ASTContext &Ctx, const Decl *Decl,
288 bool FullyQualified, bool WithGlobalNsPrefix) {
289 assert(Decl);
290
291 const DeclContext *DC = Decl->getDeclContext()->getRedeclContext();
292 const auto *Outer = dyn_cast<NamedDecl>(DC);
293 const auto *OuterNS = dyn_cast<NamespaceDecl>(DC);
294 if (Outer && !(OuterNS && OuterNS->isAnonymousNamespace())) {
295 if (OuterNS) {
296 return createNestedNameSpecifier(Ctx, OuterNS, WithGlobalNsPrefix);
297 } else if (const auto *TD = dyn_cast<TagDecl>(Outer)) {
298 return createNestedNameSpecifier(
299 Ctx, TD, FullyQualified, WithGlobalNsPrefix);
300 } else if (isa<TranslationUnitDecl>(Outer)) {
301 // Context is the TU. Nothing needs to be done.
302 return nullptr;
303 } else {
304 // Decl's context was neither the TU, a namespace, nor a
305 // TagDecl, which means it is a type local to a scope, and not
306 // accessible at the end of the TU.
307 return nullptr;
308 }
309 } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
310 return NestedNameSpecifier::GlobalSpecifier(Ctx);
311 }
312 return nullptr;
313}
314
315/// Create a nested name specifier for the declaring context of
316/// the type.
317static inline NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
318 const ASTContext &Ctx, const Type *TypePtr,
319 bool FullyQualified, bool WithGlobalNsPrefix) {
320 if (!TypePtr) return nullptr;
321
322 Decl *Decl = nullptr;
323 // There are probably other cases ...
324 if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
325 Decl = TDT->getDecl();
326 } else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
327 Decl = TagDeclType->getDecl();
328 } else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
329 Decl = TST->getTemplateName().getAsTemplateDecl();
330 } else {
331 Decl = TypePtr->getAsCXXRecordDecl();
332 }
333
334 if (!Decl) return nullptr;
335
337 Ctx, Decl, FullyQualified, WithGlobalNsPrefix);
338}
339
340inline NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
341 const NamespaceDecl *Namespace,
342 bool WithGlobalNsPrefix) {
343 while (Namespace && Namespace->isInline()) {
344 // Ignore inline namespace;
345 Namespace = dyn_cast<NamespaceDecl>(Namespace->getDeclContext());
346 }
347 if (!Namespace) return nullptr;
348
349 bool FullyQualified = true; // doesn't matter, DeclContexts are namespaces
350 return NestedNameSpecifier::Create(
351 Ctx,
352 createOuterNNS(Ctx, Namespace, FullyQualified, WithGlobalNsPrefix),
353 Namespace);
354}
355
356inline NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
357 const TypeDecl *TD,
358 bool FullyQualify,
359 bool WithGlobalNsPrefix) {
360 const Type *TypePtr = TD->getTypeForDecl();
361 if (isa<const TemplateSpecializationType>(TypePtr) ||
362 isa<const RecordType>(TypePtr)) {
363 // We are asked to fully qualify and we have a Record Type (which
364 // may point to a template specialization) or Template
365 // Specialization Type. We need to fully qualify their arguments.
366
367 TypePtr = getFullyQualifiedTemplateType(Ctx, TypePtr, WithGlobalNsPrefix);
368 }
369
370 return NestedNameSpecifier::Create(
371 Ctx, createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
372 false /*No TemplateKeyword*/, TypePtr);
373}
374
375/// Return the fully qualified type, including fully-qualified
376/// versions of any template parameters.
377inline QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
378 bool WithGlobalNsPrefix = false) {
379 // In case of myType* we need to strip the pointer first, fully
380 // qualify and attach the pointer once again.
381 if (isa<PointerType>(QT.getTypePtr())) {
382 // Get the qualifiers.
383 Qualifiers Quals = QT.getQualifiers();
384 QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
385 QT = Ctx.getPointerType(QT);
386 // Add back the qualifiers.
387 QT = Ctx.getQualifiedType(QT, Quals);
388 return QT;
389 }
390
391 if (auto *MPT = dyn_cast<MemberPointerType>(QT.getTypePtr())) {
392 // Get the qualifiers.
393 Qualifiers Quals = QT.getQualifiers();
394 // Fully qualify the pointee and class types.
395 QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
396 QualType Class = getFullyQualifiedType(QualType(MPT->getClass(), 0), Ctx,
397 WithGlobalNsPrefix);
398 QT = Ctx.getMemberPointerType(QT, Class.getTypePtr());
399 // Add back the qualifiers.
400 QT = Ctx.getQualifiedType(QT, Quals);
401 return QT;
402 }
403
404 // In case of myType& we need to strip the reference first, fully
405 // qualify and attach the reference once again.
406 if (isa<ReferenceType>(QT.getTypePtr())) {
407 // Get the qualifiers.
408 bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
409 Qualifiers Quals = QT.getQualifiers();
410 QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
411 // Add the r- or l-value reference type back to the fully
412 // qualified one.
413 if (IsLValueRefTy)
414 QT = Ctx.getLValueReferenceType(QT);
415 else
416 QT = Ctx.getRValueReferenceType(QT);
417 // Add back the qualifiers.
418 QT = Ctx.getQualifiedType(QT, Quals);
419 return QT;
420 }
421
422 // Remove the part of the type related to the type being a template
423 // parameter (we won't report it as part of the 'type name' and it
424 // is actually make the code below to be more complex (to handle
425 // those)
426 while (isa<SubstTemplateTypeParmType>(QT.getTypePtr())) {
427 // Get the qualifiers.
428 Qualifiers Quals = QT.getQualifiers();
429
430 QT = cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();
431
432 // Add back the qualifiers.
433 QT = Ctx.getQualifiedType(QT, Quals);
434 }
435
436 NestedNameSpecifier *Prefix = nullptr;
437 // Local qualifiers are attached to the QualType outside of the
438 // elaborated type. Retrieve them before descending into the
439 // elaborated type.
440 Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
441 QT = QualType(QT.getTypePtr(), 0);
442#if LIBCLANG_VERSION_MAJOR >= 18
443 constexpr ElaboratedTypeKeyword ETK_None = ElaboratedTypeKeyword::None;
444#endif
445 ElaboratedTypeKeyword Keyword = ETK_None;
446 if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
447 QT = ETypeInput->getNamedType();
448 assert(!QT.hasLocalQualifiers());
449 Keyword = ETypeInput->getKeyword();
450 }
451
452 // We don't consider the alias introduced by `using a::X` as a new type.
453 // The qualified name is still a::X.
454 if (const auto *UT = QT->getAs<UsingType>()) {
455 QT = Ctx.getQualifiedType(UT->getUnderlyingType(), PrefixQualifiers);
456 return getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
457 }
458
459 // Create a nested name specifier if needed.
460 Prefix = createNestedNameSpecifierForScopeOf(Ctx, QT.getTypePtr(),
461 true /*FullyQualified*/,
462 WithGlobalNsPrefix);
463
464 // In case of template specializations iterate over the arguments and
465 // fully qualify them as well.
466 if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
467 isa<const RecordType>(QT.getTypePtr())) {
468 // We are asked to fully qualify and we have a Record Type (which
469 // may point to a template specialization) or Template
470 // Specialization Type. We need to fully qualify their arguments.
471
472 const Type *TypePtr = getFullyQualifiedTemplateType(
473 Ctx, QT.getTypePtr(), WithGlobalNsPrefix);
474 QT = QualType(TypePtr, 0);
475 }
476 if (Prefix || Keyword != ETK_None) {
477 QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
478 }
479 QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
480 return QT;
481}
482
483inline std::string getFullyQualifiedName(QualType QT,
484 const ASTContext &Ctx,
485 const PrintingPolicy &Policy,
486 bool WithGlobalNsPrefix = false) {
487 QualType FQQT = getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
488 return FQQT.getAsString(Policy);
489}
490
491} // end namespace TypeName
492} // end namespace clang
static const clang::Decl * get_cursor_declaration(CXCursor cursor)
Returns the underlying Decl that cursor represents.
static QString reconstructQualifiedPathForCursor(CXCursor cur)
Reconstruct the qualified path name of a function that is being overridden.
QString functionName(CXCursor cursor)
Returns the function name from a given cursor representing a function declaration.
static std::string get_default_value_initializer_as_string(const clang::TemplateTemplateParmDecl *parameter)
static QString fromCXString(CXString &&string)
convert a CXString to a QString, and dispose the CXString
static QDebug operator<<(QDebug debug, const std::vector< T > &v)
static QString getSpelling(CXSourceRange range)
static void setOverridesForFunction(FunctionNode *fn, CXCursor cursor)
static QList< QByteArray > includePathsFromHeaders(const std::set< Config::HeaderFilePath > &allHeaders)
static const auto kClangDontDisplayDiagnostics
void getMoreArgs(const std::vector< QByteArray > &include_paths, const std::set< Config::HeaderFilePath > &all_headers, std::vector< const char * > &args)
Load the include paths into moreArgs.
static std::string get_default_value_initializer_as_string(const clang::ParmVarDecl *parameter)
void getDefaultArgs(const QList< QByteArray > &defines, std::vector< const char * > &args)
Load the default arguments and the defines into args.
static std::string get_expression_as_string(const clang::Expr *expression, const clang::ASTContext &declaration_context)
bool visitChildrenLambda(CXCursor cursor, T &&lambda)
Call clang_visitChildren on the given cursor with the lambda as a callback T can be any functor that ...
static std::string get_default_value_initializer_as_string(const clang::NamedDecl *declaration)
static RelaxedTemplateDeclaration get_template_declaration(const clang::TemplateDecl *template_declaration)
static std::string get_default_value_initializer_as_string(const clang::NonTypeTemplateParmDecl *parameter)
static QString fromCache(const QByteArray &cache, unsigned int offset1, unsigned int offset2)
static float getUnpatchedVersion(QString t)
std::optional< PCHFile > buildPCH(QDocDatabase *qdb, QString module_header, const std::set< Config::HeaderFilePath > &all_headers, const std::vector< QByteArray > &include_paths, const QList< QByteArray > &defines)
Building the PCH must be possible when there are no .cpp files, so it is moved here to its own member...
static Location fromCXSourceLocation(CXSourceLocation location)
convert a CXSourceLocation to a qdoc Location
static Access fromCX_CXXAccessSpecifier(CX_CXXAccessSpecifier spec)
convert a CX_CXXAccessSpecifier to Node::Access
static std::string get_default_value_initializer_as_string(const clang::TemplateTypeParmDecl *parameter)
constexpr const char fnDummyFileName[]
static CXTranslationUnit_Flags flags_
static Node * findNodeForCursor(QDocDatabase *qdb, CXCursor cur)
Find the node from the QDocDatabase qdb that corresponds to the declaration represented by the cursor...
static std::string get_fully_qualified_type_name(clang::QualType type, const clang::ASTContext &declaration_context)
Returns a string representing the name of type as if it was referred to at the end of the translation...
static void printDiagnostics(const CXTranslationUnit &translationUnit)
static const char * defaultArgs_[]
static QString readFile(CXFile cxFile, unsigned int offset1, unsigned int offset2)
void addChild(Node *child)
Adds the child to this node's child list and sets the child's parent pointer to this Aggregate.
ParsedCppFileIR parse_cpp_file(const QString &filePath)
Get ready to parse the C++ cpp file identified by filePath and add its parsed contents to the databas...
ClangCodeParser(QDocDatabase *qdb, Config &, const std::vector< QByteArray > &include_paths, const QList< QByteArray > &defines, std::optional< std::reference_wrapper< const PCHFile > > pch)
ClangVisitor(QDocDatabase *qdb, const std::set< Config::HeaderFilePath > &allHeaders)
Node * nodeForCommentAtLocation(CXSourceLocation loc, CXSourceLocation nextCommentLoc)
Given a comment at location loc, return a Node for this comment nextCommentLoc is the location of the...
CXChildVisitResult visitChildren(CXCursor cursor)
QDocDatabase * qdocDB()
CXChildVisitResult visitFnArg(CXCursor cursor, Node **fnNode, bool &ignoreSignature)
The ClassNode represents a C++ class.
Definition classnode.h:21
void addResolvedBaseClass(Access access, ClassNode *node)
Adds the base class node to this class's list of base classes.
Definition classnode.cpp:27
static bool isWorthWarningAbout(const Doc &doc)
Test for whether a doc comment warrants warnings.
The Config class contains the configuration variables for controlling how qdoc produces documentation...
Definition config.h:84
Definition doc.h:31
const Location & location() const
Returns the starting location of a qdoc comment.
Definition doc.cpp:90
TopicList topicsUsed() const
Returns a reference to the list of topic commands used in the current qdoc comment.
Definition doc.cpp:238
void setFlagsType(TypedefNode *typedefNode)
Definition enumnode.cpp:76
This node is used to represent any kind of function being documented.
void setConst(bool b)
void setStatic(bool b)
void setVirtualness(Virtualness virtualness)
bool isNonvirtual() const
void setInvokable(bool b)
void setRef(bool b)
void setOverride(bool b)
void setRefRef(bool b)
void markConstexpr()
void markExplicit()
void setMetaness(Metaness metaness)
Parameters & parameters()
The Location class provides a way to mark a location in a file.
Definition location.h:15
void setColumnNo(int no)
Definition location.h:36
void setLineNo(int no)
Definition location.h:35
This class represents a C++ namespace.
void setGenus(Genus t)
Definition node.h:125
void setAccess(Access t)
Sets the node's access type to t.
Definition node.h:203
NodeType
An unsigned char value that identifies an object as a particular subclass of Node.
Definition node.h:54
@ Variable
Definition node.h:69
@ Struct
Definition node.h:58
@ Union
Definition node.h:59
@ Class
Definition node.h:57
bool isNamespace() const
Returns true if the node type is Namespace.
Definition node.h:143
bool isTypedef() const
Returns true if the node type is Typedef.
Definition node.h:160
bool isFunction(Genus g=DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
Definition node.h:135
bool isEnumType() const
Returns true if the node type is Enum.
Definition node.h:132
bool isVariable() const
Returns true if the node type is Variable.
Definition node.h:165
void setLocation(const Location &t)
Sets the node's declaration location, its definition location, or both, depending on the suffix of th...
Definition node.cpp:886
virtual bool isAggregate() const
Returns true if this node is an aggregate, which means it inherits Aggregate and can therefore have c...
Definition node.h:170
virtual void setRelatedNonmember(bool b)
Sets a flag in the node indicating whether this node is a related nonmember of something.
Definition node.h:218
@ CPP
Definition node.h:83
bool isClass() const
Returns true if the node type is Class.
Definition node.h:129
LinkType
An unsigned char value that probably should be moved out of the Node base class.
Definition node.h:112
virtual bool isClassNode() const
Returns true if this is an instance of ClassNode.
Definition node.h:177
A class for parsing and managing a function parameter list.
Definition parameters.h:57
Parameter & operator[](int index)
Definition parameters.h:77
void pop_back()
Definition parameters.h:81
void reserve(int count)
Definition parameters.h:73
void clear()
Definition parameters.h:62
Parameter & last()
Definition parameters.h:75
int count() const
Definition parameters.h:72
void setPrivateSignal()
Definition parameters.h:82
This class describes one instance of using the Q_PROPERTY macro.
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
NamespaceNode * primaryTreeRoot()
Returns a pointer to the root node of the primary tree.
void setStatic(bool b)
const QString & leftType() const
Node * clone(Aggregate *parent) override
Clone this node on the heap and make the clone a child of parent.
bool isStatic() const override
Returns true if the FunctionNode represents a static function.
QString dataType() const
const QString & rightType() const
#define COMMAND_SINCE
Definition codeparser.h:73
#define COMMAND_FN
Definition codeparser.h:26
#define COMMAND_PAGE
Definition codeparser.h:44
#define CONFIG_VERSION
Definition config.h:394
bool hasTooManyTopics(const Doc &doc)
Checks if there are too many topic commands in doc.
Combined button and popup list for selecting options.
static NestedNameSpecifier * createOuterNNS(const ASTContext &Ctx, const Decl *D, bool FullyQualify, bool WithGlobalNsPrefix)
QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, bool WithGlobalNsPrefix)
static bool getFullyQualifiedTemplateName(const ASTContext &Ctx, TemplateName &TName, bool WithGlobalNsPrefix)
static const Type * getFullyQualifiedTemplateType(const ASTContext &Ctx, const Type *TypePtr, bool WithGlobalNsPrefix)
static NestedNameSpecifier * createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Type *TypePtr, bool FullyQualified, bool WithGlobalNsPrefix)
static NestedNameSpecifier * createNestedNameSpecifier(const ASTContext &Ctx, const TypeDecl *TD, bool FullyQualify, bool WithGlobalNsPrefix)
static NestedNameSpecifier * createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Decl *decl, bool FullyQualified, bool WithGlobalNsPrefix)
static NestedNameSpecifier * getFullyQualifiedNestedNameSpecifier(const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix)
Return a fully qualified version of this name specifier.
static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx, TemplateArgument &Arg, bool WithGlobalNsPrefix)
std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx, const PrintingPolicy &Policy, bool WithGlobalNsPrefix=false)
static NestedNameSpecifier * createNestedNameSpecifier(const ASTContext &Ctx, const NamespaceDecl *Namesp, bool WithGlobalNsPrefix)
QList< Node * > NodeVector
Definition node.h:43
#define assert
Returns the spelling in the file for a source range.
std::variant< Node *, FnMatchError > operator()(const Location &location, const QString &fnSignature, const QString &idTag, QStringList context)
Use clang to parse the function signature from a function command.
Encapsulates information about.
Definition parsererror.h:13
CXTranslationUnit tu