clang 19.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/ASTFwd.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclCXX.h"
20#include "clang/AST/Type.h"
21#include "clang/AST/TypeLoc.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Support/raw_ostream.h"
27#include <optional>
28
29using namespace clang::extractapi;
30using namespace llvm;
31
32namespace {
33
34void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
36 clang::FunctionProtoTypeLoc &BlockProto) {
37 if (!TSInfo)
38 return;
39
41 while (true) {
42 // Look through qualified types
43 if (auto QualifiedTL = TL.getAs<clang::QualifiedTypeLoc>()) {
44 TL = QualifiedTL.getUnqualifiedLoc();
45 continue;
46 }
47
48 if (auto AttrTL = TL.getAs<clang::AttributedTypeLoc>()) {
49 TL = AttrTL.getModifiedLoc();
50 continue;
51 }
52
53 // Try to get the function prototype behind the block pointer type,
54 // then we're done.
55 if (auto BlockPtr = TL.getAs<clang::BlockPointerTypeLoc>()) {
56 TL = BlockPtr.getPointeeLoc().IgnoreParens();
58 BlockProto = TL.getAs<clang::FunctionProtoTypeLoc>();
59 }
60 break;
61 }
62}
63
64} // namespace
65
67DeclarationFragments::appendUnduplicatedTextCharacter(char Character) {
68 if (!Fragments.empty()) {
69 Fragment &Last = Fragments.back();
70 if (Last.Kind == FragmentKind::Text) {
71 // Merge the extra space into the last fragment if the last fragment is
72 // also text.
73 if (Last.Spelling.back() != Character) { // avoid duplicates at end
74 Last.Spelling.push_back(Character);
75 }
76 } else {
78 Fragments.back().Spelling.push_back(Character);
79 }
80 }
81
82 return *this;
83}
84
86 return appendUnduplicatedTextCharacter(' ');
87}
88
90 return appendUnduplicatedTextCharacter(';');
91}
92
94 if (Fragments.empty())
95 return *this;
96
97 Fragment &Last = Fragments.back();
98 if (Last.Kind == FragmentKind::Text && Last.Spelling.back() == ';')
99 Last.Spelling.pop_back();
100
101 return *this;
102}
103
106 switch (Kind) {
108 return "none";
110 return "keyword";
112 return "attribute";
114 return "number";
116 return "string";
118 return "identifier";
120 return "typeIdentifier";
122 return "genericParameter";
124 return "externalParam";
126 return "internalParam";
128 return "text";
129 }
130
131 llvm_unreachable("Unhandled FragmentKind");
132}
133
136 return llvm::StringSwitch<FragmentKind>(S)
142 .Case("typeIdentifier",
144 .Case("genericParameter",
150}
151
153 ExceptionSpecificationType ExceptionSpec) {
154 DeclarationFragments Fragments;
155 switch (ExceptionSpec) {
157 return Fragments;
164 // FIXME: throw(int), get types of inner expression
165 return Fragments;
170 // FIXME: throw(conditional-expression), get expression
171 break;
184 default:
185 return Fragments;
186 }
187
188 llvm_unreachable("Unhandled exception specification");
189}
190
193 DeclarationFragments Fragments;
194 if (Record->isStruct())
196 else if (Record->isUnion())
198 else
200
201 return Fragments;
202}
203
204// NNS stores C++ nested name specifiers, which are prefixes to qualified names.
205// Build declaration fragments for NNS recursively so that we have the USR for
206// every part in a qualified name, and also leaves the actual underlying type
207// cleaner for its own fragment.
209DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS,
210 ASTContext &Context,
211 DeclarationFragments &After) {
212 DeclarationFragments Fragments;
213 if (NNS->getPrefix())
214 Fragments.append(getFragmentsForNNS(NNS->getPrefix(), Context, After));
215
216 switch (NNS->getKind()) {
218 Fragments.append(NNS->getAsIdentifier()->getName(),
220 break;
221
223 const NamespaceDecl *NS = NNS->getAsNamespace();
224 if (NS->isAnonymousNamespace())
225 return Fragments;
228 Fragments.append(NS->getName(),
230 break;
231 }
232
234 const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias();
236 index::generateUSRForDecl(Alias, USR);
237 Fragments.append(Alias->getName(),
239 Alias);
240 break;
241 }
242
244 // The global specifier `::` at the beginning. No stored value.
245 break;
246
248 // Microsoft's `__super` specifier.
250 break;
251
253 // A type prefixed by the `template` keyword.
255 Fragments.appendSpace();
256 // Fallthrough after adding the keyword to handle the actual type.
257 [[fallthrough]];
258
260 const Type *T = NNS->getAsType();
261 // FIXME: Handle C++ template specialization type
262 Fragments.append(getFragmentsForType(T, Context, After));
263 break;
264 }
265 }
266
267 // Add the separator text `::` for this segment.
268 return Fragments.append("::", DeclarationFragments::FragmentKind::Text);
269}
270
271// Recursively build the declaration fragments for an underlying `Type` with
272// qualifiers removed.
273DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
274 const Type *T, ASTContext &Context, DeclarationFragments &After) {
275 assert(T && "invalid type");
276
277 DeclarationFragments Fragments;
278
279 // An ElaboratedType is a sugar for types that are referred to using an
280 // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
281 // qualified name, e.g., `N::M::type`, or both.
282 if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) {
283 ElaboratedTypeKeyword Keyword = ET->getKeyword();
284 if (Keyword != ElaboratedTypeKeyword::None) {
285 Fragments
288 .appendSpace();
289 }
290
291 if (const NestedNameSpecifier *NNS = ET->getQualifier())
292 Fragments.append(getFragmentsForNNS(NNS, Context, After));
293
294 // After handling the elaborated keyword or qualified name, build
295 // declaration fragments for the desugared underlying type.
296 return Fragments.append(getFragmentsForType(ET->desugar(), Context, After));
297 }
298
299 // If the type is a typedefed type, get the underlying TypedefNameDecl for a
300 // direct reference to the typedef instead of the wrapped type.
301
302 // 'id' type is a typedef for an ObjCObjectPointerType
303 // we treat it as a typedef
304 if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(T)) {
305 const TypedefNameDecl *Decl = TypedefTy->getDecl();
306 TypedefUnderlyingTypeResolver TypedefResolver(Context);
307 std::string USR = TypedefResolver.getUSRForType(QualType(T, 0));
308
309 if (T->isObjCIdType()) {
310 return Fragments.append(Decl->getName(),
312 }
313
314 return Fragments.append(
316 USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0)));
317 }
318
319 // Declaration fragments of a pointer type is the declaration fragments of
320 // the pointee type followed by a `*`,
322 return Fragments
323 .append(getFragmentsForType(T->getPointeeType(), Context, After))
325
326 // For Objective-C `id` and `Class` pointers
327 // we do not spell out the `*`.
328 if (T->isObjCObjectPointerType() &&
330
331 Fragments.append(getFragmentsForType(T->getPointeeType(), Context, After));
332
333 // id<protocol> is an qualified id type
334 // id<protocol>* is not an qualified id type
337 }
338
339 return Fragments;
340 }
341
342 // Declaration fragments of a lvalue reference type is the declaration
343 // fragments of the underlying type followed by a `&`.
344 if (const LValueReferenceType *LRT = dyn_cast<LValueReferenceType>(T))
345 return Fragments
346 .append(
347 getFragmentsForType(LRT->getPointeeTypeAsWritten(), Context, After))
349
350 // Declaration fragments of a rvalue reference type is the declaration
351 // fragments of the underlying type followed by a `&&`.
352 if (const RValueReferenceType *RRT = dyn_cast<RValueReferenceType>(T))
353 return Fragments
354 .append(
355 getFragmentsForType(RRT->getPointeeTypeAsWritten(), Context, After))
357
358 // Declaration fragments of an array-typed variable have two parts:
359 // 1. the element type of the array that appears before the variable name;
360 // 2. array brackets `[(0-9)?]` that appear after the variable name.
361 if (const ArrayType *AT = T->getAsArrayTypeUnsafe()) {
362 // Build the "after" part first because the inner element type might also
363 // be an array-type. For example `int matrix[3][4]` which has a type of
364 // "(array 3 of (array 4 of ints))."
365 // Push the array size part first to make sure they are in the right order.
367
368 switch (AT->getSizeModifier()) {
370 break;
373 break;
376 break;
377 }
378
379 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
380 // FIXME: right now this would evaluate any expressions/macros written in
381 // the original source to concrete values. For example
382 // `int nums[MAX]` -> `int nums[100]`
383 // `char *str[5 + 1]` -> `char *str[6]`
385 CAT->getSize().toStringUnsigned(Size);
387 }
388
390
391 return Fragments.append(
392 getFragmentsForType(AT->getElementType(), Context, After));
393 }
394
395 if (const TemplateSpecializationType *TemplSpecTy =
396 dyn_cast<TemplateSpecializationType>(T)) {
397 const auto TemplName = TemplSpecTy->getTemplateName();
398 std::string Str;
399 raw_string_ostream Stream(Str);
400 TemplName.print(Stream, Context.getPrintingPolicy(),
402 SmallString<64> USR("");
403 if (const auto *TemplDecl = TemplName.getAsTemplateDecl())
404 index::generateUSRForDecl(TemplDecl, USR);
405
406 return Fragments
410 TemplSpecTy->template_arguments(), Context, std::nullopt))
412 }
413
414 // Everything we care about has been handled now, reduce to the canonical
415 // unqualified base type.
417
418 // If the base type is a TagType (struct/interface/union/class/enum), let's
419 // get the underlying Decl for better names and USRs.
420 if (const TagType *TagTy = dyn_cast<TagType>(Base)) {
421 const TagDecl *Decl = TagTy->getDecl();
422 // Anonymous decl, skip this fragment.
423 if (Decl->getName().empty())
424 return Fragments.append("{ ... }",
426 SmallString<128> TagUSR;
428 return Fragments.append(Decl->getName(),
430 TagUSR, Decl);
431 }
432
433 // If the base type is an ObjCInterfaceType, use the underlying
434 // ObjCInterfaceDecl for the true USR.
435 if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(Base)) {
436 const auto *Decl = ObjCIT->getDecl();
439 return Fragments.append(Decl->getName(),
441 USR, Decl);
442 }
443
444 // Default fragment builder for other kinds of types (BuiltinType etc.)
447 Fragments.append(Base.getAsString(),
449
450 return Fragments;
451}
452
454DeclarationFragmentsBuilder::getFragmentsForQualifiers(const Qualifiers Quals) {
455 DeclarationFragments Fragments;
456 if (Quals.hasConst())
458 if (Quals.hasVolatile())
460 if (Quals.hasRestrict())
462
463 return Fragments;
464}
465
466DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
467 const QualType QT, ASTContext &Context, DeclarationFragments &After) {
468 assert(!QT.isNull() && "invalid type");
469
470 if (const ParenType *PT = dyn_cast<ParenType>(QT)) {
472 return getFragmentsForType(PT->getInnerType(), Context, After)
474 }
475
476 const SplitQualType SQT = QT.split();
477 DeclarationFragments QualsFragments = getFragmentsForQualifiers(SQT.Quals),
478 TypeFragments =
479 getFragmentsForType(SQT.Ty, Context, After);
480 if (QT.getAsString() == "_Bool")
481 TypeFragments.replace("bool", 0);
482
483 if (QualsFragments.getFragments().empty())
484 return TypeFragments;
485
486 // Use east qualifier for pointer types
487 // For example:
488 // ```
489 // int * const
490 // ^---- ^----
491 // type qualifier
492 // ^-----------------
493 // const pointer to int
494 // ```
495 // should not be reconstructed as
496 // ```
497 // const int *
498 // ^---- ^--
499 // qualifier type
500 // ^---------------- ^
501 // pointer to const int
502 // ```
503 if (SQT.Ty->isAnyPointerType())
504 return TypeFragments.appendSpace().append(std::move(QualsFragments));
505
506 return QualsFragments.appendSpace().append(std::move(TypeFragments));
507}
508
510 const NamespaceDecl *Decl) {
511 DeclarationFragments Fragments;
513 if (!Decl->isAnonymousNamespace())
514 Fragments.appendSpace().append(
516 return Fragments.appendSemicolon();
517}
518
521 DeclarationFragments Fragments;
522 if (Var->isConstexpr())
524 .appendSpace();
525
526 StorageClass SC = Var->getStorageClass();
527 if (SC != SC_None)
528 Fragments
531 .appendSpace();
532
533 // Capture potential fragments that needs to be placed after the variable name
534 // ```
535 // int nums[5];
536 // char (*ptr_to_array)[6];
537 // ```
539 FunctionTypeLoc BlockLoc;
540 FunctionProtoTypeLoc BlockProtoLoc;
541 findTypeLocForBlockDecl(Var->getTypeSourceInfo(), BlockLoc, BlockProtoLoc);
542
543 if (!BlockLoc) {
545 ? Var->getTypeSourceInfo()->getType()
547 Var->getType());
548
549 Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
550 .appendSpace();
551 } else {
552 Fragments.append(getFragmentsForBlock(Var, BlockLoc, BlockProtoLoc, After));
553 }
554
555 return Fragments
557 .append(std::move(After))
559}
560
563 DeclarationFragments Fragments;
564 if (Var->isConstexpr())
566 .appendSpace();
567 QualType T =
568 Var->getTypeSourceInfo()
569 ? Var->getTypeSourceInfo()->getType()
571
572 // Might be a member, so might be static.
573 if (Var->isStaticDataMember())
575 .appendSpace();
576
578 DeclarationFragments ArgumentFragment =
579 getFragmentsForType(T, Var->getASTContext(), After);
580 if (StringRef(ArgumentFragment.begin()->Spelling)
581 .starts_with("type-parameter")) {
582 std::string ProperArgName = T.getAsString();
583 ArgumentFragment.begin()->Spelling.swap(ProperArgName);
584 }
585 Fragments.append(std::move(ArgumentFragment))
586 .appendSpace()
589 return Fragments;
590}
591
593DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
594 DeclarationFragments Fragments, After;
595
596 auto *TSInfo = Param->getTypeSourceInfo();
597
598 QualType T = TSInfo ? TSInfo->getType()
600 Param->getType());
601
602 FunctionTypeLoc BlockLoc;
603 FunctionProtoTypeLoc BlockProtoLoc;
604 findTypeLocForBlockDecl(TSInfo, BlockLoc, BlockProtoLoc);
605
606 DeclarationFragments TypeFragments;
607 if (BlockLoc)
608 TypeFragments.append(
609 getFragmentsForBlock(Param, BlockLoc, BlockProtoLoc, After));
610 else
611 TypeFragments.append(getFragmentsForType(T, Param->getASTContext(), After));
612
613 if (StringRef(TypeFragments.begin()->Spelling)
614 .starts_with("type-parameter")) {
615 std::string ProperArgName = Param->getOriginalType().getAsString();
616 TypeFragments.begin()->Spelling.swap(ProperArgName);
617 }
618
619 if (Param->isObjCMethodParameter()) {
621 .append(std::move(TypeFragments))
622 .append(std::move(After))
624 .append(Param->getName(),
626 } else {
627 Fragments.append(std::move(TypeFragments));
628 if (!T->isBlockPointerType())
629 Fragments.appendSpace();
630 Fragments
631 .append(Param->getName(),
633 .append(std::move(After));
634 }
635 return Fragments;
636}
637
638DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForBlock(
640 FunctionProtoTypeLoc &BlockProto, DeclarationFragments &After) {
641 DeclarationFragments Fragments;
642
643 DeclarationFragments RetTyAfter;
644 auto ReturnValueFragment = getFragmentsForType(
645 Block.getTypePtr()->getReturnType(), BlockDecl->getASTContext(), After);
646
647 Fragments.append(std::move(ReturnValueFragment))
648 .append(std::move(RetTyAfter))
649 .appendSpace()
651
653 unsigned NumParams = Block.getNumParams();
654
655 if (!BlockProto || NumParams == 0) {
656 if (BlockProto && BlockProto.getTypePtr()->isVariadic())
658 else
660 } else {
662 for (unsigned I = 0; I != NumParams; ++I) {
663 if (I)
665 After.append(getFragmentsForParam(Block.getParam(I)));
666 if (I == NumParams - 1 && BlockProto.getTypePtr()->isVariadic())
668 }
670 }
671
672 return Fragments;
673}
674
677 DeclarationFragments Fragments;
678 switch (Func->getStorageClass()) {
679 case SC_None:
680 case SC_PrivateExtern:
681 break;
682 case SC_Extern:
684 .appendSpace();
685 break;
686 case SC_Static:
688 .appendSpace();
689 break;
690 case SC_Auto:
691 case SC_Register:
692 llvm_unreachable("invalid for functions");
693 }
694 if (Func->isConsteval()) // if consteval, it is also constexpr
696 .appendSpace();
697 else if (Func->isConstexpr())
699 .appendSpace();
700
701 // FIXME: Is `after` actually needed here?
703 auto ReturnValueFragment =
704 getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After);
705 if (StringRef(ReturnValueFragment.begin()->Spelling)
706 .starts_with("type-parameter")) {
707 std::string ProperArgName = Func->getReturnType().getAsString();
708 ReturnValueFragment.begin()->Spelling.swap(ProperArgName);
709 }
710
711 Fragments.append(std::move(ReturnValueFragment))
712 .appendSpace()
714
715 if (Func->getTemplateSpecializationInfo()) {
717
718 for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) {
719 if (i)
721 Fragments.append(
722 getFragmentsForType(Func->getParamDecl(i)->getType(),
723 Func->getParamDecl(i)->getASTContext(), After));
724 }
726 }
727 Fragments.append(std::move(After));
728
730 unsigned NumParams = Func->getNumParams();
731 for (unsigned i = 0; i != NumParams; ++i) {
732 if (i)
734 Fragments.append(getFragmentsForParam(Func->getParamDecl(i)));
735 }
736
737 if (Func->isVariadic()) {
738 if (NumParams > 0)
741 }
743
745 Func->getExceptionSpecType()));
746
747 return Fragments.appendSemicolon();
748}
749
751 const EnumConstantDecl *EnumConstDecl) {
752 DeclarationFragments Fragments;
753 return Fragments.append(EnumConstDecl->getName(),
755}
756
761
762 DeclarationFragments Fragments, After;
764
765 if (!EnumDecl->getName().empty())
766 Fragments.appendSpace().append(
768
769 QualType IntegerType = EnumDecl->getIntegerType();
770 if (!IntegerType.isNull())
771 Fragments.appendSpace()
773 .append(
774 getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After))
775 .append(std::move(After));
776
777 if (EnumDecl->getName().empty())
778 Fragments.appendSpace().append("{ ... }",
780
781 return Fragments.appendSemicolon();
782}
783
787 DeclarationFragments Fragments;
788 if (Field->isMutable())
790 .appendSpace();
791 return Fragments
792 .append(
793 getFragmentsForType(Field->getType(), Field->getASTContext(), After))
794 .appendSpace()
796 .append(std::move(After))
798}
799
801 const RecordDecl *Record) {
802 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
804
805 DeclarationFragments Fragments;
806 if (Record->isUnion())
808 else
810
811 Fragments.appendSpace();
812 if (!Record->getName().empty())
813 Fragments.append(Record->getName(),
815 else
817
818 return Fragments.appendSemicolon();
819}
820
822 const CXXRecordDecl *Record) {
823 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
825
826 DeclarationFragments Fragments;
828
829 if (!Record->getName().empty())
830 Fragments.appendSpace().append(
832
833 return Fragments.appendSemicolon();
834}
835
838 const CXXMethodDecl *Method) {
839 DeclarationFragments Fragments;
840 std::string Name;
841 if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(Method)) {
842 Name = Method->getNameAsString();
843 if (Constructor->isExplicit())
845 .appendSpace();
846 } else if (isa<CXXDestructorDecl>(Method))
847 Name = Method->getNameAsString();
848
851 .append(std::move(After));
853 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
854 if (i)
856 Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
857 }
859
861 Method->getExceptionSpecType()));
862
863 return Fragments.appendSemicolon();
864}
865
867 const CXXMethodDecl *Method) {
868 DeclarationFragments Fragments;
869 StringRef Name = Method->getName();
870 if (Method->isStatic())
872 .appendSpace();
873 if (Method->isConstexpr())
875 .appendSpace();
876 if (Method->isVolatile())
878 .appendSpace();
879
880 // Build return type
882 Fragments
883 .append(getFragmentsForType(Method->getReturnType(),
884 Method->getASTContext(), After))
885 .appendSpace()
887 .append(std::move(After));
889 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
890 if (i)
892 Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
893 }
895
896 if (Method->isConst())
897 Fragments.appendSpace().append("const",
899
901 Method->getExceptionSpecType()));
902
903 return Fragments.appendSemicolon();
904}
905
908 const CXXConversionDecl *ConversionFunction) {
909 DeclarationFragments Fragments;
910
911 if (ConversionFunction->isExplicit())
913 .appendSpace();
914
916 .appendSpace();
917
918 Fragments
919 .append(ConversionFunction->getConversionType().getAsString(),
922 for (unsigned i = 0, end = ConversionFunction->getNumParams(); i != end;
923 ++i) {
924 if (i)
926 Fragments.append(getFragmentsForParam(ConversionFunction->getParamDecl(i)));
927 }
929
930 if (ConversionFunction->isConst())
931 Fragments.appendSpace().append("const",
933
934 return Fragments.appendSemicolon();
935}
936
939 const CXXMethodDecl *Method) {
940 DeclarationFragments Fragments;
941
942 // Build return type
944 Fragments
945 .append(getFragmentsForType(Method->getReturnType(),
946 Method->getASTContext(), After))
947 .appendSpace()
948 .append(Method->getNameAsString(),
950 .append(std::move(After));
952 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
953 if (i)
955 Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
956 }
958
959 if (Method->isConst())
960 Fragments.appendSpace().append("const",
962
964 Method->getExceptionSpecType()));
965
966 return Fragments.appendSemicolon();
967}
968
969// Get fragments for template parameters, e.g. T in tempalte<typename T> ...
972 ArrayRef<NamedDecl *> ParameterArray) {
973 DeclarationFragments Fragments;
974 for (unsigned i = 0, end = ParameterArray.size(); i != end; ++i) {
975 if (i)
977 .appendSpace();
978
979 if (const auto *TemplateParam =
980 dyn_cast<TemplateTypeParmDecl>(ParameterArray[i])) {
981 if (TemplateParam->hasTypeConstraint())
982 Fragments.append(TemplateParam->getTypeConstraint()
983 ->getNamedConcept()
984 ->getName()
985 .str(),
987 else if (TemplateParam->wasDeclaredWithTypename())
988 Fragments.append("typename",
990 else
992
993 if (TemplateParam->isParameterPack())
995
996 if (!TemplateParam->getName().empty())
997 Fragments.appendSpace().append(
998 TemplateParam->getName(),
1000
1001 if (TemplateParam->hasDefaultArgument()) {
1002 const auto Default = TemplateParam->getDefaultArgument();
1005 {Default.getArgument()}, TemplateParam->getASTContext(),
1006 {Default}));
1007 }
1008 } else if (const auto *NTP =
1009 dyn_cast<NonTypeTemplateParmDecl>(ParameterArray[i])) {
1011 const auto TyFragments =
1012 getFragmentsForType(NTP->getType(), NTP->getASTContext(), After);
1013 Fragments.append(std::move(TyFragments)).append(std::move(After));
1014
1015 if (NTP->isParameterPack())
1017
1018 if (!NTP->getName().empty())
1019 Fragments.appendSpace().append(
1020 NTP->getName(),
1022
1023 if (NTP->hasDefaultArgument()) {
1024 SmallString<8> ExprStr;
1025 raw_svector_ostream Output(ExprStr);
1026 NTP->getDefaultArgument().getArgument().print(
1027 NTP->getASTContext().getPrintingPolicy(), Output,
1028 /*IncludeType=*/false);
1031 }
1032 } else if (const auto *TTP =
1033 dyn_cast<TemplateTemplateParmDecl>(ParameterArray[i])) {
1035 .appendSpace()
1038 TTP->getTemplateParameters()->asArray()))
1040 .appendSpace()
1041 .append(TTP->wasDeclaredWithTypename() ? "typename" : "class",
1043
1044 if (TTP->isParameterPack())
1046
1047 if (!TTP->getName().empty())
1048 Fragments.appendSpace().append(
1049 TTP->getName(),
1051 if (TTP->hasDefaultArgument()) {
1052 const auto Default = TTP->getDefaultArgument();
1055 {Default.getArgument()}, TTP->getASTContext(), {Default}));
1056 }
1057 }
1058 }
1059 return Fragments;
1060}
1061
1062// Get fragments for template arguments, e.g. int in template<typename T>
1063// Foo<int>;
1064//
1065// Note: TemplateParameters is only necessary if the Decl is a
1066// PartialSpecialization, where we need the parameters to deduce the name of the
1067// generic arguments.
1070 const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context,
1071 const std::optional<ArrayRef<TemplateArgumentLoc>> TemplateArgumentLocs) {
1072 DeclarationFragments Fragments;
1073 for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) {
1074 if (i)
1076 .appendSpace();
1077
1078 const auto &CTA = TemplateArguments[i];
1079 switch (CTA.getKind()) {
1082 DeclarationFragments ArgumentFragment =
1083 getFragmentsForType(CTA.getAsType(), Context, After);
1084
1085 if (StringRef(ArgumentFragment.begin()->Spelling)
1086 .starts_with("type-parameter")) {
1087 if (TemplateArgumentLocs.has_value() &&
1088 TemplateArgumentLocs->size() > i) {
1089 std::string ProperArgName = TemplateArgumentLocs.value()[i]
1090 .getTypeSourceInfo()
1091 ->getType()
1092 .getAsString();
1093 ArgumentFragment.begin()->Spelling.swap(ProperArgName);
1094 } else {
1095 auto &Spelling = ArgumentFragment.begin()->Spelling;
1096 Spelling.clear();
1097 raw_string_ostream OutStream(Spelling);
1098 CTA.print(Context.getPrintingPolicy(), OutStream, false);
1099 OutStream.flush();
1100 }
1101 }
1102
1103 Fragments.append(std::move(ArgumentFragment));
1104 break;
1105 }
1107 const auto *VD = CTA.getAsDecl();
1108 SmallString<128> USR;
1110 Fragments.append(VD->getNameAsString(),
1112 break;
1113 }
1116 break;
1117
1119 SmallString<4> Str;
1120 CTA.getAsIntegral().toString(Str);
1122 break;
1123 }
1124
1126 const auto SVTy = CTA.getStructuralValueType();
1127 Fragments.append(CTA.getAsStructuralValue().getAsString(Context, SVTy),
1129 break;
1130 }
1131
1134 std::string Str;
1135 raw_string_ostream Stream(Str);
1136 CTA.getAsTemplate().print(Stream, Context.getPrintingPolicy());
1137 SmallString<64> USR("");
1138 if (const auto *TemplDecl =
1139 CTA.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
1140 index::generateUSRForDecl(TemplDecl, USR);
1142 USR);
1143 if (CTA.getKind() == TemplateArgument::TemplateExpansion)
1145 break;
1146 }
1147
1150 .append(getFragmentsForTemplateArguments(CTA.pack_elements(), Context,
1151 {}))
1153 break;
1154
1156 SmallString<8> ExprStr;
1157 raw_svector_ostream Output(ExprStr);
1158 CTA.getAsExpr()->printPretty(Output, nullptr,
1159 Context.getPrintingPolicy());
1161 break;
1162 }
1163
1165 break;
1166 }
1167 }
1168 return Fragments;
1169}
1170
1172 const ConceptDecl *Concept) {
1173 DeclarationFragments Fragments;
1174 return Fragments
1176 .appendSpace()
1179 Concept->getTemplateParameters()->asArray()))
1181 .appendSpace()
1183 .appendSpace()
1184 .append(Concept->getName().str(),
1186 .appendSemicolon();
1187}
1188
1191 const RedeclarableTemplateDecl *RedeclarableTemplate) {
1192 DeclarationFragments Fragments;
1194 .appendSpace()
1197 RedeclarableTemplate->getTemplateParameters()->asArray()))
1199 .appendSpace();
1200
1201 if (isa<TypeAliasTemplateDecl>(RedeclarableTemplate))
1202 Fragments.appendSpace()
1204 .appendSpace()
1205 .append(RedeclarableTemplate->getName(),
1207 // the templated records will be resposbible for injecting their templates
1208 return Fragments.appendSpace();
1209}
1210
1214 DeclarationFragments Fragments;
1215 return Fragments
1217 .appendSpace()
1220 .appendSpace()
1222 cast<CXXRecordDecl>(Decl)))
1223 .pop_back() // there is an extra semicolon now
1226 Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1227 Decl->getTemplateArgsAsWritten()->arguments()))
1229 .appendSemicolon();
1230}
1231
1235 DeclarationFragments Fragments;
1236 return Fragments
1238 .appendSpace()
1241 Decl->getTemplateParameters()->asArray()))
1243 .appendSpace()
1245 cast<CXXRecordDecl>(Decl)))
1246 .pop_back() // there is an extra semicolon now
1249 Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1250 Decl->getTemplateArgsAsWritten()->arguments()))
1252 .appendSemicolon();
1253}
1254
1258 DeclarationFragments Fragments;
1259 return Fragments
1261 .appendSpace()
1264 .appendSpace()
1266 .pop_back() // there is an extra semicolon now
1269 Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1270 Decl->getTemplateArgsAsWritten()->arguments()))
1272 .appendSemicolon();
1273}
1274
1278 DeclarationFragments Fragments;
1279 return Fragments
1281 .appendSpace()
1283 // Partial specs may have new params.
1285 Decl->getTemplateParameters()->asArray()))
1287 .appendSpace()
1289 .pop_back() // there is an extra semicolon now
1292 Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1293 Decl->getTemplateArgsAsWritten()->arguments()))
1295 .appendSemicolon();
1296}
1297
1300 const FunctionTemplateDecl *Decl) {
1301 DeclarationFragments Fragments;
1302 return Fragments
1304 .appendSpace()
1306 // Partial specs may have new params.
1308 Decl->getTemplateParameters()->asArray()))
1310 .appendSpace()
1312 Decl->getAsFunction()));
1313}
1314
1317 const FunctionDecl *Decl) {
1318 DeclarationFragments Fragments;
1319 return Fragments
1321 .appendSpace()
1323 .appendSpace()
1325}
1326
1329 const MacroDirective *MD) {
1330 DeclarationFragments Fragments;
1332 .appendSpace();
1334
1335 auto *MI = MD->getMacroInfo();
1336
1337 if (MI->isFunctionLike()) {
1339 unsigned numParameters = MI->getNumParams();
1340 if (MI->isC99Varargs())
1341 --numParameters;
1342 for (unsigned i = 0; i < numParameters; ++i) {
1343 if (i)
1345 Fragments.append(MI->params()[i]->getName(),
1347 }
1348 if (MI->isVariadic()) {
1349 if (numParameters && MI->isC99Varargs())
1352 }
1354 }
1355 return Fragments;
1356}
1357
1359 const ObjCCategoryDecl *Category) {
1360 DeclarationFragments Fragments;
1361
1362 auto *Interface = Category->getClassInterface();
1363 SmallString<128> InterfaceUSR;
1364 index::generateUSRForDecl(Interface, InterfaceUSR);
1365
1367 .appendSpace()
1368 .append(Interface->getName(),
1370 Interface)
1372 .append(Category->getName(),
1375
1376 return Fragments;
1377}
1378
1381 DeclarationFragments Fragments;
1382 // Build the base of the Objective-C interface declaration.
1384 .appendSpace()
1385 .append(Interface->getName(),
1387
1388 // Build the inheritance part of the declaration.
1389 if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) {
1390 SmallString<128> SuperUSR;
1391 index::generateUSRForDecl(SuperClass, SuperUSR);
1393 .append(SuperClass->getName(),
1395 SuperClass);
1396 }
1397
1398 return Fragments;
1399}
1400
1402 const ObjCMethodDecl *Method) {
1403 DeclarationFragments Fragments, After;
1404 // Build the instance/class method indicator.
1405 if (Method->isClassMethod())
1407 else if (Method->isInstanceMethod())
1409
1410 // Build the return type.
1412 .append(getFragmentsForType(Method->getReturnType(),
1413 Method->getASTContext(), After))
1414 .append(std::move(After))
1416
1417 // Build the selector part.
1418 Selector Selector = Method->getSelector();
1419 if (Selector.getNumArgs() == 0)
1420 // For Objective-C methods that don't take arguments, the first (and only)
1421 // slot of the selector is the method name.
1422 Fragments.appendSpace().append(
1425
1426 // For Objective-C methods that take arguments, build the selector slots.
1427 for (unsigned i = 0, end = Method->param_size(); i != end; ++i) {
1428 // Objective-C method selector parts are considered as identifiers instead
1429 // of "external parameters" as in Swift. This is because Objective-C method
1430 // symbols are referenced with the entire selector, instead of just the
1431 // method name in Swift.
1433 ParamID.append(":");
1434 Fragments.appendSpace().append(
1436
1437 // Build the internal parameter.
1438 const ParmVarDecl *Param = Method->getParamDecl(i);
1439 Fragments.append(getFragmentsForParam(Param));
1440 }
1441
1442 return Fragments.appendSemicolon();
1443}
1444
1446 const ObjCPropertyDecl *Property) {
1447 DeclarationFragments Fragments, After;
1448
1449 // Build the Objective-C property keyword.
1451
1452 const auto Attributes = Property->getPropertyAttributesAsWritten();
1453 // Build the attributes if there is any associated with the property.
1454 if (Attributes != ObjCPropertyAttribute::kind_noattr) {
1455 // No leading comma for the first attribute.
1456 bool First = true;
1458 // Helper function to render the attribute.
1459 auto RenderAttribute =
1460 [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling,
1461 StringRef Arg = "",
1464 // Check if the `Kind` attribute is set for this property.
1465 if ((Attributes & Kind) && !Spelling.empty()) {
1466 // Add a leading comma if this is not the first attribute rendered.
1467 if (!First)
1469 // Render the spelling of this attribute `Kind` as a keyword.
1470 Fragments.append(Spelling,
1472 // If this attribute takes in arguments (e.g. `getter=getterName`),
1473 // render the arguments.
1474 if (!Arg.empty())
1476 .append(Arg, ArgKind);
1477 First = false;
1478 }
1479 };
1480
1481 // Go through all possible Objective-C property attributes and render set
1482 // ones.
1483 RenderAttribute(ObjCPropertyAttribute::kind_class, "class");
1484 RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct");
1485 RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic");
1486 RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic");
1487 RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign");
1488 RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain");
1489 RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong");
1490 RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy");
1491 RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak");
1493 "unsafe_unretained");
1494 RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite");
1495 RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly");
1496 RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter",
1497 Property->getGetterName().getAsString());
1498 RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter",
1499 Property->getSetterName().getAsString());
1500
1501 // Render nullability attributes.
1502 if (Attributes & ObjCPropertyAttribute::kind_nullability) {
1503 QualType Type = Property->getType();
1504 if (const auto Nullability =
1506 if (!First)
1508 if (*Nullability == NullabilityKind::Unspecified &&
1510 Fragments.append("null_resettable",
1512 else
1513 Fragments.append(
1514 getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true),
1516 First = false;
1517 }
1518 }
1519
1521 }
1522
1523 Fragments.appendSpace();
1524
1525 FunctionTypeLoc BlockLoc;
1526 FunctionProtoTypeLoc BlockProtoLoc;
1527 findTypeLocForBlockDecl(Property->getTypeSourceInfo(), BlockLoc,
1528 BlockProtoLoc);
1529
1530 auto PropType = Property->getType();
1531 if (!BlockLoc)
1532 Fragments
1533 .append(getFragmentsForType(PropType, Property->getASTContext(), After))
1534 .appendSpace();
1535 else
1536 Fragments.append(
1537 getFragmentsForBlock(Property, BlockLoc, BlockProtoLoc, After));
1538
1539 return Fragments
1540 .append(Property->getName(),
1542 .append(std::move(After))
1543 .appendSemicolon();
1544}
1545
1547 const ObjCProtocolDecl *Protocol) {
1548 DeclarationFragments Fragments;
1549 // Build basic protocol declaration.
1551 .appendSpace()
1552 .append(Protocol->getName(),
1554
1555 // If this protocol conforms to other protocols, build the conformance list.
1556 if (!Protocol->protocols().empty()) {
1558 for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin();
1559 It != Protocol->protocol_end(); It++) {
1560 // Add a leading comma if this is not the first protocol rendered.
1561 if (It != Protocol->protocol_begin())
1563
1564 SmallString<128> USR;
1565 index::generateUSRForDecl(*It, USR);
1566 Fragments.append((*It)->getName(),
1568 *It);
1569 }
1571 }
1572
1573 return Fragments;
1574}
1575
1577 const TypedefNameDecl *Decl) {
1578 DeclarationFragments Fragments, After;
1580 .appendSpace()
1581 .append(getFragmentsForType(Decl->getUnderlyingType(),
1582 Decl->getASTContext(), After))
1583 .append(std::move(After))
1584 .appendSpace()
1586
1587 return Fragments.appendSemicolon();
1588}
1589
1590// Instantiate template for FunctionDecl.
1591template FunctionSignature
1593
1594// Instantiate template for ObjCMethodDecl.
1595template FunctionSignature
1597
1598// Subheading of a symbol defaults to its name.
1601 DeclarationFragments Fragments;
1602 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
1603 Fragments.append(cast<CXXRecordDecl>(Decl->getDeclContext())->getName(),
1605 else if (isa<CXXConversionDecl>(Decl)) {
1606 Fragments.append(
1607 cast<CXXConversionDecl>(Decl)->getConversionType().getAsString(),
1609 } else if (isa<CXXMethodDecl>(Decl) &&
1610 cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) {
1611 Fragments.append(Decl->getNameAsString(),
1613 } else if (!Decl->getName().empty())
1614 Fragments.append(Decl->getName(),
1616 return Fragments;
1617}
1618
1619// Subheading of an Objective-C method is a `+` or `-` sign indicating whether
1620// it's a class method or an instance method, followed by the selector name.
1623 DeclarationFragments Fragments;
1624 if (Method->isClassMethod())
1626 else if (Method->isInstanceMethod())
1628
1629 return Fragments.append(Method->getNameAsString(),
1631}
1632
1633// Subheading of a symbol defaults to its name.
1636 DeclarationFragments Fragments;
1638 return Fragments;
1639}
Forward declaration of all AST node types.
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:2979
const CFGBlock * Block
Definition: HTMLLogger.cpp:153
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
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:185
QualType getUnqualifiedObjCPointerType(QualType type) const
getUnqualifiedObjCPointerType - Returns version of Objective-C pointer type with lifetime qualifier r...
Definition: ASTContext.h:2210
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3537
Type source information for an attributed type.
Definition: TypeLoc.h:875
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:4854
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4496
Wrapper for source info for block pointers.
Definition: TypeLoc.h:1314
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2862
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
bool isVolatile() const
Definition: DeclCXX.h:2113
bool isConst() const
Definition: DeclCXX.h:2112
bool isStatic() const
Definition: DeclCXX.cpp:2186
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.
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3575
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:249
DeclContext * getDeclContext()
Definition: DeclBase.h:454
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:799
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6387
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3299
Represents an enum.
Definition: Decl.h:3869
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Definition: Decl.h:4029
Represents a member of a struct/union/class.
Definition: Decl.h:3059
Represents a function declaration or definition.
Definition: Decl.h:1971
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2708
ExceptionSpecificationType getExceptionSpecType() const
Gets the ExceptionSpecificationType as declared.
Definition: Decl.h:2780
QualType getReturnType() const
Definition: Decl.h:2756
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
Definition: Decl.h:2434
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3688
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5031
Declaration of a template function.
Definition: DeclTemplate.h:957
Wrapper for source info for functions.
Definition: TypeLoc.h:1428
StringRef getName() const
Return the actual identifier string.
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:514
An lvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3443
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:416
This represents a decl that may have a name.
Definition: Decl.h:249
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
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:292
Represents a C++ namespace alias.
Definition: DeclCXX.h:3120
Represent a C++ namespace.
Definition: Decl.h:547
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
Definition: Decl.h:605
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:2326
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
unsigned param_size() const
Definition: DeclObjC.h:347
Selector getSelector() const
Definition: DeclObjC.h:327
bool isInstanceMethod() const
Definition: DeclObjC.h:426
ParmVarDecl * getParamDecl(unsigned Idx)
Definition: DeclObjC.h:377
QualType getReturnType() const
Definition: DeclObjC.h:329
bool isClassMethod() const
Definition: DeclObjC.h:434
Represents a pointer to an Objective C object.
Definition: Type.h:7024
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Definition: Type.h:7099
bool isObjCIdOrClassType() const
True if this is equivalent to the 'id' or 'Class' type,.
Definition: Type.h:7093
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:2155
Sugar for parentheses used when specifying types.
Definition: Type.h:3132
Represents a parameter to a function.
Definition: Decl.h:1761
bool isObjCMethodParameter() const
Definition: Decl.h:1804
QualType getOriginalType() const
Definition: Decl.cpp:2920
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:7396
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1341
Wrapper of type source information for a type with non-trivial direct qualifiers.
Definition: TypeLoc.h:289
The collection of all-type qualifiers we support.
Definition: Type.h:318
bool hasConst() const
Definition: Type.h:443
bool hasRestrict() const
Definition: Type.h:463
bool hasVolatile() const
Definition: Type.h:453
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3461
Represents a struct/union/class.
Definition: Decl.h:4170
Declaration of a redeclarable template.
Definition: DeclTemplate.h:716
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:3586
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3814
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
Definition: TemplateBase.h:89
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:139
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6105
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
Definition: TypeLoc.h:338
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:89
TypeLoc IgnoreParens() const
Definition: TypeLoc.h:1225
A container of type source information.
Definition: Type.h:7346
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:256
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7357
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition: Type.cpp:3259
The base class of the type hierarchy.
Definition: Type.h:1827
bool isBlockPointerType() const
Definition: Type.h:7636
bool isFunctionPointerType() const
Definition: Type.h:7662
bool isPointerType() const
Definition: Type.h:7628
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:705
bool isObjCIdType() const
Definition: Type.h:7797
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8199
bool isObjCObjectPointerType() const
Definition: Type.h:7764
bool isAnyPointerType() const
Definition: Type.h:7632
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8146
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3434
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1549
static const char * getStorageClassSpecifierString(StorageClass SC)
Return the string used to specify the storage class SC.
Definition: Decl.cpp:2111
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1270
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1155
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 getFragmentsForTemplateArguments(const ArrayRef< TemplateArgument >, ASTContext &, const std::optional< ArrayRef< TemplateArgumentLoc > >)
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 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 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 getFragmentsForRecordDecl(const RecordDecl *)
Build DeclarationFragments for a struct/union record declaration RecordDecl.
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 & append(DeclarationFragments Other)
Append another DeclarationFragments to the end.
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.
DeclarationFragments & removeTrailingSemicolon()
Removes a trailing semicolon character if present.
static StringRef getFragmentKindString(FragmentKind Kind)
Get the string description of a FragmentKind Kind.
static DeclarationFragments getStructureTypeFragment(const RecordDecl *Decl)
DeclarationFragments & appendSemicolon()
Append a text Fragment of a semicolon character.
static FragmentKind parseFragmentKindFromString(StringRef S)
Get the corresponding FragmentKind from string S.
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:245
@ SC_Auto
Definition: Specifiers.h:253
@ SC_PrivateExtern
Definition: Specifiers.h:250
@ SC_Extern
Definition: Specifiers.h:248
@ SC_Register
Definition: Specifiers.h:254
@ SC_Static
Definition: Specifiers.h:249
@ SC_None
Definition: Specifiers.h:247
@ Property
The type of a property.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.
const FunctionProtoType * T
llvm::StringRef getAsString(SyncScope S)
Definition: SyncScope.h:60
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: Type.h:6290
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ None
No keyword precedes the qualified type name.
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)
Diagnostic wrappers for TextAPI types for error reporting.
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:873
const Type * Ty
The locally-unqualified type.
Definition: Type.h:875
Qualifiers Quals
The local qualifiers.
Definition: Type.h:878
Fragment holds information of a single fragment.