xref: /llvm-project/clang/include/clang/ExtractAPI/DeclarationFragments.h (revision b1b24d751776d5fd2218a5cb43a8d103bf59fa32)
189f6b26fSZixu Wang //===- ExtractAPI/DeclarationFragments.h ------------------------*- C++ -*-===//
289f6b26fSZixu Wang //
389f6b26fSZixu Wang // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
489f6b26fSZixu Wang // See https://llvm.org/LICENSE.txt for license information.
589f6b26fSZixu Wang // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
689f6b26fSZixu Wang //
789f6b26fSZixu Wang //===----------------------------------------------------------------------===//
889f6b26fSZixu Wang ///
989f6b26fSZixu Wang /// \file
1089f6b26fSZixu Wang /// This file defines the Declaration Fragments related classes.
1189f6b26fSZixu Wang ///
1289f6b26fSZixu Wang /// Declaration Fragments represent parts of a symbol declaration tagged with
1389f6b26fSZixu Wang /// syntactic/semantic information.
1489f6b26fSZixu Wang /// See https://github.com/apple/swift-docc-symbolkit
1589f6b26fSZixu Wang ///
1689f6b26fSZixu Wang //===----------------------------------------------------------------------===//
1789f6b26fSZixu Wang 
1889f6b26fSZixu Wang #ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
1989f6b26fSZixu Wang #define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
2089f6b26fSZixu Wang 
2189f6b26fSZixu Wang #include "clang/AST/ASTContext.h"
2289f6b26fSZixu Wang #include "clang/AST/Decl.h"
2389f6b26fSZixu Wang #include "clang/AST/DeclCXX.h"
249b36e126SZixu Wang #include "clang/AST/DeclObjC.h"
257ba37f4eSErick Velez #include "clang/AST/DeclTemplate.h"
268d8c8981SErick Velez #include "clang/AST/ExprCXX.h"
276b89fab8SDaniel Grumberg #include "clang/AST/TypeLoc.h"
288d8c8981SErick Velez #include "clang/Basic/Specifiers.h"
29529a0570SDaniel Grumberg #include "clang/Lex/MacroInfo.h"
302bcbe40fSDaniel Grumberg #include <iterator>
312bcbe40fSDaniel Grumberg #include <utility>
3289f6b26fSZixu Wang #include <vector>
3389f6b26fSZixu Wang 
3489f6b26fSZixu Wang namespace clang {
3589f6b26fSZixu Wang namespace extractapi {
3689f6b26fSZixu Wang 
3789f6b26fSZixu Wang /// DeclarationFragments is a vector of tagged important parts of a symbol's
3889f6b26fSZixu Wang /// declaration.
3989f6b26fSZixu Wang ///
4089f6b26fSZixu Wang /// The fragments sequence can be joined to form spans of declaration text, with
4189f6b26fSZixu Wang /// attached information useful for purposes like syntax-highlighting etc.
4289f6b26fSZixu Wang /// For example:
4389f6b26fSZixu Wang /// \code
4489f6b26fSZixu Wang ///   const -> keyword    "const"
4589f6b26fSZixu Wang ///   int   -> type       "int"
4689f6b26fSZixu Wang ///   pi;   -> identifier "pi"
4789f6b26fSZixu Wang /// \endcode
4889f6b26fSZixu Wang class DeclarationFragments {
4989f6b26fSZixu Wang public:
5089f6b26fSZixu Wang   DeclarationFragments() = default;
5189f6b26fSZixu Wang 
5289f6b26fSZixu Wang   /// The kind of a fragment.
5389f6b26fSZixu Wang   enum class FragmentKind {
5489f6b26fSZixu Wang     /// Unknown fragment kind.
5589f6b26fSZixu Wang     None,
5689f6b26fSZixu Wang 
5789f6b26fSZixu Wang     Keyword,
5889f6b26fSZixu Wang     Attribute,
5989f6b26fSZixu Wang     NumberLiteral,
6089f6b26fSZixu Wang     StringLiteral,
6189f6b26fSZixu Wang     Identifier,
6289f6b26fSZixu Wang 
6389f6b26fSZixu Wang     /// Identifier that refers to a type in the context.
6489f6b26fSZixu Wang     TypeIdentifier,
6589f6b26fSZixu Wang 
6689f6b26fSZixu Wang     /// Parameter that's used as generics in the context. For example template
6789f6b26fSZixu Wang     /// parameters.
6889f6b26fSZixu Wang     GenericParameter,
6989f6b26fSZixu Wang 
7089f6b26fSZixu Wang     /// External parameters in Objective-C methods.
7189f6b26fSZixu Wang     /// For example, \c forKey in
7289f6b26fSZixu Wang     /// \code{.m}
7389f6b26fSZixu Wang     ///   - (void) setValue:(Value)value forKey(Key)key
7489f6b26fSZixu Wang     /// \endcode
7589f6b26fSZixu Wang     ExternalParam,
7689f6b26fSZixu Wang 
7789f6b26fSZixu Wang     /// Internal/local parameters in Objective-C methods.
7889f6b26fSZixu Wang     /// For example, \c key in
7989f6b26fSZixu Wang     /// \code{.m}
8089f6b26fSZixu Wang     ///   - (void) setValue:(Value)value forKey(Key)key
8189f6b26fSZixu Wang     /// \endcode
8289f6b26fSZixu Wang     InternalParam,
8389f6b26fSZixu Wang 
8489f6b26fSZixu Wang     Text,
8589f6b26fSZixu Wang   };
8689f6b26fSZixu Wang 
8789f6b26fSZixu Wang   /// Fragment holds information of a single fragment.
8889f6b26fSZixu Wang   struct Fragment {
8989f6b26fSZixu Wang     std::string Spelling;
9089f6b26fSZixu Wang     FragmentKind Kind;
9189f6b26fSZixu Wang 
9289f6b26fSZixu Wang     /// The USR of the fragment symbol, if applicable.
9389f6b26fSZixu Wang     std::string PreciseIdentifier;
9489f6b26fSZixu Wang 
957a851921SDaniel Grumberg     /// The associated declaration, if applicable. This is not intended to be
967a851921SDaniel Grumberg     /// used outside of libclang.
977a851921SDaniel Grumberg     const Decl *Declaration;
987a851921SDaniel Grumberg 
997a851921SDaniel Grumberg     Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier,
1007a851921SDaniel Grumberg              const Decl *Declaration)
1017a851921SDaniel Grumberg         : Spelling(Spelling), Kind(Kind), PreciseIdentifier(PreciseIdentifier),
1027a851921SDaniel Grumberg           Declaration(Declaration) {}
10389f6b26fSZixu Wang   };
10489f6b26fSZixu Wang 
10592180daeSruturaj4   using FragmentIterator = std::vector<Fragment>::iterator;
10692180daeSruturaj4   using ConstFragmentIterator = std::vector<Fragment>::const_iterator;
10792180daeSruturaj4 
10889f6b26fSZixu Wang   const std::vector<Fragment> &getFragments() const { return Fragments; }
10989f6b26fSZixu Wang 
11092180daeSruturaj4   FragmentIterator begin() { return Fragments.begin(); }
11192180daeSruturaj4 
11292180daeSruturaj4   FragmentIterator end() { return Fragments.end(); }
11392180daeSruturaj4 
11492180daeSruturaj4   ConstFragmentIterator cbegin() const { return Fragments.cbegin(); }
11592180daeSruturaj4 
11692180daeSruturaj4   ConstFragmentIterator cend() const { return Fragments.cend(); }
117135ce2f8Sruturaj4 
1182bcbe40fSDaniel Grumberg   /// Prepend another DeclarationFragments to the beginning.
1192bcbe40fSDaniel Grumberg   ///
1202bcbe40fSDaniel Grumberg   /// \returns a reference to the DeclarationFragments object itself after
1212bcbe40fSDaniel Grumberg   /// appending to chain up consecutive operations.
1222bcbe40fSDaniel Grumberg   DeclarationFragments &prepend(DeclarationFragments Other) {
1232bcbe40fSDaniel Grumberg     return insert(begin(), std::move(Other));
1243ac55098Sruturaj4   }
1253ac55098Sruturaj4 
1262bcbe40fSDaniel Grumberg   /// Append another DeclarationFragments to the end.
1272bcbe40fSDaniel Grumberg   ///
1282bcbe40fSDaniel Grumberg   /// \returns a reference to the DeclarationFragments object itself after
1292bcbe40fSDaniel Grumberg   /// appending to chain up consecutive operations.
1302bcbe40fSDaniel Grumberg   DeclarationFragments &append(DeclarationFragments Other) {
1312bcbe40fSDaniel Grumberg     return insert(end(), std::move(Other));
1323ac55098Sruturaj4   }
1333ac55098Sruturaj4 
13489f6b26fSZixu Wang   /// Append a new Fragment to the end of the Fragments.
13589f6b26fSZixu Wang   ///
13689f6b26fSZixu Wang   /// \returns a reference to the DeclarationFragments object itself after
1372bcbe40fSDaniel Grumberg   /// appending to chain up consecutive operations.
13889f6b26fSZixu Wang   DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
1397a851921SDaniel Grumberg                                StringRef PreciseIdentifier = "",
1407a851921SDaniel Grumberg                                const Decl *Declaration = nullptr) {
14189f6b26fSZixu Wang     if (Kind == FragmentKind::Text && !Fragments.empty() &&
14289f6b26fSZixu Wang         Fragments.back().Kind == FragmentKind::Text) {
14389f6b26fSZixu Wang       // If appending a text fragment, and the last fragment is also text,
14489f6b26fSZixu Wang       // merge into the last fragment.
14589f6b26fSZixu Wang       Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
14689f6b26fSZixu Wang     } else {
1477a851921SDaniel Grumberg       Fragments.emplace_back(Spelling, Kind, PreciseIdentifier, Declaration);
14889f6b26fSZixu Wang     }
14989f6b26fSZixu Wang     return *this;
15089f6b26fSZixu Wang   }
15189f6b26fSZixu Wang 
1522bcbe40fSDaniel Grumberg   /// Inserts another DeclarationFragments at \p It.
15389f6b26fSZixu Wang   ///
15489f6b26fSZixu Wang   /// \returns a reference to the DeclarationFragments object itself after
1552bcbe40fSDaniel Grumberg   /// appending to chain up consecutive operations.
1562bcbe40fSDaniel Grumberg   DeclarationFragments &insert(FragmentIterator It,
1572bcbe40fSDaniel Grumberg                                DeclarationFragments Other) {
1582bcbe40fSDaniel Grumberg     if (Other.Fragments.empty())
1592bcbe40fSDaniel Grumberg       return *this;
1602bcbe40fSDaniel Grumberg 
1612bcbe40fSDaniel Grumberg     if (Fragments.empty()) {
1622bcbe40fSDaniel Grumberg       Fragments = std::move(Other.Fragments);
1632bcbe40fSDaniel Grumberg       return *this;
1642bcbe40fSDaniel Grumberg     }
1652bcbe40fSDaniel Grumberg 
1662bcbe40fSDaniel Grumberg     const auto &OtherFrags = Other.Fragments;
1672bcbe40fSDaniel Grumberg     auto ToInsertBegin = std::make_move_iterator(Other.begin());
1682bcbe40fSDaniel Grumberg     auto ToInsertEnd = std::make_move_iterator(Other.end());
1692bcbe40fSDaniel Grumberg 
1702bcbe40fSDaniel Grumberg     // If we aren't inserting at the end let's make sure that we merge their
1712bcbe40fSDaniel Grumberg     // last fragment with It if both are text fragments.
1722bcbe40fSDaniel Grumberg     if (It != end() && It->Kind == FragmentKind::Text &&
1732bcbe40fSDaniel Grumberg         OtherFrags.back().Kind == FragmentKind::Text) {
1742bcbe40fSDaniel Grumberg       auto &TheirBackSpelling = OtherFrags.back().Spelling;
1752bcbe40fSDaniel Grumberg       It->Spelling.reserve(It->Spelling.size() + TheirBackSpelling.size());
1762bcbe40fSDaniel Grumberg       It->Spelling.insert(It->Spelling.begin(), TheirBackSpelling.begin(),
1772bcbe40fSDaniel Grumberg                           TheirBackSpelling.end());
1782bcbe40fSDaniel Grumberg       --ToInsertEnd;
1792bcbe40fSDaniel Grumberg     }
1802bcbe40fSDaniel Grumberg 
1812bcbe40fSDaniel Grumberg     // If we aren't inserting at the beginning we want to merge their first
1822bcbe40fSDaniel Grumberg     // fragment with the fragment before It if both are text fragments.
1832bcbe40fSDaniel Grumberg     if (It != begin() && std::prev(It)->Kind == FragmentKind::Text &&
1842bcbe40fSDaniel Grumberg         OtherFrags.front().Kind == FragmentKind::Text) {
1852bcbe40fSDaniel Grumberg       auto PrevIt = std::prev(It);
1862bcbe40fSDaniel Grumberg       auto &TheirFrontSpelling = OtherFrags.front().Spelling;
1872bcbe40fSDaniel Grumberg       PrevIt->Spelling.reserve(PrevIt->Spelling.size() +
1882bcbe40fSDaniel Grumberg                                TheirFrontSpelling.size());
1892bcbe40fSDaniel Grumberg       PrevIt->Spelling.append(TheirFrontSpelling);
1902bcbe40fSDaniel Grumberg       ++ToInsertBegin;
1912bcbe40fSDaniel Grumberg     }
1922bcbe40fSDaniel Grumberg 
1932bcbe40fSDaniel Grumberg     Fragments.insert(It, ToInsertBegin, ToInsertEnd);
19489f6b26fSZixu Wang     return *this;
19589f6b26fSZixu Wang   }
19689f6b26fSZixu Wang 
1977ba37f4eSErick Velez   DeclarationFragments &pop_back() {
1987ba37f4eSErick Velez     Fragments.pop_back();
1997ba37f4eSErick Velez     return *this;
2007ba37f4eSErick Velez   }
2017ba37f4eSErick Velez 
202e8174456SErick Velez   DeclarationFragments &replace(std::string NewSpelling, unsigned Position) {
203e8174456SErick Velez     Fragments.at(Position).Spelling = NewSpelling;
204e8174456SErick Velez     return *this;
205e8174456SErick Velez   }
206e8174456SErick Velez 
20789f6b26fSZixu Wang   /// Append a text Fragment of a space character.
20889f6b26fSZixu Wang   ///
20989f6b26fSZixu Wang   /// \returns a reference to the DeclarationFragments object itself after
2102bcbe40fSDaniel Grumberg   /// appending to chain up consecutive operations.
21189f6b26fSZixu Wang   DeclarationFragments &appendSpace();
21289f6b26fSZixu Wang 
213e05c1b46SDaniel Grumberg   /// Append a text Fragment of a semicolon character.
214e05c1b46SDaniel Grumberg   ///
215e05c1b46SDaniel Grumberg   /// \returns a reference to the DeclarationFragments object itself after
2162bcbe40fSDaniel Grumberg   /// appending to chain up consecutive operations.
217e05c1b46SDaniel Grumberg   DeclarationFragments &appendSemicolon();
218e05c1b46SDaniel Grumberg 
219e05c1b46SDaniel Grumberg   /// Removes a trailing semicolon character if present.
220e05c1b46SDaniel Grumberg   ///
221e05c1b46SDaniel Grumberg   /// \returns a reference to the DeclarationFragments object itself after
222e05c1b46SDaniel Grumberg   /// removing to chain up consecutive operations.
223e05c1b46SDaniel Grumberg   DeclarationFragments &removeTrailingSemicolon();
224e05c1b46SDaniel Grumberg 
22589f6b26fSZixu Wang   /// Get the string description of a FragmentKind \p Kind.
22689f6b26fSZixu Wang   static StringRef getFragmentKindString(FragmentKind Kind);
22789f6b26fSZixu Wang 
22889f6b26fSZixu Wang   /// Get the corresponding FragmentKind from string \p S.
22989f6b26fSZixu Wang   static FragmentKind parseFragmentKindFromString(StringRef S);
23089f6b26fSZixu Wang 
23175f55eb3SErick Velez   static DeclarationFragments
23275f55eb3SErick Velez   getExceptionSpecificationString(ExceptionSpecificationType ExceptionSpec);
23375f55eb3SErick Velez 
23475f55eb3SErick Velez   static DeclarationFragments getStructureTypeFragment(const RecordDecl *Decl);
23575f55eb3SErick Velez 
23689f6b26fSZixu Wang private:
237e05c1b46SDaniel Grumberg   DeclarationFragments &appendUnduplicatedTextCharacter(char Character);
23889f6b26fSZixu Wang   std::vector<Fragment> Fragments;
23989f6b26fSZixu Wang };
24089f6b26fSZixu Wang 
24175f55eb3SErick Velez class AccessControl {
24275f55eb3SErick Velez public:
24375f55eb3SErick Velez   AccessControl(std::string Access) : Access(Access) {}
244e05c1b46SDaniel Grumberg   AccessControl() : Access("public") {}
24575f55eb3SErick Velez 
24675f55eb3SErick Velez   const std::string &getAccess() const { return Access; }
24775f55eb3SErick Velez 
24875f55eb3SErick Velez   bool empty() const { return Access.empty(); }
24975f55eb3SErick Velez 
25075f55eb3SErick Velez private:
25175f55eb3SErick Velez   std::string Access;
25275f55eb3SErick Velez };
25375f55eb3SErick Velez 
25489f6b26fSZixu Wang /// Store function signature information with DeclarationFragments of the
25589f6b26fSZixu Wang /// return type and parameters.
25689f6b26fSZixu Wang class FunctionSignature {
25789f6b26fSZixu Wang public:
25889f6b26fSZixu Wang   FunctionSignature() = default;
25989f6b26fSZixu Wang 
26089f6b26fSZixu Wang   /// Parameter holds the name and DeclarationFragments of a single parameter.
26189f6b26fSZixu Wang   struct Parameter {
26289f6b26fSZixu Wang     std::string Name;
26389f6b26fSZixu Wang     DeclarationFragments Fragments;
26489f6b26fSZixu Wang 
26589f6b26fSZixu Wang     Parameter(StringRef Name, DeclarationFragments Fragments)
26689f6b26fSZixu Wang         : Name(Name), Fragments(Fragments) {}
26789f6b26fSZixu Wang   };
26889f6b26fSZixu Wang 
26989f6b26fSZixu Wang   const std::vector<Parameter> &getParameters() const { return Parameters; }
27089f6b26fSZixu Wang   const DeclarationFragments &getReturnType() const { return ReturnType; }
27189f6b26fSZixu Wang 
27289f6b26fSZixu Wang   FunctionSignature &addParameter(StringRef Name,
27389f6b26fSZixu Wang                                   DeclarationFragments Fragments) {
27489f6b26fSZixu Wang     Parameters.emplace_back(Name, Fragments);
27589f6b26fSZixu Wang     return *this;
27689f6b26fSZixu Wang   }
27789f6b26fSZixu Wang 
27889f6b26fSZixu Wang   void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
27989f6b26fSZixu Wang 
28089f6b26fSZixu Wang   /// Determine if the FunctionSignature is empty.
28189f6b26fSZixu Wang   ///
28289f6b26fSZixu Wang   /// \returns true if the return type DeclarationFragments is empty and there
28389f6b26fSZixu Wang   /// is no parameter, otherwise false.
28489f6b26fSZixu Wang   bool empty() const {
28589f6b26fSZixu Wang     return Parameters.empty() && ReturnType.getFragments().empty();
28689f6b26fSZixu Wang   }
28789f6b26fSZixu Wang 
28889f6b26fSZixu Wang private:
28989f6b26fSZixu Wang   std::vector<Parameter> Parameters;
29089f6b26fSZixu Wang   DeclarationFragments ReturnType;
29189f6b26fSZixu Wang };
29289f6b26fSZixu Wang 
29389f6b26fSZixu Wang /// A factory class to build DeclarationFragments for different kinds of Decl.
29489f6b26fSZixu Wang class DeclarationFragmentsBuilder {
29589f6b26fSZixu Wang public:
29675f55eb3SErick Velez   /// Build FunctionSignature for a function-like declaration \c FunctionT like
29775f55eb3SErick Velez   /// FunctionDecl, ObjCMethodDecl, or CXXMethodDecl.
29875f55eb3SErick Velez   ///
29975f55eb3SErick Velez   /// The logic and implementation of building a signature for a FunctionDecl,
30075f55eb3SErick Velez   /// CXXMethodDecl, and ObjCMethodDecl are exactly the same, but they do not
30175f55eb3SErick Velez   /// share a common base. This template helps reuse the code.
30275f55eb3SErick Velez   template <typename FunctionT>
30375f55eb3SErick Velez   static FunctionSignature getFunctionSignature(const FunctionT *Function);
30475f55eb3SErick Velez 
30575f55eb3SErick Velez   static AccessControl getAccessControl(const Decl *Decl) {
30675f55eb3SErick Velez     switch (Decl->getAccess()) {
30775f55eb3SErick Velez     case AS_public:
30808f034f9SErick Velez     case AS_none:
30975f55eb3SErick Velez       return AccessControl("public");
31075f55eb3SErick Velez     case AS_private:
31175f55eb3SErick Velez       return AccessControl("private");
31275f55eb3SErick Velez     case AS_protected:
31375f55eb3SErick Velez       return AccessControl("protected");
31475f55eb3SErick Velez     }
31575f55eb3SErick Velez     llvm_unreachable("Unhandled access control");
31675f55eb3SErick Velez   }
31775f55eb3SErick Velez 
31808f034f9SErick Velez   static DeclarationFragments
31908f034f9SErick Velez   getFragmentsForNamespace(const NamespaceDecl *Decl);
32008f034f9SErick Velez 
32189f6b26fSZixu Wang   /// Build DeclarationFragments for a variable declaration VarDecl.
32289f6b26fSZixu Wang   static DeclarationFragments getFragmentsForVar(const VarDecl *);
32389f6b26fSZixu Wang 
3248d8c8981SErick Velez   static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *);
3258d8c8981SErick Velez 
32689f6b26fSZixu Wang   /// Build DeclarationFragments for a function declaration FunctionDecl.
32789f6b26fSZixu Wang   static DeclarationFragments getFragmentsForFunction(const FunctionDecl *);
32889f6b26fSZixu Wang 
32971b4c226SZixu Wang   /// Build DeclarationFragments for an enum constant declaration
33071b4c226SZixu Wang   /// EnumConstantDecl.
33171b4c226SZixu Wang   static DeclarationFragments
33271b4c226SZixu Wang   getFragmentsForEnumConstant(const EnumConstantDecl *);
33371b4c226SZixu Wang 
33471b4c226SZixu Wang   /// Build DeclarationFragments for an enum declaration EnumDecl.
33571b4c226SZixu Wang   static DeclarationFragments getFragmentsForEnum(const EnumDecl *);
33671b4c226SZixu Wang 
3375bb5704cSZixu Wang   /// Build DeclarationFragments for a field declaration FieldDecl.
3385bb5704cSZixu Wang   static DeclarationFragments getFragmentsForField(const FieldDecl *);
3395bb5704cSZixu Wang 
34069fedaf8SDaniel Grumberg   /// Build DeclarationFragments for a struct/union record declaration
34169fedaf8SDaniel Grumberg   /// RecordDecl.
34269fedaf8SDaniel Grumberg   static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *);
3435bb5704cSZixu Wang 
34475f55eb3SErick Velez   static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *);
34575f55eb3SErick Velez 
34675f55eb3SErick Velez   static DeclarationFragments
34775f55eb3SErick Velez   getFragmentsForSpecialCXXMethod(const CXXMethodDecl *);
34875f55eb3SErick Velez 
34975f55eb3SErick Velez   static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *);
35075f55eb3SErick Velez 
35175f55eb3SErick Velez   static DeclarationFragments
35275f55eb3SErick Velez   getFragmentsForConversionFunction(const CXXConversionDecl *);
35375f55eb3SErick Velez 
35475f55eb3SErick Velez   static DeclarationFragments
35575f55eb3SErick Velez   getFragmentsForOverloadedOperator(const CXXMethodDecl *);
35675f55eb3SErick Velez 
3577ba37f4eSErick Velez   static DeclarationFragments
3587ba37f4eSErick Velez       getFragmentsForTemplateParameters(ArrayRef<NamedDecl *>);
3597ba37f4eSErick Velez 
3602b6c038eSErick Velez   static DeclarationFragments getFragmentsForTemplateArguments(
3612b6c038eSErick Velez       const ArrayRef<TemplateArgument>, ASTContext &,
3622b6c038eSErick Velez       const std::optional<ArrayRef<TemplateArgumentLoc>>);
3637ba37f4eSErick Velez 
3647ba37f4eSErick Velez   static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
3657ba37f4eSErick Velez 
3667ba37f4eSErick Velez   static DeclarationFragments
3677ba37f4eSErick Velez   getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *);
3687ba37f4eSErick Velez 
3697ba37f4eSErick Velez   static DeclarationFragments getFragmentsForClassTemplateSpecialization(
3707ba37f4eSErick Velez       const ClassTemplateSpecializationDecl *);
3717ba37f4eSErick Velez 
3727ba37f4eSErick Velez   static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(
3737ba37f4eSErick Velez       const ClassTemplatePartialSpecializationDecl *);
3747ba37f4eSErick Velez 
3758d8c8981SErick Velez   static DeclarationFragments getFragmentsForVarTemplateSpecialization(
3768d8c8981SErick Velez       const VarTemplateSpecializationDecl *);
3778d8c8981SErick Velez 
3788d8c8981SErick Velez   static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(
3798d8c8981SErick Velez       const VarTemplatePartialSpecializationDecl *);
3808d8c8981SErick Velez 
38180b787e8SErick Velez   static DeclarationFragments
38280b787e8SErick Velez   getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl);
38380b787e8SErick Velez 
38480b787e8SErick Velez   static DeclarationFragments
38580b787e8SErick Velez   getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl);
38680b787e8SErick Velez 
387178aad9bSZixu Wang   /// Build DeclarationFragments for an Objective-C category declaration
388178aad9bSZixu Wang   /// ObjCCategoryDecl.
389178aad9bSZixu Wang   static DeclarationFragments
390178aad9bSZixu Wang   getFragmentsForObjCCategory(const ObjCCategoryDecl *);
391178aad9bSZixu Wang 
3929b36e126SZixu Wang   /// Build DeclarationFragments for an Objective-C interface declaration
3939b36e126SZixu Wang   /// ObjCInterfaceDecl.
3949b36e126SZixu Wang   static DeclarationFragments
3959b36e126SZixu Wang   getFragmentsForObjCInterface(const ObjCInterfaceDecl *);
3969b36e126SZixu Wang 
3979b36e126SZixu Wang   /// Build DeclarationFragments for an Objective-C method declaration
3989b36e126SZixu Wang   /// ObjCMethodDecl.
3999b36e126SZixu Wang   static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *);
4009b36e126SZixu Wang 
4019b36e126SZixu Wang   /// Build DeclarationFragments for an Objective-C property declaration
4029b36e126SZixu Wang   /// ObjCPropertyDecl.
4039b36e126SZixu Wang   static DeclarationFragments
4049b36e126SZixu Wang   getFragmentsForObjCProperty(const ObjCPropertyDecl *);
4059b36e126SZixu Wang 
406d1d34bafSZixu Wang   /// Build DeclarationFragments for an Objective-C protocol declaration
407d1d34bafSZixu Wang   /// ObjCProtocolDecl.
408d1d34bafSZixu Wang   static DeclarationFragments
409d1d34bafSZixu Wang   getFragmentsForObjCProtocol(const ObjCProtocolDecl *);
410d1d34bafSZixu Wang 
411529a0570SDaniel Grumberg   /// Build DeclarationFragments for a macro.
412529a0570SDaniel Grumberg   ///
413529a0570SDaniel Grumberg   /// \param Name name of the macro.
414*b1b24d75SDaniel Grumberg   /// \param MI the associated MacroInfo.
415529a0570SDaniel Grumberg   static DeclarationFragments getFragmentsForMacro(StringRef Name,
416*b1b24d75SDaniel Grumberg                                                    const MacroInfo *MI);
417529a0570SDaniel Grumberg 
4189fc45ca0SDaniel Grumberg   /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
4199fc45ca0SDaniel Grumberg   static DeclarationFragments
4209fc45ca0SDaniel Grumberg   getFragmentsForTypedef(const TypedefNameDecl *Decl);
4219fc45ca0SDaniel Grumberg 
42289f6b26fSZixu Wang   /// Build sub-heading fragments for a NamedDecl.
42389f6b26fSZixu Wang   static DeclarationFragments getSubHeading(const NamedDecl *);
42489f6b26fSZixu Wang 
4259b36e126SZixu Wang   /// Build sub-heading fragments for an Objective-C method.
4269b36e126SZixu Wang   static DeclarationFragments getSubHeading(const ObjCMethodDecl *);
4279b36e126SZixu Wang 
428529a0570SDaniel Grumberg   /// Build a sub-heading for macro \p Name.
429529a0570SDaniel Grumberg   static DeclarationFragments getSubHeadingForMacro(StringRef Name);
430529a0570SDaniel Grumberg 
43189f6b26fSZixu Wang private:
43289f6b26fSZixu Wang   DeclarationFragmentsBuilder() = delete;
43389f6b26fSZixu Wang 
43489f6b26fSZixu Wang   /// Build DeclarationFragments for a QualType.
43589f6b26fSZixu Wang   static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
43689f6b26fSZixu Wang                                                   DeclarationFragments &);
43789f6b26fSZixu Wang 
43889f6b26fSZixu Wang   /// Build DeclarationFragments for a Type.
43989f6b26fSZixu Wang   static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
44089f6b26fSZixu Wang                                                   DeclarationFragments &);
44189f6b26fSZixu Wang 
44289f6b26fSZixu Wang   /// Build DeclarationFragments for a NestedNameSpecifier.
44389f6b26fSZixu Wang   static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
44489f6b26fSZixu Wang                                                  ASTContext &,
44589f6b26fSZixu Wang                                                  DeclarationFragments &);
44689f6b26fSZixu Wang 
44789f6b26fSZixu Wang   /// Build DeclarationFragments for Qualifiers.
44889f6b26fSZixu Wang   static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
44989f6b26fSZixu Wang 
45089f6b26fSZixu Wang   /// Build DeclarationFragments for a parameter variable declaration
45189f6b26fSZixu Wang   /// ParmVarDecl.
45289f6b26fSZixu Wang   static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
4536b89fab8SDaniel Grumberg 
4546b89fab8SDaniel Grumberg   static DeclarationFragments
4556b89fab8SDaniel Grumberg   getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block,
4566b89fab8SDaniel Grumberg                        FunctionProtoTypeLoc &BlockProto,
4576b89fab8SDaniel Grumberg                        DeclarationFragments &After);
45889f6b26fSZixu Wang };
45989f6b26fSZixu Wang 
46075f55eb3SErick Velez template <typename FunctionT>
46175f55eb3SErick Velez FunctionSignature
46275f55eb3SErick Velez DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
46375f55eb3SErick Velez   FunctionSignature Signature;
46475f55eb3SErick Velez 
46575f55eb3SErick Velez   DeclarationFragments ReturnType, After;
46680b787e8SErick Velez   ReturnType = getFragmentsForType(Function->getReturnType(),
46780b787e8SErick Velez                                    Function->getASTContext(), After);
46880b787e8SErick Velez   if (isa<FunctionDecl>(Function) &&
46980b787e8SErick Velez       dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
47026648daeSKazu Hirata       StringRef(ReturnType.begin()->Spelling).starts_with("type-parameter")) {
4712b6c038eSErick Velez     std::string ProperArgName = Function->getReturnType().getAsString();
47280b787e8SErick Velez     ReturnType.begin()->Spelling.swap(ProperArgName);
47380b787e8SErick Velez   }
47480b787e8SErick Velez   ReturnType.append(std::move(After));
47575f55eb3SErick Velez   Signature.setReturnType(ReturnType);
47675f55eb3SErick Velez 
47775f55eb3SErick Velez   for (const auto *Param : Function->parameters())
47875f55eb3SErick Velez     Signature.addParameter(Param->getName(), getFragmentsForParam(Param));
47975f55eb3SErick Velez 
48075f55eb3SErick Velez   return Signature;
48175f55eb3SErick Velez }
48275f55eb3SErick Velez 
48389f6b26fSZixu Wang } // namespace extractapi
48489f6b26fSZixu Wang } // namespace clang
48589f6b26fSZixu Wang 
48689f6b26fSZixu Wang #endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
487