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