clang 18.0.0git
DeclarationFragments.h
Go to the documentation of this file.
1//===- ExtractAPI/DeclarationFragments.h ------------------------*- C++ -*-===//
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/// \file
10/// This file defines the Declaration Fragments related classes.
11///
12/// Declaration Fragments represent parts of a symbol declaration tagged with
13/// syntactic/semantic information.
14/// See https://github.com/apple/swift-docc-symbolkit
15///
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
19#define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
20
22#include "clang/AST/Decl.h"
23#include "clang/AST/DeclCXX.h"
24#include "clang/AST/DeclObjC.h"
26#include "clang/AST/ExprCXX.h"
27#include "clang/AST/TypeLoc.h"
29#include "clang/Lex/MacroInfo.h"
30#include "llvm/ADT/SmallVector.h"
31#include "llvm/ADT/StringRef.h"
32#include <vector>
33
34namespace clang {
35namespace extractapi {
36
37/// DeclarationFragments is a vector of tagged important parts of a symbol's
38/// declaration.
39///
40/// The fragments sequence can be joined to form spans of declaration text, with
41/// attached information useful for purposes like syntax-highlighting etc.
42/// For example:
43/// \code
44/// const -> keyword "const"
45/// int -> type "int"
46/// pi; -> identifier "pi"
47/// \endcode
49public:
51
52 /// The kind of a fragment.
53 enum class FragmentKind {
54 /// Unknown fragment kind.
55 None,
56
57 Keyword,
62
63 /// Identifier that refers to a type in the context.
65
66 /// Parameter that's used as generics in the context. For example template
67 /// parameters.
69
70 /// External parameters in Objective-C methods.
71 /// For example, \c forKey in
72 /// \code{.m}
73 /// - (void) setValue:(Value)value forKey(Key)key
74 /// \endcode
76
77 /// Internal/local parameters in Objective-C methods.
78 /// For example, \c key in
79 /// \code{.m}
80 /// - (void) setValue:(Value)value forKey(Key)key
81 /// \endcode
83
84 Text,
85 };
86
87 /// Fragment holds information of a single fragment.
88 struct Fragment {
89 std::string Spelling;
91
92 /// The USR of the fragment symbol, if applicable.
93 std::string PreciseIdentifier;
94
95 /// The associated declaration, if applicable. This is not intended to be
96 /// used outside of libclang.
98
100 const Decl *Declaration)
103 };
104
105 using FragmentIterator = std::vector<Fragment>::iterator;
106 using ConstFragmentIterator = std::vector<Fragment>::const_iterator;
107
108 const std::vector<Fragment> &getFragments() const { return Fragments; }
109
110 FragmentIterator begin() { return Fragments.begin(); }
111
112 FragmentIterator end() { return Fragments.end(); }
113
114 ConstFragmentIterator cbegin() const { return Fragments.cbegin(); }
115
116 ConstFragmentIterator cend() const { return Fragments.cend(); }
117
118 // Add a new Fragment at an arbitrary offset.
120 FragmentKind Kind,
121 StringRef PreciseIdentifier = "",
122 const Decl *Declaration = nullptr) {
123 Fragments.insert(It,
124 Fragment(Spelling, Kind, PreciseIdentifier, Declaration));
125 return *this;
126 }
127
130 Fragments.insert(It, std::make_move_iterator(Other.Fragments.begin()),
131 std::make_move_iterator(Other.Fragments.end()));
132 Other.Fragments.clear();
133 return *this;
134 }
135
136 /// Append a new Fragment to the end of the Fragments.
137 ///
138 /// \returns a reference to the DeclarationFragments object itself after
139 /// appending to chain up consecutive appends.
140 DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
141 StringRef PreciseIdentifier = "",
142 const Decl *Declaration = nullptr) {
143 if (Kind == FragmentKind::Text && !Fragments.empty() &&
144 Fragments.back().Kind == FragmentKind::Text) {
145 // If appending a text fragment, and the last fragment is also text,
146 // merge into the last fragment.
147 Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
148 } else {
149 Fragments.emplace_back(Spelling, Kind, PreciseIdentifier, Declaration);
150 }
151 return *this;
152 }
153
154 /// Append another DeclarationFragments to the end.
155 ///
156 /// Note: \p Other is moved from and cannot be used after a call to this
157 /// method.
158 ///
159 /// \returns a reference to the DeclarationFragments object itself after
160 /// appending to chain up consecutive appends.
162 Fragments.insert(Fragments.end(),
163 std::make_move_iterator(Other.Fragments.begin()),
164 std::make_move_iterator(Other.Fragments.end()));
165 Other.Fragments.clear();
166 return *this;
167 }
168
170 Fragments.pop_back();
171 return *this;
172 }
173
174 DeclarationFragments &replace(std::string NewSpelling, unsigned Position) {
175 Fragments.at(Position).Spelling = NewSpelling;
176 return *this;
177 }
178
179 /// Append a text Fragment of a space character.
180 ///
181 /// \returns a reference to the DeclarationFragments object itself after
182 /// appending to chain up consecutive appends.
184
185 /// Get the string description of a FragmentKind \p Kind.
186 static StringRef getFragmentKindString(FragmentKind Kind);
187
188 /// Get the corresponding FragmentKind from string \p S.
189 static FragmentKind parseFragmentKindFromString(StringRef S);
190
193
195
196private:
197 std::vector<Fragment> Fragments;
198};
199
201public:
202 AccessControl(std::string Access) : Access(Access) {}
203
204 const std::string &getAccess() const { return Access; }
205
206 bool empty() const { return Access.empty(); }
207
208private:
209 std::string Access;
210};
211
212/// Store function signature information with DeclarationFragments of the
213/// return type and parameters.
215public:
216 FunctionSignature() = default;
217
218 /// Parameter holds the name and DeclarationFragments of a single parameter.
219 struct Parameter {
220 std::string Name;
222
225 };
226
227 const std::vector<Parameter> &getParameters() const { return Parameters; }
228 const DeclarationFragments &getReturnType() const { return ReturnType; }
229
231 DeclarationFragments Fragments) {
232 Parameters.emplace_back(Name, Fragments);
233 return *this;
234 }
235
236 void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
237
238 /// Determine if the FunctionSignature is empty.
239 ///
240 /// \returns true if the return type DeclarationFragments is empty and there
241 /// is no parameter, otherwise false.
242 bool empty() const {
243 return Parameters.empty() && ReturnType.getFragments().empty();
244 }
245
246private:
247 std::vector<Parameter> Parameters;
248 DeclarationFragments ReturnType;
249};
250
251/// A factory class to build DeclarationFragments for different kinds of Decl.
253public:
254 /// Build FunctionSignature for a function-like declaration \c FunctionT like
255 /// FunctionDecl, ObjCMethodDecl, or CXXMethodDecl.
256 ///
257 /// The logic and implementation of building a signature for a FunctionDecl,
258 /// CXXMethodDecl, and ObjCMethodDecl are exactly the same, but they do not
259 /// share a common base. This template helps reuse the code.
260 template <typename FunctionT>
261 static FunctionSignature getFunctionSignature(const FunctionT *Function);
262
264 switch (Decl->getAccess()) {
265 case AS_public:
266 case AS_none:
267 return AccessControl("public");
268 case AS_private:
269 return AccessControl("private");
270 case AS_protected:
271 return AccessControl("protected");
272 }
273 llvm_unreachable("Unhandled access control");
274 }
275
278
279 /// Build DeclarationFragments for a variable declaration VarDecl.
281
283
284 /// Build DeclarationFragments for a function declaration FunctionDecl.
286
287 /// Build DeclarationFragments for an enum constant declaration
288 /// EnumConstantDecl.
291
292 /// Build DeclarationFragments for an enum declaration EnumDecl.
294
295 /// Build DeclarationFragments for a field declaration FieldDecl.
297
298 /// Build DeclarationFragments for a struct record declaration RecordDecl.
300
302
305
307
310
313
316
317 static std::string
319
322 ASTContext &,
323 const std::optional<ArrayRef<NamedDecl *>>);
324
326
329
332
335
338
341
344
347
348 /// Build DeclarationFragments for an Objective-C category declaration
349 /// ObjCCategoryDecl.
352
353 /// Build DeclarationFragments for an Objective-C interface declaration
354 /// ObjCInterfaceDecl.
357
358 /// Build DeclarationFragments for an Objective-C method declaration
359 /// ObjCMethodDecl.
361
362 /// Build DeclarationFragments for an Objective-C property declaration
363 /// ObjCPropertyDecl.
366
367 /// Build DeclarationFragments for an Objective-C protocol declaration
368 /// ObjCProtocolDecl.
371
372 /// Build DeclarationFragments for a macro.
373 ///
374 /// \param Name name of the macro.
375 /// \param MD the associated MacroDirective.
376 static DeclarationFragments getFragmentsForMacro(StringRef Name,
377 const MacroDirective *MD);
378
379 /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
382
383 /// Build sub-heading fragments for a NamedDecl.
385
386 /// Build sub-heading fragments for an Objective-C method.
388
389 /// Build a sub-heading for macro \p Name.
390 static DeclarationFragments getSubHeadingForMacro(StringRef Name);
391
392private:
394
395 /// Build DeclarationFragments for a QualType.
396 static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
398
399 /// Build DeclarationFragments for a Type.
400 static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
402
403 /// Build DeclarationFragments for a NestedNameSpecifier.
404 static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
405 ASTContext &,
407
408 /// Build DeclarationFragments for Qualifiers.
409 static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
410
411 /// Build DeclarationFragments for a parameter variable declaration
412 /// ParmVarDecl.
413 static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
414
416 getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block,
417 FunctionProtoTypeLoc &BlockProto,
418 DeclarationFragments &After);
419};
420
421template <typename FunctionT>
422FunctionSignature
424 FunctionSignature Signature;
425
426 DeclarationFragments ReturnType, After;
427 ReturnType = getFragmentsForType(Function->getReturnType(),
428 Function->getASTContext(), After);
429 if (isa<FunctionDecl>(Function) &&
430 dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
431 ReturnType.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
432 0) {
433 std::string ProperArgName =
434 getNameForTemplateArgument(dyn_cast<FunctionDecl>(Function)
435 ->getDescribedFunctionTemplate()
436 ->getTemplateParameters()
437 ->asArray(),
438 ReturnType.begin()->Spelling);
439 ReturnType.begin()->Spelling.swap(ProperArgName);
440 }
441 ReturnType.append(std::move(After));
442 Signature.setReturnType(ReturnType);
443
444 for (const auto *Param : Function->parameters())
445 Signature.addParameter(Param->getName(), getFragmentsForParam(Param));
446
447 return Signature;
448}
449
450} // namespace extractapi
451} // namespace clang
452
453#endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines various enumerations that describe declaration and type specifiers.
Defines the clang::TypeLoc interface and its subclasses.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4463
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2855
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2053
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Represents a class template specialization, which refers to a class template with a given set of temp...
Declaration of a C++20 concept.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
AccessSpecifier getAccess() const
Definition: DeclBase.h:512
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3253
Represents an enum.
Definition: Decl.h:3816
Represents a member of a struct/union/class.
Definition: Decl.h:3015
Represents a function declaration or definition.
Definition: Decl.h:1957
Declaration of a template function.
Definition: DeclTemplate.h:977
Wrapper for source info for functions.
Definition: TypeLoc.h:1392
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
Definition: MacroInfo.h:313
This represents a decl that may have a name.
Definition: Decl.h:248
Represent a C++ namespace.
Definition: Decl.h:545
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2323
Represents an ObjC class declaration.
Definition: DeclObjC.h:1150
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:729
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2079
Represents a parameter to a function.
Definition: Decl.h:1747
A (possibly-)qualified type.
Definition: Type.h:736
The collection of all-type qualifiers we support.
Definition: Type.h:146
Represents a struct/union/class.
Definition: Decl.h:4117
Declaration of a redeclarable template.
Definition: DeclTemplate.h:736
The base class of the type hierarchy.
Definition: Type.h:1602
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3383
Represents a variable declaration or definition.
Definition: Decl.h:916
Represents a variable template specialization, which refers to a variable template with a given set o...
const std::string & getAccess() const
A factory class to build DeclarationFragments for different kinds of Decl.
static DeclarationFragments getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *)
static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *)
static DeclarationFragments getFragmentsForEnumConstant(const EnumConstantDecl *)
Build DeclarationFragments for an enum constant declaration EnumConstantDecl.
static DeclarationFragments getFragmentsForObjCCategory(const ObjCCategoryDecl *)
Build DeclarationFragments for an Objective-C category declaration ObjCCategoryDecl.
static DeclarationFragments getFragmentsForTypedef(const TypedefNameDecl *Decl)
Build DeclarationFragments for a typedef TypedefNameDecl.
static DeclarationFragments getFragmentsForEnum(const EnumDecl *)
Build DeclarationFragments for an enum declaration EnumDecl.
static DeclarationFragments getFragmentsForConversionFunction(const CXXConversionDecl *)
static DeclarationFragments getFragmentsForClassTemplateSpecialization(const ClassTemplateSpecializationDecl *)
static DeclarationFragments getFragmentsForTemplateParameters(ArrayRef< NamedDecl * >)
static DeclarationFragments getFragmentsForObjCProtocol(const ObjCProtocolDecl *)
Build DeclarationFragments for an Objective-C protocol declaration ObjCProtocolDecl.
static DeclarationFragments getFragmentsForConcept(const ConceptDecl *)
static DeclarationFragments getFragmentsForField(const FieldDecl *)
Build DeclarationFragments for a field declaration FieldDecl.
static DeclarationFragments getFragmentsForVar(const VarDecl *)
Build DeclarationFragments for a variable declaration VarDecl.
static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(const ClassTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *)
Build DeclarationFragments for an Objective-C method declaration ObjCMethodDecl.
static DeclarationFragments getSubHeadingForMacro(StringRef Name)
Build a sub-heading for macro Name.
static DeclarationFragments getFragmentsForFunction(const FunctionDecl *)
Build DeclarationFragments for a function declaration FunctionDecl.
static AccessControl getAccessControl(const Decl *Decl)
static DeclarationFragments getFragmentsForObjCProperty(const ObjCPropertyDecl *)
Build DeclarationFragments for an Objective-C property declaration ObjCPropertyDecl.
static DeclarationFragments getFragmentsForSpecialCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForNamespace(const NamespaceDecl *Decl)
static DeclarationFragments getFragmentsForStruct(const RecordDecl *)
Build DeclarationFragments for a struct record declaration RecordDecl.
static DeclarationFragments getFragmentsForTemplateArguments(const ArrayRef< TemplateArgument >, ASTContext &, const std::optional< ArrayRef< NamedDecl * > >)
static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(const VarTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl)
static DeclarationFragments getFragmentsForVarTemplateSpecialization(const VarTemplateSpecializationDecl *)
static FunctionSignature getFunctionSignature(const FunctionT *Function)
Build FunctionSignature for a function-like declaration FunctionT like FunctionDecl,...
static DeclarationFragments getSubHeading(const NamedDecl *)
Build sub-heading fragments for a NamedDecl.
static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *)
static std::string getNameForTemplateArgument(const ArrayRef< NamedDecl * >, std::string)
static DeclarationFragments getFragmentsForOverloadedOperator(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl)
static DeclarationFragments getFragmentsForMacro(StringRef Name, const MacroDirective *MD)
Build DeclarationFragments for a macro.
static DeclarationFragments getFragmentsForObjCInterface(const ObjCInterfaceDecl *)
Build DeclarationFragments for an Objective-C interface declaration ObjCInterfaceDecl.
DeclarationFragments is a vector of tagged important parts of a symbol's declaration.
DeclarationFragments & replace(std::string NewSpelling, unsigned Position)
std::vector< Fragment >::iterator FragmentIterator
const std::vector< Fragment > & getFragments() const
DeclarationFragments & appendSpace()
Append a text Fragment of a space character.
DeclarationFragments & append(DeclarationFragments &&Other)
Append another DeclarationFragments to the end.
static DeclarationFragments getExceptionSpecificationString(ExceptionSpecificationType ExceptionSpec)
DeclarationFragments & insert(FragmentIterator It, StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier="", const Decl *Declaration=nullptr)
@ GenericParameter
Parameter that's used as generics in the context.
@ ExternalParam
External parameters in Objective-C methods.
@ TypeIdentifier
Identifier that refers to a type in the context.
@ InternalParam
Internal/local parameters in Objective-C methods.
static StringRef getFragmentKindString(FragmentKind Kind)
Get the string description of a FragmentKind Kind.
static DeclarationFragments getStructureTypeFragment(const RecordDecl *Decl)
std::vector< Fragment >::const_iterator ConstFragmentIterator
DeclarationFragments & insert(FragmentIterator It, DeclarationFragments &&Other)
static FragmentKind parseFragmentKindFromString(StringRef S)
Get the corresponding FragmentKind from string S.
DeclarationFragments & append(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier="", const Decl *Declaration=nullptr)
Append a new Fragment to the end of the Fragments.
Store function signature information with DeclarationFragments of the return type and parameters.
FunctionSignature & addParameter(StringRef Name, DeclarationFragments Fragments)
void setReturnType(DeclarationFragments RT)
const std::vector< Parameter > & getParameters() const
const DeclarationFragments & getReturnType() const
bool empty() const
Determine if the FunctionSignature is empty.
@ Other
Other implicit parameter.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ AS_public
Definition: Specifiers.h:119
@ AS_protected
Definition: Specifiers.h:120
@ AS_none
Definition: Specifiers.h:122
@ AS_private
Definition: Specifiers.h:121
Fragment holds information of a single fragment.
std::string PreciseIdentifier
The USR of the fragment symbol, if applicable.
const Decl * Declaration
The associated declaration, if applicable.
Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier, const Decl *Declaration)
Parameter holds the name and DeclarationFragments of a single parameter.
Parameter(StringRef Name, DeclarationFragments Fragments)