DeclarationFragments.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  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. #include "clang/ExtractAPI/DeclarationFragments.h"
  14. #include "TypedefUnderlyingTypeResolver.h"
  15. #include "clang/Index/USRGeneration.h"
  16. #include "llvm/ADT/StringSwitch.h"
  17. using namespace clang::extractapi;
  18. using namespace llvm;
  19. DeclarationFragments &DeclarationFragments::appendSpace() {
  20. if (!Fragments.empty()) {
  21. Fragment &Last = Fragments.back();
  22. if (Last.Kind == FragmentKind::Text) {
  23. // Merge the extra space into the last fragment if the last fragment is
  24. // also text.
  25. if (Last.Spelling.back() != ' ') { // avoid extra trailing spaces.
  26. Last.Spelling.push_back(' ');
  27. }
  28. } else {
  29. append(" ", FragmentKind::Text);
  30. }
  31. }
  32. return *this;
  33. }
  34. StringRef DeclarationFragments::getFragmentKindString(
  35. DeclarationFragments::FragmentKind Kind) {
  36. switch (Kind) {
  37. case DeclarationFragments::FragmentKind::None:
  38. return "none";
  39. case DeclarationFragments::FragmentKind::Keyword:
  40. return "keyword";
  41. case DeclarationFragments::FragmentKind::Attribute:
  42. return "attribute";
  43. case DeclarationFragments::FragmentKind::NumberLiteral:
  44. return "number";
  45. case DeclarationFragments::FragmentKind::StringLiteral:
  46. return "string";
  47. case DeclarationFragments::FragmentKind::Identifier:
  48. return "identifier";
  49. case DeclarationFragments::FragmentKind::TypeIdentifier:
  50. return "typeIdentifier";
  51. case DeclarationFragments::FragmentKind::GenericParameter:
  52. return "genericParameter";
  53. case DeclarationFragments::FragmentKind::ExternalParam:
  54. return "externalParam";
  55. case DeclarationFragments::FragmentKind::InternalParam:
  56. return "internalParam";
  57. case DeclarationFragments::FragmentKind::Text:
  58. return "text";
  59. }
  60. llvm_unreachable("Unhandled FragmentKind");
  61. }
  62. DeclarationFragments::FragmentKind
  63. DeclarationFragments::parseFragmentKindFromString(StringRef S) {
  64. return llvm::StringSwitch<FragmentKind>(S)
  65. .Case("keyword", DeclarationFragments::FragmentKind::Keyword)
  66. .Case("attribute", DeclarationFragments::FragmentKind::Attribute)
  67. .Case("number", DeclarationFragments::FragmentKind::NumberLiteral)
  68. .Case("string", DeclarationFragments::FragmentKind::StringLiteral)
  69. .Case("identifier", DeclarationFragments::FragmentKind::Identifier)
  70. .Case("typeIdentifier",
  71. DeclarationFragments::FragmentKind::TypeIdentifier)
  72. .Case("genericParameter",
  73. DeclarationFragments::FragmentKind::GenericParameter)
  74. .Case("internalParam", DeclarationFragments::FragmentKind::InternalParam)
  75. .Case("externalParam", DeclarationFragments::FragmentKind::ExternalParam)
  76. .Case("text", DeclarationFragments::FragmentKind::Text)
  77. .Default(DeclarationFragments::FragmentKind::None);
  78. }
  79. // NNS stores C++ nested name specifiers, which are prefixes to qualified names.
  80. // Build declaration fragments for NNS recursively so that we have the USR for
  81. // every part in a qualified name, and also leaves the actual underlying type
  82. // cleaner for its own fragment.
  83. DeclarationFragments
  84. DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS,
  85. ASTContext &Context,
  86. DeclarationFragments &After) {
  87. DeclarationFragments Fragments;
  88. if (NNS->getPrefix())
  89. Fragments.append(getFragmentsForNNS(NNS->getPrefix(), Context, After));
  90. switch (NNS->getKind()) {
  91. case NestedNameSpecifier::Identifier:
  92. Fragments.append(NNS->getAsIdentifier()->getName(),
  93. DeclarationFragments::FragmentKind::Identifier);
  94. break;
  95. case NestedNameSpecifier::Namespace: {
  96. const NamespaceDecl *NS = NNS->getAsNamespace();
  97. if (NS->isAnonymousNamespace())
  98. return Fragments;
  99. SmallString<128> USR;
  100. index::generateUSRForDecl(NS, USR);
  101. Fragments.append(NS->getName(),
  102. DeclarationFragments::FragmentKind::Identifier, USR, NS);
  103. break;
  104. }
  105. case NestedNameSpecifier::NamespaceAlias: {
  106. const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias();
  107. SmallString<128> USR;
  108. index::generateUSRForDecl(Alias, USR);
  109. Fragments.append(Alias->getName(),
  110. DeclarationFragments::FragmentKind::Identifier, USR,
  111. Alias);
  112. break;
  113. }
  114. case NestedNameSpecifier::Global:
  115. // The global specifier `::` at the beginning. No stored value.
  116. break;
  117. case NestedNameSpecifier::Super:
  118. // Microsoft's `__super` specifier.
  119. Fragments.append("__super", DeclarationFragments::FragmentKind::Keyword);
  120. break;
  121. case NestedNameSpecifier::TypeSpecWithTemplate:
  122. // A type prefixed by the `template` keyword.
  123. Fragments.append("template", DeclarationFragments::FragmentKind::Keyword);
  124. Fragments.appendSpace();
  125. // Fallthrough after adding the keyword to handle the actual type.
  126. [[fallthrough]];
  127. case NestedNameSpecifier::TypeSpec: {
  128. const Type *T = NNS->getAsType();
  129. // FIXME: Handle C++ template specialization type
  130. Fragments.append(getFragmentsForType(T, Context, After));
  131. break;
  132. }
  133. }
  134. // Add the separator text `::` for this segment.
  135. return Fragments.append("::", DeclarationFragments::FragmentKind::Text);
  136. }
  137. // Recursively build the declaration fragments for an underlying `Type` with
  138. // qualifiers removed.
  139. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
  140. const Type *T, ASTContext &Context, DeclarationFragments &After) {
  141. assert(T && "invalid type");
  142. DeclarationFragments Fragments;
  143. // Declaration fragments of a pointer type is the declaration fragments of
  144. // the pointee type followed by a `*`, except for Objective-C `id` and `Class`
  145. // pointers, where we do not spell out the `*`.
  146. if (T->isPointerType() ||
  147. (T->isObjCObjectPointerType() &&
  148. !T->getAs<ObjCObjectPointerType>()->isObjCIdOrClassType())) {
  149. return Fragments
  150. .append(getFragmentsForType(T->getPointeeType(), Context, After))
  151. .append(" *", DeclarationFragments::FragmentKind::Text);
  152. }
  153. // Declaration fragments of a lvalue reference type is the declaration
  154. // fragments of the underlying type followed by a `&`.
  155. if (const LValueReferenceType *LRT = dyn_cast<LValueReferenceType>(T))
  156. return Fragments
  157. .append(
  158. getFragmentsForType(LRT->getPointeeTypeAsWritten(), Context, After))
  159. .append(" &", DeclarationFragments::FragmentKind::Text);
  160. // Declaration fragments of a rvalue reference type is the declaration
  161. // fragments of the underlying type followed by a `&&`.
  162. if (const RValueReferenceType *RRT = dyn_cast<RValueReferenceType>(T))
  163. return Fragments
  164. .append(
  165. getFragmentsForType(RRT->getPointeeTypeAsWritten(), Context, After))
  166. .append(" &&", DeclarationFragments::FragmentKind::Text);
  167. // Declaration fragments of an array-typed variable have two parts:
  168. // 1. the element type of the array that appears before the variable name;
  169. // 2. array brackets `[(0-9)?]` that appear after the variable name.
  170. if (const ArrayType *AT = T->getAsArrayTypeUnsafe()) {
  171. // Build the "after" part first because the inner element type might also
  172. // be an array-type. For example `int matrix[3][4]` which has a type of
  173. // "(array 3 of (array 4 of ints))."
  174. // Push the array size part first to make sure they are in the right order.
  175. After.append("[", DeclarationFragments::FragmentKind::Text);
  176. switch (AT->getSizeModifier()) {
  177. case ArrayType::Normal:
  178. break;
  179. case ArrayType::Static:
  180. Fragments.append("static", DeclarationFragments::FragmentKind::Keyword);
  181. break;
  182. case ArrayType::Star:
  183. Fragments.append("*", DeclarationFragments::FragmentKind::Text);
  184. break;
  185. }
  186. if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
  187. // FIXME: right now this would evaluate any expressions/macros written in
  188. // the original source to concrete values. For example
  189. // `int nums[MAX]` -> `int nums[100]`
  190. // `char *str[5 + 1]` -> `char *str[6]`
  191. SmallString<128> Size;
  192. CAT->getSize().toStringUnsigned(Size);
  193. After.append(Size, DeclarationFragments::FragmentKind::NumberLiteral);
  194. }
  195. After.append("]", DeclarationFragments::FragmentKind::Text);
  196. return Fragments.append(
  197. getFragmentsForType(AT->getElementType(), Context, After));
  198. }
  199. // An ElaboratedType is a sugar for types that are referred to using an
  200. // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
  201. // qualified name, e.g., `N::M::type`, or both.
  202. if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) {
  203. ElaboratedTypeKeyword Keyword = ET->getKeyword();
  204. if (Keyword != ETK_None) {
  205. Fragments
  206. .append(ElaboratedType::getKeywordName(Keyword),
  207. DeclarationFragments::FragmentKind::Keyword)
  208. .appendSpace();
  209. }
  210. if (const NestedNameSpecifier *NNS = ET->getQualifier())
  211. Fragments.append(getFragmentsForNNS(NNS, Context, After));
  212. // After handling the elaborated keyword or qualified name, build
  213. // declaration fragments for the desugared underlying type.
  214. return Fragments.append(getFragmentsForType(ET->desugar(), Context, After));
  215. }
  216. // Everything we care about has been handled now, reduce to the canonical
  217. // unqualified base type.
  218. QualType Base = T->getCanonicalTypeUnqualified();
  219. // Render Objective-C `id`/`instancetype` as keywords.
  220. if (T->isObjCIdType())
  221. return Fragments.append(Base.getAsString(),
  222. DeclarationFragments::FragmentKind::Keyword);
  223. // If the type is a typedefed type, get the underlying TypedefNameDecl for a
  224. // direct reference to the typedef instead of the wrapped type.
  225. if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(T)) {
  226. const TypedefNameDecl *Decl = TypedefTy->getDecl();
  227. TypedefUnderlyingTypeResolver TypedefResolver(Context);
  228. std::string USR = TypedefResolver.getUSRForType(QualType(T, 0));
  229. return Fragments.append(
  230. Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier,
  231. USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0)));
  232. }
  233. // If the base type is a TagType (struct/interface/union/class/enum), let's
  234. // get the underlying Decl for better names and USRs.
  235. if (const TagType *TagTy = dyn_cast<TagType>(Base)) {
  236. const TagDecl *Decl = TagTy->getDecl();
  237. // Anonymous decl, skip this fragment.
  238. if (Decl->getName().empty())
  239. return Fragments;
  240. SmallString<128> TagUSR;
  241. clang::index::generateUSRForDecl(Decl, TagUSR);
  242. return Fragments.append(Decl->getName(),
  243. DeclarationFragments::FragmentKind::TypeIdentifier,
  244. TagUSR, Decl);
  245. }
  246. // If the base type is an ObjCInterfaceType, use the underlying
  247. // ObjCInterfaceDecl for the true USR.
  248. if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(Base)) {
  249. const auto *Decl = ObjCIT->getDecl();
  250. SmallString<128> USR;
  251. index::generateUSRForDecl(Decl, USR);
  252. return Fragments.append(Decl->getName(),
  253. DeclarationFragments::FragmentKind::TypeIdentifier,
  254. USR, Decl);
  255. }
  256. // Default fragment builder for other kinds of types (BuiltinType etc.)
  257. SmallString<128> USR;
  258. clang::index::generateUSRForType(Base, Context, USR);
  259. Fragments.append(Base.getAsString(),
  260. DeclarationFragments::FragmentKind::TypeIdentifier, USR);
  261. return Fragments;
  262. }
  263. DeclarationFragments
  264. DeclarationFragmentsBuilder::getFragmentsForQualifiers(const Qualifiers Quals) {
  265. DeclarationFragments Fragments;
  266. if (Quals.hasConst())
  267. Fragments.append("const", DeclarationFragments::FragmentKind::Keyword);
  268. if (Quals.hasVolatile())
  269. Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword);
  270. if (Quals.hasRestrict())
  271. Fragments.append("restrict", DeclarationFragments::FragmentKind::Keyword);
  272. return Fragments;
  273. }
  274. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
  275. const QualType QT, ASTContext &Context, DeclarationFragments &After) {
  276. assert(!QT.isNull() && "invalid type");
  277. if (const ParenType *PT = dyn_cast<ParenType>(QT)) {
  278. After.append(")", DeclarationFragments::FragmentKind::Text);
  279. return getFragmentsForType(PT->getInnerType(), Context, After)
  280. .append("(", DeclarationFragments::FragmentKind::Text);
  281. }
  282. const SplitQualType SQT = QT.split();
  283. DeclarationFragments QualsFragments = getFragmentsForQualifiers(SQT.Quals),
  284. TypeFragments =
  285. getFragmentsForType(SQT.Ty, Context, After);
  286. if (QualsFragments.getFragments().empty())
  287. return TypeFragments;
  288. // Use east qualifier for pointer types
  289. // For example:
  290. // ```
  291. // int * const
  292. // ^---- ^----
  293. // type qualifier
  294. // ^-----------------
  295. // const pointer to int
  296. // ```
  297. // should not be reconstructed as
  298. // ```
  299. // const int *
  300. // ^---- ^--
  301. // qualifier type
  302. // ^---------------- ^
  303. // pointer to const int
  304. // ```
  305. if (SQT.Ty->isAnyPointerType())
  306. return TypeFragments.appendSpace().append(std::move(QualsFragments));
  307. return QualsFragments.appendSpace().append(std::move(TypeFragments));
  308. }
  309. DeclarationFragments
  310. DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) {
  311. DeclarationFragments Fragments;
  312. StorageClass SC = Var->getStorageClass();
  313. if (SC != SC_None)
  314. Fragments
  315. .append(VarDecl::getStorageClassSpecifierString(SC),
  316. DeclarationFragments::FragmentKind::Keyword)
  317. .appendSpace();
  318. QualType T =
  319. Var->getTypeSourceInfo()
  320. ? Var->getTypeSourceInfo()->getType()
  321. : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
  322. // Capture potential fragments that needs to be placed after the variable name
  323. // ```
  324. // int nums[5];
  325. // char (*ptr_to_array)[6];
  326. // ```
  327. DeclarationFragments After;
  328. return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
  329. .appendSpace()
  330. .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier)
  331. .append(std::move(After));
  332. }
  333. DeclarationFragments
  334. DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
  335. DeclarationFragments Fragments, After;
  336. QualType T = Param->getTypeSourceInfo()
  337. ? Param->getTypeSourceInfo()->getType()
  338. : Param->getASTContext().getUnqualifiedObjCPointerType(
  339. Param->getType());
  340. DeclarationFragments TypeFragments =
  341. getFragmentsForType(T, Param->getASTContext(), After);
  342. if (Param->isObjCMethodParameter())
  343. Fragments.append("(", DeclarationFragments::FragmentKind::Text)
  344. .append(std::move(TypeFragments))
  345. .append(") ", DeclarationFragments::FragmentKind::Text);
  346. else
  347. Fragments.append(std::move(TypeFragments)).appendSpace();
  348. return Fragments
  349. .append(Param->getName(),
  350. DeclarationFragments::FragmentKind::InternalParam)
  351. .append(std::move(After));
  352. }
  353. DeclarationFragments
  354. DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) {
  355. DeclarationFragments Fragments;
  356. // FIXME: Handle template specialization
  357. switch (Func->getStorageClass()) {
  358. case SC_None:
  359. case SC_PrivateExtern:
  360. break;
  361. case SC_Extern:
  362. Fragments.append("extern", DeclarationFragments::FragmentKind::Keyword)
  363. .appendSpace();
  364. break;
  365. case SC_Static:
  366. Fragments.append("static", DeclarationFragments::FragmentKind::Keyword)
  367. .appendSpace();
  368. break;
  369. case SC_Auto:
  370. case SC_Register:
  371. llvm_unreachable("invalid for functions");
  372. }
  373. // FIXME: Handle C++ function specifiers: constexpr, consteval, explicit, etc.
  374. // FIXME: Is `after` actually needed here?
  375. DeclarationFragments After;
  376. Fragments
  377. .append(getFragmentsForType(Func->getReturnType(), Func->getASTContext(),
  378. After))
  379. .appendSpace()
  380. .append(Func->getName(), DeclarationFragments::FragmentKind::Identifier)
  381. .append(std::move(After));
  382. Fragments.append("(", DeclarationFragments::FragmentKind::Text);
  383. for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) {
  384. if (i)
  385. Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
  386. Fragments.append(getFragmentsForParam(Func->getParamDecl(i)));
  387. }
  388. Fragments.append(")", DeclarationFragments::FragmentKind::Text);
  389. // FIXME: Handle exception specifiers: throw, noexcept
  390. return Fragments;
  391. }
  392. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForEnumConstant(
  393. const EnumConstantDecl *EnumConstDecl) {
  394. DeclarationFragments Fragments;
  395. return Fragments.append(EnumConstDecl->getName(),
  396. DeclarationFragments::FragmentKind::Identifier);
  397. }
  398. DeclarationFragments
  399. DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) {
  400. if (const auto *TypedefNameDecl = EnumDecl->getTypedefNameForAnonDecl())
  401. return getFragmentsForTypedef(TypedefNameDecl);
  402. DeclarationFragments Fragments, After;
  403. Fragments.append("enum", DeclarationFragments::FragmentKind::Keyword);
  404. if (!EnumDecl->getName().empty())
  405. Fragments.appendSpace().append(
  406. EnumDecl->getName(), DeclarationFragments::FragmentKind::Identifier);
  407. QualType IntegerType = EnumDecl->getIntegerType();
  408. if (!IntegerType.isNull())
  409. Fragments.append(": ", DeclarationFragments::FragmentKind::Text)
  410. .append(
  411. getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After))
  412. .append(std::move(After));
  413. return Fragments;
  414. }
  415. DeclarationFragments
  416. DeclarationFragmentsBuilder::getFragmentsForField(const FieldDecl *Field) {
  417. DeclarationFragments After;
  418. return getFragmentsForType(Field->getType(), Field->getASTContext(), After)
  419. .appendSpace()
  420. .append(Field->getName(), DeclarationFragments::FragmentKind::Identifier)
  421. .append(std::move(After));
  422. }
  423. DeclarationFragments
  424. DeclarationFragmentsBuilder::getFragmentsForStruct(const RecordDecl *Record) {
  425. if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
  426. return getFragmentsForTypedef(TypedefNameDecl);
  427. DeclarationFragments Fragments;
  428. Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword);
  429. if (!Record->getName().empty())
  430. Fragments.appendSpace().append(
  431. Record->getName(), DeclarationFragments::FragmentKind::Identifier);
  432. return Fragments;
  433. }
  434. DeclarationFragments
  435. DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name,
  436. const MacroDirective *MD) {
  437. DeclarationFragments Fragments;
  438. Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword)
  439. .appendSpace();
  440. Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
  441. auto *MI = MD->getMacroInfo();
  442. if (MI->isFunctionLike()) {
  443. Fragments.append("(", DeclarationFragments::FragmentKind::Text);
  444. unsigned numParameters = MI->getNumParams();
  445. if (MI->isC99Varargs())
  446. --numParameters;
  447. for (unsigned i = 0; i < numParameters; ++i) {
  448. if (i)
  449. Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
  450. Fragments.append(MI->params()[i]->getName(),
  451. DeclarationFragments::FragmentKind::InternalParam);
  452. }
  453. if (MI->isVariadic()) {
  454. if (numParameters && MI->isC99Varargs())
  455. Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
  456. Fragments.append("...", DeclarationFragments::FragmentKind::Text);
  457. }
  458. Fragments.append(")", DeclarationFragments::FragmentKind::Text);
  459. }
  460. return Fragments;
  461. }
  462. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory(
  463. const ObjCCategoryDecl *Category) {
  464. DeclarationFragments Fragments;
  465. auto *Interface = Category->getClassInterface();
  466. SmallString<128> InterfaceUSR;
  467. index::generateUSRForDecl(Interface, InterfaceUSR);
  468. Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword)
  469. .appendSpace()
  470. .append(Category->getClassInterface()->getName(),
  471. DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR,
  472. Interface)
  473. .append(" (", DeclarationFragments::FragmentKind::Text)
  474. .append(Category->getName(),
  475. DeclarationFragments::FragmentKind::Identifier)
  476. .append(")", DeclarationFragments::FragmentKind::Text);
  477. return Fragments;
  478. }
  479. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCInterface(
  480. const ObjCInterfaceDecl *Interface) {
  481. DeclarationFragments Fragments;
  482. // Build the base of the Objective-C interface declaration.
  483. Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword)
  484. .appendSpace()
  485. .append(Interface->getName(),
  486. DeclarationFragments::FragmentKind::Identifier);
  487. // Build the inheritance part of the declaration.
  488. if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) {
  489. SmallString<128> SuperUSR;
  490. index::generateUSRForDecl(SuperClass, SuperUSR);
  491. Fragments.append(" : ", DeclarationFragments::FragmentKind::Text)
  492. .append(SuperClass->getName(),
  493. DeclarationFragments::FragmentKind::TypeIdentifier, SuperUSR,
  494. SuperClass);
  495. }
  496. return Fragments;
  497. }
  498. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod(
  499. const ObjCMethodDecl *Method) {
  500. DeclarationFragments Fragments, After;
  501. // Build the instance/class method indicator.
  502. if (Method->isClassMethod())
  503. Fragments.append("+ ", DeclarationFragments::FragmentKind::Text);
  504. else if (Method->isInstanceMethod())
  505. Fragments.append("- ", DeclarationFragments::FragmentKind::Text);
  506. // Build the return type.
  507. Fragments.append("(", DeclarationFragments::FragmentKind::Text)
  508. .append(getFragmentsForType(Method->getReturnType(),
  509. Method->getASTContext(), After))
  510. .append(std::move(After))
  511. .append(")", DeclarationFragments::FragmentKind::Text);
  512. // Build the selector part.
  513. Selector Selector = Method->getSelector();
  514. if (Selector.getNumArgs() == 0)
  515. // For Objective-C methods that don't take arguments, the first (and only)
  516. // slot of the selector is the method name.
  517. Fragments.appendSpace().append(
  518. Selector.getNameForSlot(0),
  519. DeclarationFragments::FragmentKind::Identifier);
  520. // For Objective-C methods that take arguments, build the selector slots.
  521. for (unsigned i = 0, end = Method->param_size(); i != end; ++i) {
  522. // Objective-C method selector parts are considered as identifiers instead
  523. // of "external parameters" as in Swift. This is because Objective-C method
  524. // symbols are referenced with the entire selector, instead of just the
  525. // method name in Swift.
  526. SmallString<32> ParamID(Selector.getNameForSlot(i));
  527. ParamID.append(":");
  528. Fragments.appendSpace().append(
  529. ParamID, DeclarationFragments::FragmentKind::Identifier);
  530. // Build the internal parameter.
  531. const ParmVarDecl *Param = Method->getParamDecl(i);
  532. Fragments.append(getFragmentsForParam(Param));
  533. }
  534. return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
  535. }
  536. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty(
  537. const ObjCPropertyDecl *Property) {
  538. DeclarationFragments Fragments, After;
  539. // Build the Objective-C property keyword.
  540. Fragments.append("@property", DeclarationFragments::FragmentKind::Keyword);
  541. const auto Attributes = Property->getPropertyAttributes();
  542. // Build the attributes if there is any associated with the property.
  543. if (Attributes != ObjCPropertyAttribute::kind_noattr) {
  544. // No leading comma for the first attribute.
  545. bool First = true;
  546. Fragments.append(" (", DeclarationFragments::FragmentKind::Text);
  547. // Helper function to render the attribute.
  548. auto RenderAttribute =
  549. [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling,
  550. StringRef Arg = "",
  551. DeclarationFragments::FragmentKind ArgKind =
  552. DeclarationFragments::FragmentKind::Identifier) {
  553. // Check if the `Kind` attribute is set for this property.
  554. if ((Attributes & Kind) && !Spelling.empty()) {
  555. // Add a leading comma if this is not the first attribute rendered.
  556. if (!First)
  557. Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
  558. // Render the spelling of this attribute `Kind` as a keyword.
  559. Fragments.append(Spelling,
  560. DeclarationFragments::FragmentKind::Keyword);
  561. // If this attribute takes in arguments (e.g. `getter=getterName`),
  562. // render the arguments.
  563. if (!Arg.empty())
  564. Fragments.append("=", DeclarationFragments::FragmentKind::Text)
  565. .append(Arg, ArgKind);
  566. First = false;
  567. }
  568. };
  569. // Go through all possible Objective-C property attributes and render set
  570. // ones.
  571. RenderAttribute(ObjCPropertyAttribute::kind_class, "class");
  572. RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct");
  573. RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic");
  574. RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic");
  575. RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign");
  576. RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain");
  577. RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong");
  578. RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy");
  579. RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak");
  580. RenderAttribute(ObjCPropertyAttribute::kind_unsafe_unretained,
  581. "unsafe_unretained");
  582. RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite");
  583. RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly");
  584. RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter",
  585. Property->getGetterName().getAsString());
  586. RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter",
  587. Property->getSetterName().getAsString());
  588. // Render nullability attributes.
  589. if (Attributes & ObjCPropertyAttribute::kind_nullability) {
  590. QualType Type = Property->getType();
  591. if (const auto Nullability =
  592. AttributedType::stripOuterNullability(Type)) {
  593. if (!First)
  594. Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
  595. if (*Nullability == NullabilityKind::Unspecified &&
  596. (Attributes & ObjCPropertyAttribute::kind_null_resettable))
  597. Fragments.append("null_resettable",
  598. DeclarationFragments::FragmentKind::Keyword);
  599. else
  600. Fragments.append(
  601. getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true),
  602. DeclarationFragments::FragmentKind::Keyword);
  603. First = false;
  604. }
  605. }
  606. Fragments.append(")", DeclarationFragments::FragmentKind::Text);
  607. }
  608. // Build the property type and name, and return the completed fragments.
  609. return Fragments.appendSpace()
  610. .append(getFragmentsForType(Property->getType(),
  611. Property->getASTContext(), After))
  612. .appendSpace()
  613. .append(Property->getName(),
  614. DeclarationFragments::FragmentKind::Identifier)
  615. .append(std::move(After));
  616. }
  617. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(
  618. const ObjCProtocolDecl *Protocol) {
  619. DeclarationFragments Fragments;
  620. // Build basic protocol declaration.
  621. Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword)
  622. .appendSpace()
  623. .append(Protocol->getName(),
  624. DeclarationFragments::FragmentKind::Identifier);
  625. // If this protocol conforms to other protocols, build the conformance list.
  626. if (!Protocol->protocols().empty()) {
  627. Fragments.append(" <", DeclarationFragments::FragmentKind::Text);
  628. for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin();
  629. It != Protocol->protocol_end(); It++) {
  630. // Add a leading comma if this is not the first protocol rendered.
  631. if (It != Protocol->protocol_begin())
  632. Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
  633. SmallString<128> USR;
  634. index::generateUSRForDecl(*It, USR);
  635. Fragments.append((*It)->getName(),
  636. DeclarationFragments::FragmentKind::TypeIdentifier, USR,
  637. *It);
  638. }
  639. Fragments.append(">", DeclarationFragments::FragmentKind::Text);
  640. }
  641. return Fragments;
  642. }
  643. DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef(
  644. const TypedefNameDecl *Decl) {
  645. DeclarationFragments Fragments, After;
  646. Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword)
  647. .appendSpace()
  648. .append(getFragmentsForType(Decl->getUnderlyingType(),
  649. Decl->getASTContext(), After))
  650. .append(std::move(After))
  651. .appendSpace()
  652. .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier);
  653. return Fragments;
  654. }
  655. template <typename FunctionT>
  656. FunctionSignature
  657. DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
  658. FunctionSignature Signature;
  659. DeclarationFragments ReturnType, After;
  660. ReturnType
  661. .append(getFragmentsForType(Function->getReturnType(),
  662. Function->getASTContext(), After))
  663. .append(std::move(After));
  664. Signature.setReturnType(ReturnType);
  665. for (const auto *Param : Function->parameters())
  666. Signature.addParameter(Param->getName(), getFragmentsForParam(Param));
  667. return Signature;
  668. }
  669. // Instantiate template for FunctionDecl.
  670. template FunctionSignature
  671. DeclarationFragmentsBuilder::getFunctionSignature(const FunctionDecl *);
  672. // Instantiate template for ObjCMethodDecl.
  673. template FunctionSignature
  674. DeclarationFragmentsBuilder::getFunctionSignature(const ObjCMethodDecl *);
  675. // Subheading of a symbol defaults to its name.
  676. DeclarationFragments
  677. DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) {
  678. DeclarationFragments Fragments;
  679. if (!Decl->getName().empty())
  680. Fragments.append(Decl->getName(),
  681. DeclarationFragments::FragmentKind::Identifier);
  682. return Fragments;
  683. }
  684. // Subheading of an Objective-C method is a `+` or `-` sign indicating whether
  685. // it's a class method or an instance method, followed by the selector name.
  686. DeclarationFragments
  687. DeclarationFragmentsBuilder::getSubHeading(const ObjCMethodDecl *Method) {
  688. DeclarationFragments Fragments;
  689. if (Method->isClassMethod())
  690. Fragments.append("+ ", DeclarationFragments::FragmentKind::Text);
  691. else if (Method->isInstanceMethod())
  692. Fragments.append("- ", DeclarationFragments::FragmentKind::Text);
  693. return Fragments.append(Method->getNameAsString(),
  694. DeclarationFragments::FragmentKind::Identifier);
  695. }
  696. // Subheading of a symbol defaults to its name.
  697. DeclarationFragments
  698. DeclarationFragmentsBuilder::getSubHeadingForMacro(StringRef Name) {
  699. DeclarationFragments Fragments;
  700. Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
  701. return Fragments;
  702. }