clang 18.0.0git
DeclarationFragments.cpp
Go to the documentation of this file.
1//===- ExtractAPI/DeclarationFragments.cpp ----------------------*- 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 implements Declaration Fragments related classes.
11///
12//===----------------------------------------------------------------------===//
13
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclCXX.h"
21#include "llvm/ADT/StringSwitch.h"
22#include <typeinfo>
23
24using namespace clang::extractapi;
25using namespace llvm;
26
28 if (!Fragments.empty()) {
29 Fragment &Last = Fragments.back();
30 if (Last.Kind == FragmentKind::Text) {
31 // Merge the extra space into the last fragment if the last fragment is
32 // also text.
33 if (Last.Spelling.back() != ' ') { // avoid extra trailing spaces.
34 Last.Spelling.push_back(' ');
35 }
36 } else {
38 }
39 }
40
41 return *this;
42}
43
46 switch (Kind) {
48 return "none";
50 return "keyword";
52 return "attribute";
54 return "number";
56 return "string";
58 return "identifier";
60 return "typeIdentifier";
62 return "genericParameter";
64 return "externalParam";
66 return "internalParam";
68 return "text";
69 }
70
71 llvm_unreachable("Unhandled FragmentKind");
72}
73
76 return llvm::StringSwitch<FragmentKind>(S)
82 .Case("typeIdentifier",
84 .Case("genericParameter",
90}
91
93 ExceptionSpecificationType ExceptionSpec) {
94 DeclarationFragments Fragments;
95 switch (ExceptionSpec) {
97 return Fragments;
104 // FIXME: throw(int), get types of inner expression
105 return Fragments;
110 // FIXME: throw(conditional-expression), get expression
111 break;
124 default:
125 return Fragments;
126 }
127
128 llvm_unreachable("Unhandled exception specification");
129}
130
133 DeclarationFragments Fragments;
134 if (Record->isStruct())
136 else if (Record->isUnion())
138 else
140
141 return Fragments;
142}
143
144// NNS stores C++ nested name specifiers, which are prefixes to qualified names.
145// Build declaration fragments for NNS recursively so that we have the USR for
146// every part in a qualified name, and also leaves the actual underlying type
147// cleaner for its own fragment.
149DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS,
150 ASTContext &Context,
151 DeclarationFragments &After) {
152 DeclarationFragments Fragments;
153 if (NNS->getPrefix())
154 Fragments.append(getFragmentsForNNS(NNS->getPrefix(), Context, After));
155
156 switch (NNS->getKind()) {
158 Fragments.append(NNS->getAsIdentifier()->getName(),
160 break;
161
163 const NamespaceDecl *NS = NNS->getAsNamespace();
164 if (NS->isAnonymousNamespace())
165 return Fragments;
168 Fragments.append(NS->getName(),
170 break;
171 }
172
174 const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias();
176 index::generateUSRForDecl(Alias, USR);
177 Fragments.append(Alias->getName(),
179 Alias);
180 break;
181 }
182
184 // The global specifier `::` at the beginning. No stored value.
185 break;
186
188 // Microsoft's `__super` specifier.
190 break;
191
193 // A type prefixed by the `template` keyword.
195 Fragments.appendSpace();
196 // Fallthrough after adding the keyword to handle the actual type.
197 [[fallthrough]];
198
200 const Type *T = NNS->getAsType();
201 // FIXME: Handle C++ template specialization type
202 Fragments.append(getFragmentsForType(T, Context, After));
203 break;
204 }
205 }
206
207 // Add the separator text `::` for this segment.
208 return Fragments.append("::", DeclarationFragments::FragmentKind::Text);
209}
210
211// Recursively build the declaration fragments for an underlying `Type` with
212// qualifiers removed.
213DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
214 const Type *T, ASTContext &Context, DeclarationFragments &After) {
215 assert(T && "invalid type");
216
217 DeclarationFragments Fragments;
218
219 // Declaration fragments of a pointer type is the declaration fragments of
220 // the pointee type followed by a `*`,
221 if (T->isPointerType())
222 return Fragments
223 .append(getFragmentsForType(T->getPointeeType(), Context, After))
225
226 // For Objective-C `id` and `Class` pointers
227 // we do not spell out the `*`.
228 if (T->isObjCObjectPointerType() &&
230
231 Fragments.append(getFragmentsForType(T->getPointeeType(), Context, After));
232
233 // id<protocol> is an qualified id type
234 // id<protocol>* is not an qualified id type
237 }
238
239 return Fragments;
240 }
241
242 // Declaration fragments of a lvalue reference type is the declaration
243 // fragments of the underlying type followed by a `&`.
244 if (const LValueReferenceType *LRT = dyn_cast<LValueReferenceType>(T))
245 return Fragments
246 .append(
247 getFragmentsForType(LRT->getPointeeTypeAsWritten(), Context, After))
249
250 // Declaration fragments of a rvalue reference type is the declaration
251 // fragments of the underlying type followed by a `&&`.
252 if (const RValueReferenceType *RRT = dyn_cast<RValueReferenceType>(T))
253 return Fragments
254 .append(
255 getFragmentsForType(RRT->getPointeeTypeAsWritten(), Context, After))
257
258 // Declaration fragments of an array-typed variable have two parts:
259 // 1. the element type of the array that appears before the variable name;
260 // 2. array brackets `[(0-9)?]` that appear after the variable name.
261 if (const ArrayType *AT = T->getAsArrayTypeUnsafe()) {
262 // Build the "after" part first because the inner element type might also
263 // be an array-type. For example `int matrix[3][4]` which has a type of
264 // "(array 3 of (array 4 of ints))."
265 // Push the array size part first to make sure they are in the right order.
267
268 switch (AT->getSizeModifier()) {
270 break;
273 break;
274 case ArrayType::Star:
276 break;
277 }
278
279 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
280 // FIXME: right now this would evaluate any expressions/macros written in
281 // the original source to concrete values. For example
282 // `int nums[MAX]` -> `int nums[100]`
283 // `char *str[5 + 1]` -> `char *str[6]`
285 CAT->getSize().toStringUnsigned(Size);
287 }
288
290
291 return Fragments.append(
292 getFragmentsForType(AT->getElementType(), Context, After));
293 }
294
295 // An ElaboratedType is a sugar for types that are referred to using an
296 // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
297 // qualified name, e.g., `N::M::type`, or both.
298 if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) {
299 ElaboratedTypeKeyword Keyword = ET->getKeyword();
300 if (Keyword != ETK_None) {
301 Fragments
304 .appendSpace();
305 }
306
307 if (const NestedNameSpecifier *NNS = ET->getQualifier())
308 Fragments.append(getFragmentsForNNS(NNS, Context, After));
309
310 // After handling the elaborated keyword or qualified name, build
311 // declaration fragments for the desugared underlying type.
312 return Fragments.append(getFragmentsForType(ET->desugar(), Context, After));
313 }
314
315 // If the type is a typedefed type, get the underlying TypedefNameDecl for a
316 // direct reference to the typedef instead of the wrapped type.
317
318 // 'id' type is a typedef for an ObjCObjectPointerType
319 // we treat it as a typedef
320 if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(T)) {
321 const TypedefNameDecl *Decl = TypedefTy->getDecl();
322 TypedefUnderlyingTypeResolver TypedefResolver(Context);
323 std::string USR = TypedefResolver.getUSRForType(QualType(T, 0));
324
325 if (T->isObjCIdType()) {
326 return Fragments.append(Decl->getName(),
328 }
329
330 return Fragments.append(
332 USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0)));
333 }
334
335 // Everything we care about has been handled now, reduce to the canonical
336 // unqualified base type.
338
339 // If the base type is a TagType (struct/interface/union/class/enum), let's
340 // get the underlying Decl for better names and USRs.
341 if (const TagType *TagTy = dyn_cast<TagType>(Base)) {
342 const TagDecl *Decl = TagTy->getDecl();
343 // Anonymous decl, skip this fragment.
344 if (Decl->getName().empty())
345 return Fragments;
346 SmallString<128> TagUSR;
348 return Fragments.append(Decl->getName(),
350 TagUSR, Decl);
351 }
352
353 // If the base type is an ObjCInterfaceType, use the underlying
354 // ObjCInterfaceDecl for the true USR.
355 if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(Base)) {
356 const auto *Decl = ObjCIT->getDecl();
359 return Fragments.append(Decl->getName(),
361 USR, Decl);
362 }
363
364 // Default fragment builder for other kinds of types (BuiltinType etc.)
367 Fragments.append(Base.getAsString(),
369
370 return Fragments;
371}
372
374DeclarationFragmentsBuilder::getFragmentsForQualifiers(const Qualifiers Quals) {
375 DeclarationFragments Fragments;
376 if (Quals.hasConst())
378 if (Quals.hasVolatile())
380 if (Quals.hasRestrict())
382
383 return Fragments;
384}
385
386DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
387 const QualType QT, ASTContext &Context, DeclarationFragments &After) {
388 assert(!QT.isNull() && "invalid type");
389
390 if (const ParenType *PT = dyn_cast<ParenType>(QT)) {
392 return getFragmentsForType(PT->getInnerType(), Context, After)
394 }
395
396 const SplitQualType SQT = QT.split();
397 DeclarationFragments QualsFragments = getFragmentsForQualifiers(SQT.Quals),
398 TypeFragments =
399 getFragmentsForType(SQT.Ty, Context, After);
400 if (QT.getAsString() == "_Bool")
401 TypeFragments.replace("bool", 0);
402
403 if (QualsFragments.getFragments().empty())
404 return TypeFragments;
405
406 // Use east qualifier for pointer types
407 // For example:
408 // ```
409 // int * const
410 // ^---- ^----
411 // type qualifier
412 // ^-----------------
413 // const pointer to int
414 // ```
415 // should not be reconstructed as
416 // ```
417 // const int *
418 // ^---- ^--
419 // qualifier type
420 // ^---------------- ^
421 // pointer to const int
422 // ```
423 if (SQT.Ty->isAnyPointerType())
424 return TypeFragments.appendSpace().append(std::move(QualsFragments));
425
426 return QualsFragments.appendSpace().append(std::move(TypeFragments));
427}
428
430 const NamespaceDecl *Decl) {
431 DeclarationFragments Fragments;
433 if (!Decl->isAnonymousNamespace())
434 Fragments.appendSpace().append(
437}
438
441 DeclarationFragments Fragments;
442 if (Var->isConstexpr())
444 .appendSpace();
445
446 StorageClass SC = Var->getStorageClass();
447 if (SC != SC_None)
448 Fragments
451 .appendSpace();
452 QualType T =
453 Var->getTypeSourceInfo()
454 ? Var->getTypeSourceInfo()->getType()
456
457 // Capture potential fragments that needs to be placed after the variable name
458 // ```
459 // int nums[5];
460 // char (*ptr_to_array)[6];
461 // ```
463 return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
464 .appendSpace()
466 .append(std::move(After))
468}
469
472 DeclarationFragments Fragments;
473 if (Var->isConstexpr())
475 .appendSpace();
476 QualType T =
477 Var->getTypeSourceInfo()
478 ? Var->getTypeSourceInfo()->getType()
480
481 // Might be a member, so might be static.
482 if (Var->isStaticDataMember())
484 .appendSpace();
485
487 DeclarationFragments ArgumentFragment =
488 getFragmentsForType(T, Var->getASTContext(), After);
489 if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
490 "type-parameter") == 0) {
491 std::string ProperArgName = getNameForTemplateArgument(
493 ArgumentFragment.begin()->Spelling);
494 ArgumentFragment.begin()->Spelling.swap(ProperArgName);
495 }
496 Fragments.append(std::move(ArgumentFragment))
497 .appendSpace()
500 return Fragments;
501}
502
504DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
505 DeclarationFragments Fragments, After;
506
507 QualType T = Param->getTypeSourceInfo()
508 ? Param->getTypeSourceInfo()->getType()
510 Param->getType());
511
512 DeclarationFragments TypeFragments =
513 getFragmentsForType(T, Param->getASTContext(), After);
514 if (TypeFragments.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
515 0) {
516 std::string ProperArgName = getNameForTemplateArgument(
517 dyn_cast<FunctionDecl>(Param->getDeclContext())
518 ->getDescribedFunctionTemplate()
519 ->getTemplateParameters()
520 ->asArray(),
521 TypeFragments.begin()->Spelling);
522 TypeFragments.begin()->Spelling.swap(ProperArgName);
523 }
524
525 if (Param->isObjCMethodParameter())
527 .append(std::move(TypeFragments))
529 else
530 Fragments.append(std::move(TypeFragments)).appendSpace();
531
532 return Fragments
533 .append(Param->getName(),
535 .append(std::move(After));
536}
537
540 DeclarationFragments Fragments;
541 // FIXME: Handle template specialization
542 switch (Func->getStorageClass()) {
543 case SC_None:
544 case SC_PrivateExtern:
545 break;
546 case SC_Extern:
548 .appendSpace();
549 break;
550 case SC_Static:
552 .appendSpace();
553 break;
554 case SC_Auto:
555 case SC_Register:
556 llvm_unreachable("invalid for functions");
557 }
558 if (Func->isConsteval()) // if consteval, it is also constexpr
560 .appendSpace();
561 else if (Func->isConstexpr())
563 .appendSpace();
564
565 // FIXME: Is `after` actually needed here?
567 auto ReturnValueFragment =
568 getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After);
569 if (ReturnValueFragment.begin()->Spelling.substr(0, 14).compare(
570 "type-parameter") == 0) {
571 std::string ProperArgName =
574 ->asArray(),
575 ReturnValueFragment.begin()->Spelling);
576 ReturnValueFragment.begin()->Spelling.swap(ProperArgName);
577 }
578
579 Fragments.append(std::move(ReturnValueFragment))
580 .appendSpace()
582
583 if (Func->getTemplateSpecializationInfo()) {
585
586 for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) {
587 if (i)
589 Fragments.append(
590 getFragmentsForType(Func->getParamDecl(i)->getType(),
591 Func->getParamDecl(i)->getASTContext(), After));
592 }
594 }
595 Fragments.append(std::move(After));
596
598 for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) {
599 if (i)
601 Fragments.append(getFragmentsForParam(Func->getParamDecl(i)));
602 }
604
606 Func->getExceptionSpecType()));
607
609}
610
612 const EnumConstantDecl *EnumConstDecl) {
613 DeclarationFragments Fragments;
614 return Fragments.append(EnumConstDecl->getName(),
616}
617
622
623 DeclarationFragments Fragments, After;
625
626 if (!EnumDecl->getName().empty())
627 Fragments.appendSpace().append(
629
630 QualType IntegerType = EnumDecl->getIntegerType();
631 if (!IntegerType.isNull())
633 .append(
634 getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After))
635 .append(std::move(After));
636
638}
639
643 DeclarationFragments Fragments;
644 if (Field->isMutable())
646 .appendSpace();
647 return Fragments
648 .append(
649 getFragmentsForType(Field->getType(), Field->getASTContext(), After))
650 .appendSpace()
652 .append(std::move(After))
654}
655
658 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
660
661 DeclarationFragments Fragments;
663
664 if (!Record->getName().empty())
665 Fragments.appendSpace().append(
667
669}
670
672 const CXXRecordDecl *Record) {
673 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
675
676 DeclarationFragments Fragments;
678
679 if (!Record->getName().empty())
680 Fragments.appendSpace().append(
682
684}
685
688 const CXXMethodDecl *Method) {
689 DeclarationFragments Fragments;
690 std::string Name;
691 if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(Method)) {
692 Name = Method->getNameAsString();
693 if (Constructor->isExplicit())
695 .appendSpace();
696 } else if (isa<CXXDestructorDecl>(Method))
697 Name = Method->getNameAsString();
698
701 .append(std::move(After));
703 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
704 if (i)
706 Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
707 }
709
711 Method->getExceptionSpecType()));
712
714}
715
717 const CXXMethodDecl *Method) {
718 DeclarationFragments Fragments;
719 StringRef Name = Method->getName();
720 if (Method->isStatic())
722 .appendSpace();
723 if (Method->isConstexpr())
725 .appendSpace();
726 if (Method->isVolatile())
728 .appendSpace();
729
730 // Build return type
732 Fragments
733 .append(getFragmentsForType(Method->getReturnType(),
734 Method->getASTContext(), After))
735 .appendSpace()
737 .append(std::move(After));
739 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
740 if (i)
742 Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
743 }
745
746 if (Method->isConst())
747 Fragments.appendSpace().append("const",
749
751 Method->getExceptionSpecType()));
752
754}
755
758 const CXXConversionDecl *ConversionFunction) {
759 DeclarationFragments Fragments;
760
761 if (ConversionFunction->isExplicit())
763 .appendSpace();
764
766 .appendSpace();
767
768 Fragments
769 .append(ConversionFunction->getConversionType().getAsString(),
772 for (unsigned i = 0, end = ConversionFunction->getNumParams(); i != end;
773 ++i) {
774 if (i)
776 Fragments.append(getFragmentsForParam(ConversionFunction->getParamDecl(i)));
777 }
779
780 if (ConversionFunction->isConst())
781 Fragments.appendSpace().append("const",
783
785}
786
789 const CXXMethodDecl *Method) {
790 DeclarationFragments Fragments;
791
792 // Build return type
794 Fragments
795 .append(getFragmentsForType(Method->getReturnType(),
796 Method->getASTContext(), After))
797 .appendSpace()
798 .append(Method->getNameAsString(),
800 .append(std::move(After));
802 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
803 if (i)
805 Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
806 }
808
809 if (Method->isConst())
810 Fragments.appendSpace().append("const",
812
814 Method->getExceptionSpecType()));
815
817}
818
819// Get fragments for template parameters, e.g. T in tempalte<typename T> ...
822 ArrayRef<NamedDecl *> ParameterArray) {
823 DeclarationFragments Fragments;
824 for (unsigned i = 0, end = ParameterArray.size(); i != end; ++i) {
825 if (i)
827 .appendSpace();
828
829 const auto *TemplateParam =
830 dyn_cast<TemplateTypeParmDecl>(ParameterArray[i]);
831 if (!TemplateParam)
832 continue;
833 if (TemplateParam->hasTypeConstraint())
834 Fragments.append(TemplateParam->getTypeConstraint()
835 ->getNamedConcept()
836 ->getName()
837 .str(),
839 else if (TemplateParam->wasDeclaredWithTypename())
841 else
843
844 if (TemplateParam->isParameterPack())
846
847 Fragments.appendSpace().append(
848 TemplateParam->getName(),
850 }
851 return Fragments;
852}
853
854// Find the name of a template argument from the template's parameters.
856 const ArrayRef<NamedDecl *> TemplateParameters, std::string TypeParameter) {
857 // The arg is a generic parameter from a partial spec, e.g.
858 // T in template<typename T> Foo<T, int>.
859 //
860 // Those names appear as "type-parameter-<index>-<depth>", so we must find its
861 // name from the template's parameter list.
862 for (unsigned i = 0; i < TemplateParameters.size(); ++i) {
863 const auto *Parameter =
864 dyn_cast<TemplateTypeParmDecl>(TemplateParameters[i]);
865 if (TypeParameter.compare("type-parameter-" +
866 std::to_string(Parameter->getDepth()) + "-" +
867 std::to_string(Parameter->getIndex())) == 0)
868 return std::string(TemplateParameters[i]->getName());
869 }
870 llvm_unreachable("Could not find the name of a template argument.");
871}
872
873// Get fragments for template arguments, e.g. int in template<typename T>
874// Foo<int>;
875//
876// Note: TemplateParameters is only necessary if the Decl is a
877// PartialSpecialization, where we need the parameters to deduce the name of the
878// generic arguments.
881 const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context,
882 const std::optional<ArrayRef<NamedDecl *>> TemplateParameters) {
883 DeclarationFragments Fragments;
884 for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) {
885 if (i)
887 .appendSpace();
888
889 std::string Type = TemplateArguments[i].getAsType().getAsString();
891 DeclarationFragments ArgumentFragment =
892 getFragmentsForType(TemplateArguments[i].getAsType(), Context, After);
893
894 if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
895 "type-parameter") == 0) {
896 std::string ProperArgName = getNameForTemplateArgument(
897 TemplateParameters.value(), ArgumentFragment.begin()->Spelling);
898 ArgumentFragment.begin()->Spelling.swap(ProperArgName);
899 }
900 Fragments.append(std::move(ArgumentFragment));
901
902 if (TemplateArguments[i].isPackExpansion())
904 }
905 return Fragments;
906}
907
909 const ConceptDecl *Concept) {
910 DeclarationFragments Fragments;
911 return Fragments
915 Concept->getTemplateParameters()->asArray()))
918 .appendSpace()
919 .append(Concept->getName().str(),
922}
923
926 const RedeclarableTemplateDecl *RedeclarableTemplate) {
927 DeclarationFragments Fragments;
931 RedeclarableTemplate->getTemplateParameters()->asArray()))
933 .appendSpace();
934
935 if (isa<TypeAliasTemplateDecl>(RedeclarableTemplate))
936 Fragments.appendSpace()
938 .appendSpace()
939 .append(RedeclarableTemplate->getName(),
941 // the templated records will be resposbible for injecting their templates
942 return Fragments.appendSpace();
943}
944
948 DeclarationFragments Fragments;
949 return Fragments
953 .appendSpace()
955 cast<CXXRecordDecl>(Decl)))
956 .pop_back() // there is an extra semicolon now
958 .append(
959 getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
960 Decl->getASTContext(), std::nullopt))
963}
964
968 DeclarationFragments Fragments;
969 return Fragments
973 Decl->getTemplateParameters()->asArray()))
975 .appendSpace()
977 cast<CXXRecordDecl>(Decl)))
978 .pop_back() // there is an extra semicolon now
981 Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
982 Decl->getTemplateParameters()->asArray()))
985}
986
990 DeclarationFragments Fragments;
991 return Fragments
995 .appendSpace()
997 .pop_back() // there is an extra semicolon now
999 .append(
1000 getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
1001 Decl->getASTContext(), std::nullopt))
1004}
1005
1009 DeclarationFragments Fragments;
1010 return Fragments
1013 // Partial specs may have new params.
1015 Decl->getTemplateParameters()->asArray()))
1017 .appendSpace()
1019 .pop_back() // there is an extra semicolon now
1022 Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1023 Decl->getTemplateParameters()->asArray()))
1026}
1027
1030 const FunctionTemplateDecl *Decl) {
1031 DeclarationFragments Fragments;
1032 return Fragments
1035 // Partial specs may have new params.
1037 Decl->getTemplateParameters()->asArray()))
1039 .appendSpace()
1041 Decl->getAsFunction()));
1042}
1043
1046 const FunctionDecl *Decl) {
1047 DeclarationFragments Fragments;
1048 return Fragments
1051 .appendSpace()
1053}
1054
1057 const MacroDirective *MD) {
1058 DeclarationFragments Fragments;
1060 .appendSpace();
1062
1063 auto *MI = MD->getMacroInfo();
1064
1065 if (MI->isFunctionLike()) {
1067 unsigned numParameters = MI->getNumParams();
1068 if (MI->isC99Varargs())
1069 --numParameters;
1070 for (unsigned i = 0; i < numParameters; ++i) {
1071 if (i)
1073 Fragments.append(MI->params()[i]->getName(),
1075 }
1076 if (MI->isVariadic()) {
1077 if (numParameters && MI->isC99Varargs())
1080 }
1082 }
1083 return Fragments;
1084}
1085
1087 const ObjCCategoryDecl *Category) {
1088 DeclarationFragments Fragments;
1089
1090 auto *Interface = Category->getClassInterface();
1091 SmallString<128> InterfaceUSR;
1092 index::generateUSRForDecl(Interface, InterfaceUSR);
1093
1095 .appendSpace()
1096 .append(Category->getClassInterface()->getName(),
1098 Interface)
1100 .append(Category->getName(),
1103
1104 return Fragments;
1105}
1106
1108 const ObjCInterfaceDecl *Interface) {
1109 DeclarationFragments Fragments;
1110 // Build the base of the Objective-C interface declaration.
1112 .appendSpace()
1113 .append(Interface->getName(),
1115
1116 // Build the inheritance part of the declaration.
1117 if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) {
1118 SmallString<128> SuperUSR;
1119 index::generateUSRForDecl(SuperClass, SuperUSR);
1121 .append(SuperClass->getName(),
1123 SuperClass);
1124 }
1125
1126 return Fragments;
1127}
1128
1130 const ObjCMethodDecl *Method) {
1131 DeclarationFragments Fragments, After;
1132 // Build the instance/class method indicator.
1133 if (Method->isClassMethod())
1135 else if (Method->isInstanceMethod())
1137
1138 // Build the return type.
1140 .append(getFragmentsForType(Method->getReturnType(),
1141 Method->getASTContext(), After))
1142 .append(std::move(After))
1144
1145 // Build the selector part.
1146 Selector Selector = Method->getSelector();
1147 if (Selector.getNumArgs() == 0)
1148 // For Objective-C methods that don't take arguments, the first (and only)
1149 // slot of the selector is the method name.
1150 Fragments.appendSpace().append(
1153
1154 // For Objective-C methods that take arguments, build the selector slots.
1155 for (unsigned i = 0, end = Method->param_size(); i != end; ++i) {
1156 // Objective-C method selector parts are considered as identifiers instead
1157 // of "external parameters" as in Swift. This is because Objective-C method
1158 // symbols are referenced with the entire selector, instead of just the
1159 // method name in Swift.
1161 ParamID.append(":");
1162 Fragments.appendSpace().append(
1164
1165 // Build the internal parameter.
1166 const ParmVarDecl *Param = Method->getParamDecl(i);
1167 Fragments.append(getFragmentsForParam(Param));
1168 }
1169
1170 return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
1171}
1172
1174 const ObjCPropertyDecl *Property) {
1175 DeclarationFragments Fragments, After;
1176
1177 // Build the Objective-C property keyword.
1179
1180 const auto Attributes = Property->getPropertyAttributesAsWritten();
1181 // Build the attributes if there is any associated with the property.
1182 if (Attributes != ObjCPropertyAttribute::kind_noattr) {
1183 // No leading comma for the first attribute.
1184 bool First = true;
1186 // Helper function to render the attribute.
1187 auto RenderAttribute =
1188 [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling,
1189 StringRef Arg = "",
1192 // Check if the `Kind` attribute is set for this property.
1193 if ((Attributes & Kind) && !Spelling.empty()) {
1194 // Add a leading comma if this is not the first attribute rendered.
1195 if (!First)
1197 // Render the spelling of this attribute `Kind` as a keyword.
1198 Fragments.append(Spelling,
1200 // If this attribute takes in arguments (e.g. `getter=getterName`),
1201 // render the arguments.
1202 if (!Arg.empty())
1204 .append(Arg, ArgKind);
1205 First = false;
1206 }
1207 };
1208
1209 // Go through all possible Objective-C property attributes and render set
1210 // ones.
1211 RenderAttribute(ObjCPropertyAttribute::kind_class, "class");
1212 RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct");
1213 RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic");
1214 RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic");
1215 RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign");
1216 RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain");
1217 RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong");
1218 RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy");
1219 RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak");
1221 "unsafe_unretained");
1222 RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite");
1223 RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly");
1224 RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter",
1225 Property->getGetterName().getAsString());
1226 RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter",
1227 Property->getSetterName().getAsString());
1228
1229 // Render nullability attributes.
1230 if (Attributes & ObjCPropertyAttribute::kind_nullability) {
1231 QualType Type = Property->getType();
1232 if (const auto Nullability =
1234 if (!First)
1236 if (*Nullability == NullabilityKind::Unspecified &&
1238 Fragments.append("null_resettable",
1240 else
1241 Fragments.append(
1242 getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true),
1244 First = false;
1245 }
1246 }
1247
1249 }
1250
1251 // Build the property type and name, and return the completed fragments.
1252 return Fragments.appendSpace()
1253 .append(getFragmentsForType(Property->getType(),
1254 Property->getASTContext(), After))
1255 .appendSpace()
1256 .append(Property->getName(),
1258 .append(std::move(After));
1259}
1260
1262 const ObjCProtocolDecl *Protocol) {
1263 DeclarationFragments Fragments;
1264 // Build basic protocol declaration.
1266 .appendSpace()
1267 .append(Protocol->getName(),
1269
1270 // If this protocol conforms to other protocols, build the conformance list.
1271 if (!Protocol->protocols().empty()) {
1273 for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin();
1274 It != Protocol->protocol_end(); It++) {
1275 // Add a leading comma if this is not the first protocol rendered.
1276 if (It != Protocol->protocol_begin())
1278
1279 SmallString<128> USR;
1280 index::generateUSRForDecl(*It, USR);
1281 Fragments.append((*It)->getName(),
1283 *It);
1284 }
1286 }
1287
1288 return Fragments;
1289}
1290
1292 const TypedefNameDecl *Decl) {
1293 DeclarationFragments Fragments, After;
1295 .appendSpace()
1296 .append(getFragmentsForType(Decl->getUnderlyingType(),
1297 Decl->getASTContext(), After))
1298 .append(std::move(After))
1299 .appendSpace()
1301
1302 return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
1303}
1304
1305// Instantiate template for FunctionDecl.
1306template FunctionSignature
1308
1309// Instantiate template for ObjCMethodDecl.
1310template FunctionSignature
1312
1313// Subheading of a symbol defaults to its name.
1316 DeclarationFragments Fragments;
1317 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
1318 Fragments.append(cast<CXXRecordDecl>(Decl->getDeclContext())->getName(),
1320 else if (isa<CXXConversionDecl>(Decl)) {
1321 Fragments.append(
1322 cast<CXXConversionDecl>(Decl)->getConversionType().getAsString(),
1324 } else if (isa<CXXMethodDecl>(Decl) &&
1325 cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) {
1326 Fragments.append(Decl->getNameAsString(),
1328 } else if (!Decl->getName().empty())
1329 Fragments.append(Decl->getName(),
1331 return Fragments;
1332}
1333
1334// Subheading of an Objective-C method is a `+` or `-` sign indicating whether
1335// it's a class method or an instance method, followed by the selector name.
1338 DeclarationFragments Fragments;
1339 if (Method->isClassMethod())
1341 else if (Method->isInstanceMethod())
1343
1344 return Fragments.append(Method->getNameAsString(),
1346}
1347
1348// Subheading of a symbol defaults to its name.
1351 DeclarationFragments Fragments;
1353 return Fragments;
1354}
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines the Declaration Fragments related classes.
int Category
Definition: Format.cpp:2939
Defines an enumeration for C++ overloaded operators.
static std::string getName(const CallEvent &Call)
This file defines the UnderlyingTypeResolver which is a helper type for resolving the undelrying type...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
QualType getUnqualifiedObjCPointerType(QualType type) const
getUnqualifiedObjCPointerType - Returns version of Objective-C pointer type with lifetime qualifier r...
Definition: ASTContext.h:2160
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3083
static std::optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it's there.
Definition: Type.cpp:4531
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2818
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2035
bool isVolatile() const
Definition: DeclCXX.h:2077
bool isConst() const
Definition: DeclCXX.h:2076
bool isStatic() const
Definition: DeclCXX.cpp:2144
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
Represents a class template specialization, which refers to a class template with a given set of temp...
Declaration of a C++20 concept.
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3131
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:429
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:228
DeclContext * getDeclContext()
Definition: DeclBase.h:441
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:796
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:5757
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3197
Represents an enum.
Definition: Decl.h:3758
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Definition: Decl.h:3918
Represents a member of a struct/union/class.
Definition: Decl.h:2962
Represents a function declaration or definition.
Definition: Decl.h:1919
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2626
ExceptionSpecificationType getExceptionSpecType() const
Gets the ExceptionSpecificationType as declared.
Definition: Decl.h:2681
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:3952
QualType getReturnType() const
Definition: Decl.h:2657
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
Definition: Decl.cpp:4076
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:2700
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
Definition: Decl.h:2367
bool isConsteval() const
Definition: Decl.h:2379
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3616
Declaration of a template function.
StringRef getName() const
Return the actual identifier string.
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:2995
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
Definition: MacroInfo.h:313
const MacroInfo * getMacroInfo() const
Definition: MacroInfo.h:413
This represents a decl that may have a name.
Definition: Decl.h:247
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Definition: Decl.h:290
Represents a C++ namespace alias.
Definition: DeclCXX.h:3074
Represent a C++ namespace.
Definition: Decl.h:544
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
Definition: Decl.h:602
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2312
Represents an ObjC class declaration.
Definition: DeclObjC.h:1147
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:351
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
unsigned param_size() const
Definition: DeclObjC.h:349
Selector getSelector() const
Definition: DeclObjC.h:329
bool isInstanceMethod() const
Definition: DeclObjC.h:428
ParmVarDecl * getParamDecl(unsigned Idx)
Definition: DeclObjC.h:379
QualType getReturnType() const
Definition: DeclObjC.h:331
bool isClassMethod() const
Definition: DeclObjC.h:436
Represents a pointer to an Objective C object.
Definition: Type.h:6395
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Definition: Type.h:6470
bool isObjCIdOrClassType() const
True if this is equivalent to the 'id' or 'Class' type,.
Definition: Type.h:6464
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:729
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2069
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:2141
Sugar for parentheses used when specifying types.
Definition: Type.h:2814
Represents a parameter to a function.
Definition: Decl.h:1724
bool isObjCMethodParameter() const
Definition: Decl.h:1767
A (possibly-)qualified type.
Definition: Type.h:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:6768
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1120
The collection of all-type qualifiers we support.
Definition: Type.h:146
bool hasConst() const
Definition: Type.h:263
bool hasRestrict() const
Definition: Type.h:283
bool hasVolatile() const
Definition: Type.h:273
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3013
Represents a struct/union/class.
Definition: Decl.h:4036
Declaration of a redeclarable template.
Definition: DeclTemplate.h:767
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
unsigned getNumArgs() const
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3477
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3703
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:429
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:135
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6729
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3082
The base class of the type hierarchy.
Definition: Type.h:1597
bool isPointerType() const
Definition: Type.h:6999
CanQualType getCanonicalTypeUnqualified() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:655
bool isObjCIdType() const
Definition: Type.h:7160
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:7576
bool isObjCObjectPointerType() const
Definition: Type.h:7127
bool isAnyPointerType() const
Definition: Type.h:7003
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7523
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3327
QualType getType() const
Definition: Decl.h:714
Represents a variable declaration or definition.
Definition: Decl.h:915
VarTemplateDecl * getDescribedVarTemplate() const
Retrieves the variable template that is described by this variable declaration.
Definition: Decl.cpp:2760
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1521
static const char * getStorageClassSpecifierString(StorageClass SC)
Return the string used to specify the storage class SC.
Definition: Decl.cpp:2100
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1242
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1127
Represents a variable template specialization, which refers to a variable template with a given set o...
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 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.
const std::vector< Fragment > & getFragments() const
DeclarationFragments & appendSpace()
Append a text Fragment of a space character.
static DeclarationFragments getExceptionSpecificationString(ExceptionSpecificationType ExceptionSpec)
@ 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)
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.
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
@ After
Like System, but searched after the system directories.
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl< char > &Buf)
Generates a USR for a type.
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
StorageClass
Storage classes.
Definition: Specifiers.h:239
@ SC_Auto
Definition: Specifiers.h:247
@ SC_PrivateExtern
Definition: Specifiers.h:244
@ SC_Extern
Definition: Specifiers.h:242
@ SC_Register
Definition: Specifiers.h:248
@ SC_Static
Definition: Specifiers.h:243
@ SC_None
Definition: Specifiers.h:241
@ Property
The type of a property.
@ Parameter
The parameter type of a method or function.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.
llvm::StringRef getAsString(SyncScope S)
Definition: SyncScope.h:55
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: Type.h:5678
@ ETK_None
No keyword precedes the qualified type name.
Definition: Type.h:5699
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_DependentNoexcept
noexcept(expression), value-dependent
@ EST_DynamicNone
throw()
@ EST_None
no exception specification
@ EST_BasicNoexcept
noexcept
@ EST_NoexceptFalse
noexcept(expression), evals to 'false'
@ EST_NoexceptTrue
noexcept(expression), evals to 'true'
@ EST_Dynamic
throw(T1, T2)
YAML serialization mapping.
Definition: Dominators.h:30
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:669
const Type * Ty
The locally-unqualified type.
Definition: Type.h:671
Qualifiers Quals
The local qualifiers.
Definition: Type.h:674
Fragment holds information of a single fragment.