Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:54

0001 //===- ExtractAPI/DeclarationFragments.h ------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file defines the Declaration Fragments related classes.
0011 ///
0012 /// Declaration Fragments represent parts of a symbol declaration tagged with
0013 /// syntactic/semantic information.
0014 /// See https://github.com/apple/swift-docc-symbolkit
0015 ///
0016 //===----------------------------------------------------------------------===//
0017 
0018 #ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
0019 #define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
0020 
0021 #include "clang/AST/ASTContext.h"
0022 #include "clang/AST/Decl.h"
0023 #include "clang/AST/DeclCXX.h"
0024 #include "clang/AST/DeclObjC.h"
0025 #include "clang/AST/DeclTemplate.h"
0026 #include "clang/AST/ExprCXX.h"
0027 #include "clang/AST/TypeLoc.h"
0028 #include "clang/Basic/Specifiers.h"
0029 #include "clang/Lex/MacroInfo.h"
0030 #include <iterator>
0031 #include <utility>
0032 #include <vector>
0033 
0034 namespace clang {
0035 namespace extractapi {
0036 
0037 /// DeclarationFragments is a vector of tagged important parts of a symbol's
0038 /// declaration.
0039 ///
0040 /// The fragments sequence can be joined to form spans of declaration text, with
0041 /// attached information useful for purposes like syntax-highlighting etc.
0042 /// For example:
0043 /// \code
0044 ///   const -> keyword    "const"
0045 ///   int   -> type       "int"
0046 ///   pi;   -> identifier "pi"
0047 /// \endcode
0048 class DeclarationFragments {
0049 public:
0050   DeclarationFragments() = default;
0051 
0052   /// The kind of a fragment.
0053   enum class FragmentKind {
0054     /// Unknown fragment kind.
0055     None,
0056 
0057     Keyword,
0058     Attribute,
0059     NumberLiteral,
0060     StringLiteral,
0061     Identifier,
0062 
0063     /// Identifier that refers to a type in the context.
0064     TypeIdentifier,
0065 
0066     /// Parameter that's used as generics in the context. For example template
0067     /// parameters.
0068     GenericParameter,
0069 
0070     /// External parameters in Objective-C methods.
0071     /// For example, \c forKey in
0072     /// \code{.m}
0073     ///   - (void) setValue:(Value)value forKey(Key)key
0074     /// \endcode
0075     ExternalParam,
0076 
0077     /// Internal/local parameters in Objective-C methods.
0078     /// For example, \c key in
0079     /// \code{.m}
0080     ///   - (void) setValue:(Value)value forKey(Key)key
0081     /// \endcode
0082     InternalParam,
0083 
0084     Text,
0085   };
0086 
0087   /// Fragment holds information of a single fragment.
0088   struct Fragment {
0089     std::string Spelling;
0090     FragmentKind Kind;
0091 
0092     /// The USR of the fragment symbol, if applicable.
0093     std::string PreciseIdentifier;
0094 
0095     /// The associated declaration, if applicable. This is not intended to be
0096     /// used outside of libclang.
0097     const Decl *Declaration;
0098 
0099     Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier,
0100              const Decl *Declaration)
0101         : Spelling(Spelling), Kind(Kind), PreciseIdentifier(PreciseIdentifier),
0102           Declaration(Declaration) {}
0103   };
0104 
0105   using FragmentIterator = std::vector<Fragment>::iterator;
0106   using ConstFragmentIterator = std::vector<Fragment>::const_iterator;
0107 
0108   const std::vector<Fragment> &getFragments() const { return Fragments; }
0109 
0110   FragmentIterator begin() { return Fragments.begin(); }
0111 
0112   FragmentIterator end() { return Fragments.end(); }
0113 
0114   ConstFragmentIterator cbegin() const { return Fragments.cbegin(); }
0115 
0116   ConstFragmentIterator cend() const { return Fragments.cend(); }
0117 
0118   /// Prepend another DeclarationFragments to the beginning.
0119   ///
0120   /// \returns a reference to the DeclarationFragments object itself after
0121   /// appending to chain up consecutive operations.
0122   DeclarationFragments &prepend(DeclarationFragments Other) {
0123     return insert(begin(), std::move(Other));
0124   }
0125 
0126   /// Append another DeclarationFragments to the end.
0127   ///
0128   /// \returns a reference to the DeclarationFragments object itself after
0129   /// appending to chain up consecutive operations.
0130   DeclarationFragments &append(DeclarationFragments Other) {
0131     return insert(end(), std::move(Other));
0132   }
0133 
0134   /// Append a new Fragment to the end of the Fragments.
0135   ///
0136   /// \returns a reference to the DeclarationFragments object itself after
0137   /// appending to chain up consecutive operations.
0138   DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
0139                                StringRef PreciseIdentifier = "",
0140                                const Decl *Declaration = nullptr) {
0141     if (Kind == FragmentKind::Text && !Fragments.empty() &&
0142         Fragments.back().Kind == FragmentKind::Text) {
0143       // If appending a text fragment, and the last fragment is also text,
0144       // merge into the last fragment.
0145       Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
0146     } else {
0147       Fragments.emplace_back(Spelling, Kind, PreciseIdentifier, Declaration);
0148     }
0149     return *this;
0150   }
0151 
0152   /// Inserts another DeclarationFragments at \p It.
0153   ///
0154   /// \returns a reference to the DeclarationFragments object itself after
0155   /// appending to chain up consecutive operations.
0156   DeclarationFragments &insert(FragmentIterator It,
0157                                DeclarationFragments Other) {
0158     if (Other.Fragments.empty())
0159       return *this;
0160 
0161     if (Fragments.empty()) {
0162       Fragments = std::move(Other.Fragments);
0163       return *this;
0164     }
0165 
0166     const auto &OtherFrags = Other.Fragments;
0167     auto ToInsertBegin = std::make_move_iterator(Other.begin());
0168     auto ToInsertEnd = std::make_move_iterator(Other.end());
0169 
0170     // If we aren't inserting at the end let's make sure that we merge their
0171     // last fragment with It if both are text fragments.
0172     if (It != end() && It->Kind == FragmentKind::Text &&
0173         OtherFrags.back().Kind == FragmentKind::Text) {
0174       auto &TheirBackSpelling = OtherFrags.back().Spelling;
0175       It->Spelling.reserve(It->Spelling.size() + TheirBackSpelling.size());
0176       It->Spelling.insert(It->Spelling.begin(), TheirBackSpelling.begin(),
0177                           TheirBackSpelling.end());
0178       --ToInsertEnd;
0179     }
0180 
0181     // If we aren't inserting at the beginning we want to merge their first
0182     // fragment with the fragment before It if both are text fragments.
0183     if (It != begin() && std::prev(It)->Kind == FragmentKind::Text &&
0184         OtherFrags.front().Kind == FragmentKind::Text) {
0185       auto PrevIt = std::prev(It);
0186       auto &TheirFrontSpelling = OtherFrags.front().Spelling;
0187       PrevIt->Spelling.reserve(PrevIt->Spelling.size() +
0188                                TheirFrontSpelling.size());
0189       PrevIt->Spelling.append(TheirFrontSpelling);
0190       ++ToInsertBegin;
0191     }
0192 
0193     Fragments.insert(It, ToInsertBegin, ToInsertEnd);
0194     return *this;
0195   }
0196 
0197   DeclarationFragments &pop_back() {
0198     Fragments.pop_back();
0199     return *this;
0200   }
0201 
0202   DeclarationFragments &replace(std::string NewSpelling, unsigned Position) {
0203     Fragments.at(Position).Spelling = NewSpelling;
0204     return *this;
0205   }
0206 
0207   /// Append a text Fragment of a space character.
0208   ///
0209   /// \returns a reference to the DeclarationFragments object itself after
0210   /// appending to chain up consecutive operations.
0211   DeclarationFragments &appendSpace();
0212 
0213   /// Append a text Fragment of a semicolon character.
0214   ///
0215   /// \returns a reference to the DeclarationFragments object itself after
0216   /// appending to chain up consecutive operations.
0217   DeclarationFragments &appendSemicolon();
0218 
0219   /// Removes a trailing semicolon character if present.
0220   ///
0221   /// \returns a reference to the DeclarationFragments object itself after
0222   /// removing to chain up consecutive operations.
0223   DeclarationFragments &removeTrailingSemicolon();
0224 
0225   /// Get the string description of a FragmentKind \p Kind.
0226   static StringRef getFragmentKindString(FragmentKind Kind);
0227 
0228   /// Get the corresponding FragmentKind from string \p S.
0229   static FragmentKind parseFragmentKindFromString(StringRef S);
0230 
0231   static DeclarationFragments
0232   getExceptionSpecificationString(ExceptionSpecificationType ExceptionSpec);
0233 
0234   static DeclarationFragments getStructureTypeFragment(const RecordDecl *Decl);
0235 
0236 private:
0237   DeclarationFragments &appendUnduplicatedTextCharacter(char Character);
0238   std::vector<Fragment> Fragments;
0239 };
0240 
0241 class AccessControl {
0242 public:
0243   AccessControl(std::string Access) : Access(Access) {}
0244   AccessControl() : Access("public") {}
0245 
0246   const std::string &getAccess() const { return Access; }
0247 
0248   bool empty() const { return Access.empty(); }
0249 
0250 private:
0251   std::string Access;
0252 };
0253 
0254 /// Store function signature information with DeclarationFragments of the
0255 /// return type and parameters.
0256 class FunctionSignature {
0257 public:
0258   FunctionSignature() = default;
0259 
0260   /// Parameter holds the name and DeclarationFragments of a single parameter.
0261   struct Parameter {
0262     std::string Name;
0263     DeclarationFragments Fragments;
0264 
0265     Parameter(StringRef Name, DeclarationFragments Fragments)
0266         : Name(Name), Fragments(Fragments) {}
0267   };
0268 
0269   const std::vector<Parameter> &getParameters() const { return Parameters; }
0270   const DeclarationFragments &getReturnType() const { return ReturnType; }
0271 
0272   FunctionSignature &addParameter(StringRef Name,
0273                                   DeclarationFragments Fragments) {
0274     Parameters.emplace_back(Name, Fragments);
0275     return *this;
0276   }
0277 
0278   void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
0279 
0280   /// Determine if the FunctionSignature is empty.
0281   ///
0282   /// \returns true if the return type DeclarationFragments is empty and there
0283   /// is no parameter, otherwise false.
0284   bool empty() const {
0285     return Parameters.empty() && ReturnType.getFragments().empty();
0286   }
0287 
0288 private:
0289   std::vector<Parameter> Parameters;
0290   DeclarationFragments ReturnType;
0291 };
0292 
0293 /// A factory class to build DeclarationFragments for different kinds of Decl.
0294 class DeclarationFragmentsBuilder {
0295 public:
0296   /// Build FunctionSignature for a function-like declaration \c FunctionT like
0297   /// FunctionDecl, ObjCMethodDecl, or CXXMethodDecl.
0298   ///
0299   /// The logic and implementation of building a signature for a FunctionDecl,
0300   /// CXXMethodDecl, and ObjCMethodDecl are exactly the same, but they do not
0301   /// share a common base. This template helps reuse the code.
0302   template <typename FunctionT>
0303   static FunctionSignature getFunctionSignature(const FunctionT *Function);
0304 
0305   static AccessControl getAccessControl(const Decl *Decl) {
0306     switch (Decl->getAccess()) {
0307     case AS_public:
0308     case AS_none:
0309       return AccessControl("public");
0310     case AS_private:
0311       return AccessControl("private");
0312     case AS_protected:
0313       return AccessControl("protected");
0314     }
0315     llvm_unreachable("Unhandled access control");
0316   }
0317 
0318   static DeclarationFragments
0319   getFragmentsForNamespace(const NamespaceDecl *Decl);
0320 
0321   /// Build DeclarationFragments for a variable declaration VarDecl.
0322   static DeclarationFragments getFragmentsForVar(const VarDecl *);
0323 
0324   static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *);
0325 
0326   /// Build DeclarationFragments for a function declaration FunctionDecl.
0327   static DeclarationFragments getFragmentsForFunction(const FunctionDecl *);
0328 
0329   /// Build DeclarationFragments for an enum constant declaration
0330   /// EnumConstantDecl.
0331   static DeclarationFragments
0332   getFragmentsForEnumConstant(const EnumConstantDecl *);
0333 
0334   /// Build DeclarationFragments for an enum declaration EnumDecl.
0335   static DeclarationFragments getFragmentsForEnum(const EnumDecl *);
0336 
0337   /// Build DeclarationFragments for a field declaration FieldDecl.
0338   static DeclarationFragments getFragmentsForField(const FieldDecl *);
0339 
0340   /// Build DeclarationFragments for a struct/union record declaration
0341   /// RecordDecl.
0342   static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *);
0343 
0344   static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *);
0345 
0346   static DeclarationFragments
0347   getFragmentsForSpecialCXXMethod(const CXXMethodDecl *);
0348 
0349   static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *);
0350 
0351   static DeclarationFragments
0352   getFragmentsForConversionFunction(const CXXConversionDecl *);
0353 
0354   static DeclarationFragments
0355   getFragmentsForOverloadedOperator(const CXXMethodDecl *);
0356 
0357   static DeclarationFragments
0358       getFragmentsForTemplateParameters(ArrayRef<NamedDecl *>);
0359 
0360   static DeclarationFragments getFragmentsForTemplateArguments(
0361       const ArrayRef<TemplateArgument>, ASTContext &,
0362       const std::optional<ArrayRef<TemplateArgumentLoc>>);
0363 
0364   static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
0365 
0366   static DeclarationFragments
0367   getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *);
0368 
0369   static DeclarationFragments getFragmentsForClassTemplateSpecialization(
0370       const ClassTemplateSpecializationDecl *);
0371 
0372   static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(
0373       const ClassTemplatePartialSpecializationDecl *);
0374 
0375   static DeclarationFragments getFragmentsForVarTemplateSpecialization(
0376       const VarTemplateSpecializationDecl *);
0377 
0378   static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(
0379       const VarTemplatePartialSpecializationDecl *);
0380 
0381   static DeclarationFragments
0382   getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl);
0383 
0384   static DeclarationFragments
0385   getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl);
0386 
0387   /// Build DeclarationFragments for an Objective-C category declaration
0388   /// ObjCCategoryDecl.
0389   static DeclarationFragments
0390   getFragmentsForObjCCategory(const ObjCCategoryDecl *);
0391 
0392   /// Build DeclarationFragments for an Objective-C interface declaration
0393   /// ObjCInterfaceDecl.
0394   static DeclarationFragments
0395   getFragmentsForObjCInterface(const ObjCInterfaceDecl *);
0396 
0397   /// Build DeclarationFragments for an Objective-C method declaration
0398   /// ObjCMethodDecl.
0399   static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *);
0400 
0401   /// Build DeclarationFragments for an Objective-C property declaration
0402   /// ObjCPropertyDecl.
0403   static DeclarationFragments
0404   getFragmentsForObjCProperty(const ObjCPropertyDecl *);
0405 
0406   /// Build DeclarationFragments for an Objective-C protocol declaration
0407   /// ObjCProtocolDecl.
0408   static DeclarationFragments
0409   getFragmentsForObjCProtocol(const ObjCProtocolDecl *);
0410 
0411   /// Build DeclarationFragments for a macro.
0412   ///
0413   /// \param Name name of the macro.
0414   /// \param MI the associated MacroInfo.
0415   static DeclarationFragments getFragmentsForMacro(StringRef Name,
0416                                                    const MacroInfo *MI);
0417 
0418   /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
0419   static DeclarationFragments
0420   getFragmentsForTypedef(const TypedefNameDecl *Decl);
0421 
0422   /// Build sub-heading fragments for a NamedDecl.
0423   static DeclarationFragments getSubHeading(const NamedDecl *);
0424 
0425   /// Build sub-heading fragments for an Objective-C method.
0426   static DeclarationFragments getSubHeading(const ObjCMethodDecl *);
0427 
0428   /// Build a sub-heading for macro \p Name.
0429   static DeclarationFragments getSubHeadingForMacro(StringRef Name);
0430 
0431 private:
0432   DeclarationFragmentsBuilder() = delete;
0433 
0434   /// Build DeclarationFragments for a QualType.
0435   static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
0436                                                   DeclarationFragments &);
0437 
0438   /// Build DeclarationFragments for a Type.
0439   static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
0440                                                   DeclarationFragments &);
0441 
0442   /// Build DeclarationFragments for a NestedNameSpecifier.
0443   static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
0444                                                  ASTContext &,
0445                                                  DeclarationFragments &);
0446 
0447   /// Build DeclarationFragments for Qualifiers.
0448   static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
0449 
0450   /// Build DeclarationFragments for a parameter variable declaration
0451   /// ParmVarDecl.
0452   static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
0453 
0454   static DeclarationFragments
0455   getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block,
0456                        FunctionProtoTypeLoc &BlockProto,
0457                        DeclarationFragments &After);
0458 };
0459 
0460 template <typename FunctionT>
0461 FunctionSignature
0462 DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
0463   FunctionSignature Signature;
0464 
0465   DeclarationFragments ReturnType, After;
0466   ReturnType = getFragmentsForType(Function->getReturnType(),
0467                                    Function->getASTContext(), After);
0468   if (isa<FunctionDecl>(Function) &&
0469       dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
0470       StringRef(ReturnType.begin()->Spelling).starts_with("type-parameter")) {
0471     std::string ProperArgName = Function->getReturnType().getAsString();
0472     ReturnType.begin()->Spelling.swap(ProperArgName);
0473   }
0474   ReturnType.append(std::move(After));
0475   Signature.setReturnType(ReturnType);
0476 
0477   for (const auto *Param : Function->parameters())
0478     Signature.addParameter(Param->getName(), getFragmentsForParam(Param));
0479 
0480   return Signature;
0481 }
0482 
0483 } // namespace extractapi
0484 } // namespace clang
0485 
0486 #endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H