xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Index/IndexSymbol.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- IndexSymbol.cpp - Types and functions for indexing symbols -------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg 
97330f729Sjoerg #include "clang/Index/IndexSymbol.h"
10*e038c9c4Sjoerg #include "clang/AST/Attr.h"
117330f729Sjoerg #include "clang/AST/DeclCXX.h"
127330f729Sjoerg #include "clang/AST/DeclObjC.h"
137330f729Sjoerg #include "clang/AST/DeclTemplate.h"
147330f729Sjoerg #include "clang/AST/PrettyPrinter.h"
157330f729Sjoerg #include "clang/Lex/MacroInfo.h"
167330f729Sjoerg 
177330f729Sjoerg using namespace clang;
187330f729Sjoerg using namespace clang::index;
197330f729Sjoerg 
207330f729Sjoerg /// \returns true if \c D is a subclass of 'XCTestCase'.
isUnitTestCase(const ObjCInterfaceDecl * D)217330f729Sjoerg static bool isUnitTestCase(const ObjCInterfaceDecl *D) {
227330f729Sjoerg   if (!D)
237330f729Sjoerg     return false;
247330f729Sjoerg   while (const ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
257330f729Sjoerg     if (SuperD->getName() == "XCTestCase")
267330f729Sjoerg       return true;
277330f729Sjoerg     D = SuperD;
287330f729Sjoerg   }
297330f729Sjoerg   return false;
307330f729Sjoerg }
317330f729Sjoerg 
327330f729Sjoerg /// \returns true if \c D is in a subclass of 'XCTestCase', returns void, has
337330f729Sjoerg /// no parameters, and its name starts with 'test'.
isUnitTest(const ObjCMethodDecl * D)347330f729Sjoerg static bool isUnitTest(const ObjCMethodDecl *D) {
357330f729Sjoerg   if (!D->parameters().empty())
367330f729Sjoerg     return false;
377330f729Sjoerg   if (!D->getReturnType()->isVoidType())
387330f729Sjoerg     return false;
397330f729Sjoerg   if (!D->getSelector().getNameForSlot(0).startswith("test"))
407330f729Sjoerg     return false;
417330f729Sjoerg   return isUnitTestCase(D->getClassInterface());
427330f729Sjoerg }
437330f729Sjoerg 
checkForIBOutlets(const Decl * D,SymbolPropertySet & PropSet)447330f729Sjoerg static void checkForIBOutlets(const Decl *D, SymbolPropertySet &PropSet) {
457330f729Sjoerg   if (D->hasAttr<IBOutletAttr>()) {
467330f729Sjoerg     PropSet |= (SymbolPropertySet)SymbolProperty::IBAnnotated;
477330f729Sjoerg   } else if (D->hasAttr<IBOutletCollectionAttr>()) {
487330f729Sjoerg     PropSet |= (SymbolPropertySet)SymbolProperty::IBAnnotated;
497330f729Sjoerg     PropSet |= (SymbolPropertySet)SymbolProperty::IBOutletCollection;
507330f729Sjoerg   }
517330f729Sjoerg }
527330f729Sjoerg 
isFunctionLocalSymbol(const Decl * D)537330f729Sjoerg bool index::isFunctionLocalSymbol(const Decl *D) {
547330f729Sjoerg   assert(D);
557330f729Sjoerg 
567330f729Sjoerg   if (isa<ParmVarDecl>(D))
577330f729Sjoerg     return true;
587330f729Sjoerg 
597330f729Sjoerg   if (isa<ObjCTypeParamDecl>(D))
607330f729Sjoerg     return true;
617330f729Sjoerg 
627330f729Sjoerg   if (isa<UsingDirectiveDecl>(D))
637330f729Sjoerg     return false;
647330f729Sjoerg   if (!D->getParentFunctionOrMethod())
657330f729Sjoerg     return false;
667330f729Sjoerg 
677330f729Sjoerg   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
687330f729Sjoerg     switch (ND->getFormalLinkage()) {
697330f729Sjoerg       case NoLinkage:
707330f729Sjoerg       case InternalLinkage:
717330f729Sjoerg         return true;
727330f729Sjoerg       case VisibleNoLinkage:
737330f729Sjoerg       case UniqueExternalLinkage:
747330f729Sjoerg       case ModuleInternalLinkage:
757330f729Sjoerg         llvm_unreachable("Not a sema linkage");
767330f729Sjoerg       case ModuleLinkage:
777330f729Sjoerg       case ExternalLinkage:
787330f729Sjoerg         return false;
797330f729Sjoerg     }
807330f729Sjoerg   }
817330f729Sjoerg 
827330f729Sjoerg   return true;
837330f729Sjoerg }
847330f729Sjoerg 
getSymbolInfo(const Decl * D)857330f729Sjoerg SymbolInfo index::getSymbolInfo(const Decl *D) {
867330f729Sjoerg   assert(D);
877330f729Sjoerg   SymbolInfo Info;
887330f729Sjoerg   Info.Kind = SymbolKind::Unknown;
897330f729Sjoerg   Info.SubKind = SymbolSubKind::None;
907330f729Sjoerg   Info.Properties = SymbolPropertySet();
917330f729Sjoerg   Info.Lang = SymbolLanguage::C;
927330f729Sjoerg 
937330f729Sjoerg   if (isFunctionLocalSymbol(D)) {
947330f729Sjoerg     Info.Properties |= (SymbolPropertySet)SymbolProperty::Local;
957330f729Sjoerg   }
967330f729Sjoerg   if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
977330f729Sjoerg     Info.Properties |= (SymbolPropertySet)SymbolProperty::ProtocolInterface;
987330f729Sjoerg   }
997330f729Sjoerg 
1007330f729Sjoerg   if (auto *VT = dyn_cast<VarTemplateDecl>(D)) {
1017330f729Sjoerg     Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1027330f729Sjoerg     Info.Lang = SymbolLanguage::CXX;
1037330f729Sjoerg     // All other fields are filled from the templated decl.
1047330f729Sjoerg     D = VT->getTemplatedDecl();
1057330f729Sjoerg   }
1067330f729Sjoerg 
1077330f729Sjoerg   if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
1087330f729Sjoerg     switch (TD->getTagKind()) {
1097330f729Sjoerg     case TTK_Struct:
1107330f729Sjoerg       Info.Kind = SymbolKind::Struct; break;
1117330f729Sjoerg     case TTK_Union:
1127330f729Sjoerg       Info.Kind = SymbolKind::Union; break;
1137330f729Sjoerg     case TTK_Class:
1147330f729Sjoerg       Info.Kind = SymbolKind::Class;
1157330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
1167330f729Sjoerg       break;
1177330f729Sjoerg     case TTK_Interface:
1187330f729Sjoerg       Info.Kind = SymbolKind::Protocol;
1197330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
1207330f729Sjoerg       break;
1217330f729Sjoerg     case TTK_Enum:
1227330f729Sjoerg       Info.Kind = SymbolKind::Enum; break;
1237330f729Sjoerg     }
1247330f729Sjoerg 
1257330f729Sjoerg     if (const CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(D)) {
1267330f729Sjoerg       if (!CXXRec->isCLike()) {
1277330f729Sjoerg         Info.Lang = SymbolLanguage::CXX;
1287330f729Sjoerg         if (CXXRec->getDescribedClassTemplate()) {
1297330f729Sjoerg           Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1307330f729Sjoerg         }
1317330f729Sjoerg       }
1327330f729Sjoerg     }
1337330f729Sjoerg 
1347330f729Sjoerg     if (isa<ClassTemplatePartialSpecializationDecl>(D)) {
1357330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1367330f729Sjoerg       Info.Properties |=
1377330f729Sjoerg           (SymbolPropertySet)SymbolProperty::TemplatePartialSpecialization;
1387330f729Sjoerg     } else if (isa<ClassTemplateSpecializationDecl>(D)) {
1397330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1407330f729Sjoerg       Info.Properties |=
1417330f729Sjoerg           (SymbolPropertySet)SymbolProperty::TemplateSpecialization;
1427330f729Sjoerg     }
1437330f729Sjoerg 
1447330f729Sjoerg   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
1457330f729Sjoerg     Info.Kind = SymbolKind::Variable;
1467330f729Sjoerg     if (isa<ParmVarDecl>(D)) {
1477330f729Sjoerg       Info.Kind = SymbolKind::Parameter;
1487330f729Sjoerg     } else if (isa<CXXRecordDecl>(D->getDeclContext())) {
1497330f729Sjoerg       Info.Kind = SymbolKind::StaticProperty;
1507330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
1517330f729Sjoerg     }
1527330f729Sjoerg 
1537330f729Sjoerg     if (isa<VarTemplatePartialSpecializationDecl>(D)) {
1547330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
1557330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1567330f729Sjoerg       Info.Properties |=
1577330f729Sjoerg           (SymbolPropertySet)SymbolProperty::TemplatePartialSpecialization;
1587330f729Sjoerg     } else if (isa<VarTemplateSpecializationDecl>(D)) {
1597330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
1607330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1617330f729Sjoerg       Info.Properties |=
1627330f729Sjoerg           (SymbolPropertySet)SymbolProperty::TemplateSpecialization;
1637330f729Sjoerg     } else if (VD->getDescribedVarTemplate()) {
1647330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
1657330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
1667330f729Sjoerg     }
1677330f729Sjoerg 
1687330f729Sjoerg   } else {
1697330f729Sjoerg     switch (D->getKind()) {
1707330f729Sjoerg     case Decl::Import:
1717330f729Sjoerg       Info.Kind = SymbolKind::Module;
1727330f729Sjoerg       break;
1737330f729Sjoerg     case Decl::Typedef:
1747330f729Sjoerg       Info.Kind = SymbolKind::TypeAlias; break; // Lang = C
1757330f729Sjoerg     case Decl::Function:
1767330f729Sjoerg       Info.Kind = SymbolKind::Function;
1777330f729Sjoerg       break;
1787330f729Sjoerg     case Decl::Field:
1797330f729Sjoerg     case Decl::IndirectField:
1807330f729Sjoerg       Info.Kind = SymbolKind::Field;
1817330f729Sjoerg       if (const CXXRecordDecl *
1827330f729Sjoerg             CXXRec = dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
1837330f729Sjoerg         if (!CXXRec->isCLike())
1847330f729Sjoerg           Info.Lang = SymbolLanguage::CXX;
1857330f729Sjoerg       }
1867330f729Sjoerg       break;
1877330f729Sjoerg     case Decl::EnumConstant:
1887330f729Sjoerg       Info.Kind = SymbolKind::EnumConstant; break;
1897330f729Sjoerg     case Decl::ObjCInterface:
1907330f729Sjoerg     case Decl::ObjCImplementation: {
1917330f729Sjoerg       Info.Kind = SymbolKind::Class;
1927330f729Sjoerg       Info.Lang = SymbolLanguage::ObjC;
1937330f729Sjoerg       const ObjCInterfaceDecl *ClsD = dyn_cast<ObjCInterfaceDecl>(D);
1947330f729Sjoerg       if (!ClsD)
1957330f729Sjoerg         ClsD = cast<ObjCImplementationDecl>(D)->getClassInterface();
1967330f729Sjoerg       if (isUnitTestCase(ClsD))
1977330f729Sjoerg         Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest;
1987330f729Sjoerg       break;
1997330f729Sjoerg     }
2007330f729Sjoerg     case Decl::ObjCProtocol:
2017330f729Sjoerg       Info.Kind = SymbolKind::Protocol;
2027330f729Sjoerg       Info.Lang = SymbolLanguage::ObjC;
2037330f729Sjoerg       break;
2047330f729Sjoerg     case Decl::ObjCCategory:
2057330f729Sjoerg     case Decl::ObjCCategoryImpl: {
2067330f729Sjoerg       Info.Kind = SymbolKind::Extension;
2077330f729Sjoerg       Info.Lang = SymbolLanguage::ObjC;
2087330f729Sjoerg       const ObjCInterfaceDecl *ClsD = nullptr;
2097330f729Sjoerg       if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))
2107330f729Sjoerg         ClsD = CatD->getClassInterface();
2117330f729Sjoerg       else
2127330f729Sjoerg         ClsD = cast<ObjCCategoryImplDecl>(D)->getClassInterface();
2137330f729Sjoerg       if (isUnitTestCase(ClsD))
2147330f729Sjoerg         Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest;
2157330f729Sjoerg       break;
2167330f729Sjoerg     }
2177330f729Sjoerg     case Decl::ObjCMethod: {
2187330f729Sjoerg       const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
2197330f729Sjoerg       Info.Kind = MD->isInstanceMethod() ? SymbolKind::InstanceMethod : SymbolKind::ClassMethod;
2207330f729Sjoerg       if (MD->isPropertyAccessor()) {
2217330f729Sjoerg         if (MD->param_size())
2227330f729Sjoerg           Info.SubKind = SymbolSubKind::AccessorSetter;
2237330f729Sjoerg         else
2247330f729Sjoerg           Info.SubKind = SymbolSubKind::AccessorGetter;
2257330f729Sjoerg       }
2267330f729Sjoerg       Info.Lang = SymbolLanguage::ObjC;
2277330f729Sjoerg       if (isUnitTest(MD))
2287330f729Sjoerg         Info.Properties |= (SymbolPropertySet)SymbolProperty::UnitTest;
2297330f729Sjoerg       if (D->hasAttr<IBActionAttr>())
2307330f729Sjoerg         Info.Properties |= (SymbolPropertySet)SymbolProperty::IBAnnotated;
2317330f729Sjoerg       break;
2327330f729Sjoerg     }
2337330f729Sjoerg     case Decl::ObjCProperty:
2347330f729Sjoerg       Info.Kind = SymbolKind::InstanceProperty;
2357330f729Sjoerg       Info.Lang = SymbolLanguage::ObjC;
2367330f729Sjoerg       checkForIBOutlets(D, Info.Properties);
2377330f729Sjoerg       if (auto *Annot = D->getAttr<AnnotateAttr>()) {
2387330f729Sjoerg         if (Annot->getAnnotation() == "gk_inspectable")
2397330f729Sjoerg           Info.Properties |= (SymbolPropertySet)SymbolProperty::GKInspectable;
2407330f729Sjoerg       }
2417330f729Sjoerg       break;
2427330f729Sjoerg     case Decl::ObjCIvar:
2437330f729Sjoerg       Info.Kind = SymbolKind::Field;
2447330f729Sjoerg       Info.Lang = SymbolLanguage::ObjC;
2457330f729Sjoerg       checkForIBOutlets(D, Info.Properties);
2467330f729Sjoerg       break;
2477330f729Sjoerg     case Decl::Namespace:
2487330f729Sjoerg       Info.Kind = SymbolKind::Namespace;
2497330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2507330f729Sjoerg       break;
2517330f729Sjoerg     case Decl::NamespaceAlias:
2527330f729Sjoerg       Info.Kind = SymbolKind::NamespaceAlias;
2537330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2547330f729Sjoerg       break;
2557330f729Sjoerg     case Decl::CXXConstructor: {
2567330f729Sjoerg       Info.Kind = SymbolKind::Constructor;
2577330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2587330f729Sjoerg       auto *CD = cast<CXXConstructorDecl>(D);
2597330f729Sjoerg       if (CD->isCopyConstructor())
2607330f729Sjoerg         Info.SubKind = SymbolSubKind::CXXCopyConstructor;
2617330f729Sjoerg       else if (CD->isMoveConstructor())
2627330f729Sjoerg         Info.SubKind = SymbolSubKind::CXXMoveConstructor;
2637330f729Sjoerg       break;
2647330f729Sjoerg     }
2657330f729Sjoerg     case Decl::CXXDestructor:
2667330f729Sjoerg       Info.Kind = SymbolKind::Destructor;
2677330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2687330f729Sjoerg       break;
2697330f729Sjoerg     case Decl::CXXConversion:
2707330f729Sjoerg       Info.Kind = SymbolKind::ConversionFunction;
2717330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2727330f729Sjoerg       break;
2737330f729Sjoerg     case Decl::CXXMethod: {
2747330f729Sjoerg       const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
2757330f729Sjoerg       if (MD->isStatic())
2767330f729Sjoerg         Info.Kind = SymbolKind::StaticMethod;
2777330f729Sjoerg       else
2787330f729Sjoerg         Info.Kind = SymbolKind::InstanceMethod;
2797330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2807330f729Sjoerg       break;
2817330f729Sjoerg     }
2827330f729Sjoerg     case Decl::ClassTemplate:
2837330f729Sjoerg       Info.Kind = SymbolKind::Class;
2847330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
2857330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2867330f729Sjoerg       break;
2877330f729Sjoerg     case Decl::FunctionTemplate:
2887330f729Sjoerg       Info.Kind = SymbolKind::Function;
2897330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
2907330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
2917330f729Sjoerg       if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
2927330f729Sjoerg                            cast<FunctionTemplateDecl>(D)->getTemplatedDecl())) {
2937330f729Sjoerg         if (isa<CXXConstructorDecl>(MD))
2947330f729Sjoerg           Info.Kind = SymbolKind::Constructor;
2957330f729Sjoerg         else if (isa<CXXDestructorDecl>(MD))
2967330f729Sjoerg           Info.Kind = SymbolKind::Destructor;
2977330f729Sjoerg         else if (isa<CXXConversionDecl>(MD))
2987330f729Sjoerg           Info.Kind = SymbolKind::ConversionFunction;
2997330f729Sjoerg         else {
3007330f729Sjoerg           if (MD->isStatic())
3017330f729Sjoerg             Info.Kind = SymbolKind::StaticMethod;
3027330f729Sjoerg           else
3037330f729Sjoerg             Info.Kind = SymbolKind::InstanceMethod;
3047330f729Sjoerg         }
3057330f729Sjoerg       }
3067330f729Sjoerg       break;
3077330f729Sjoerg     case Decl::TypeAliasTemplate:
3087330f729Sjoerg       Info.Kind = SymbolKind::TypeAlias;
3097330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
3107330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3117330f729Sjoerg       break;
3127330f729Sjoerg     case Decl::TypeAlias:
3137330f729Sjoerg       Info.Kind = SymbolKind::TypeAlias;
3147330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
3157330f729Sjoerg       break;
3167330f729Sjoerg     case Decl::UnresolvedUsingTypename:
3177330f729Sjoerg       Info.Kind = SymbolKind::Using;
3187330f729Sjoerg       Info.SubKind = SymbolSubKind::UsingTypename;
3197330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
3207330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3217330f729Sjoerg       break;
3227330f729Sjoerg     case Decl::UnresolvedUsingValue:
3237330f729Sjoerg       Info.Kind = SymbolKind::Using;
3247330f729Sjoerg       Info.SubKind = SymbolSubKind::UsingValue;
3257330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
3267330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3277330f729Sjoerg       break;
3287330f729Sjoerg     case Decl::Using:
3297330f729Sjoerg       Info.Kind = SymbolKind::Using;
3307330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
3317330f729Sjoerg       break;
3327330f729Sjoerg     case Decl::Binding:
3337330f729Sjoerg       Info.Kind = SymbolKind::Variable;
3347330f729Sjoerg       Info.Lang = SymbolLanguage::CXX;
3357330f729Sjoerg       break;
3367330f729Sjoerg     case Decl::MSProperty:
3377330f729Sjoerg       Info.Kind = SymbolKind::InstanceProperty;
3387330f729Sjoerg       if (const CXXRecordDecl *CXXRec =
3397330f729Sjoerg               dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
3407330f729Sjoerg         if (!CXXRec->isCLike())
3417330f729Sjoerg           Info.Lang = SymbolLanguage::CXX;
3427330f729Sjoerg       }
3437330f729Sjoerg       break;
3447330f729Sjoerg     case Decl::ClassTemplatePartialSpecialization:
3457330f729Sjoerg     case Decl::ClassScopeFunctionSpecialization:
3467330f729Sjoerg     case Decl::ClassTemplateSpecialization:
3477330f729Sjoerg     case Decl::CXXRecord:
3487330f729Sjoerg     case Decl::Enum:
3497330f729Sjoerg     case Decl::Record:
3507330f729Sjoerg       llvm_unreachable("records handled before");
3517330f729Sjoerg       break;
3527330f729Sjoerg     case Decl::VarTemplateSpecialization:
3537330f729Sjoerg     case Decl::VarTemplatePartialSpecialization:
3547330f729Sjoerg     case Decl::ImplicitParam:
3557330f729Sjoerg     case Decl::ParmVar:
3567330f729Sjoerg     case Decl::Var:
3577330f729Sjoerg     case Decl::VarTemplate:
3587330f729Sjoerg       llvm_unreachable("variables handled before");
3597330f729Sjoerg       break;
360*e038c9c4Sjoerg     case Decl::TemplateTypeParm:
361*e038c9c4Sjoerg       Info.Kind = SymbolKind::TemplateTypeParm;
362*e038c9c4Sjoerg       break;
363*e038c9c4Sjoerg     case Decl::TemplateTemplateParm:
364*e038c9c4Sjoerg       Info.Kind = SymbolKind::TemplateTemplateParm;
365*e038c9c4Sjoerg       break;
366*e038c9c4Sjoerg     case Decl::NonTypeTemplateParm:
367*e038c9c4Sjoerg       Info.Kind = SymbolKind::NonTypeTemplateParm;
368*e038c9c4Sjoerg       break;
3697330f729Sjoerg     // Other decls get the 'unknown' kind.
3707330f729Sjoerg     default:
3717330f729Sjoerg       break;
3727330f729Sjoerg     }
3737330f729Sjoerg   }
3747330f729Sjoerg 
3757330f729Sjoerg   if (Info.Kind == SymbolKind::Unknown)
3767330f729Sjoerg     return Info;
3777330f729Sjoerg 
3787330f729Sjoerg   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3797330f729Sjoerg     if (FD->getTemplatedKind() ==
3807330f729Sjoerg           FunctionDecl::TK_FunctionTemplateSpecialization) {
3817330f729Sjoerg       Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
3827330f729Sjoerg       Info.Properties |=
3837330f729Sjoerg           (SymbolPropertySet)SymbolProperty::TemplateSpecialization;
3847330f729Sjoerg     }
3857330f729Sjoerg   }
3867330f729Sjoerg 
3877330f729Sjoerg   if (Info.Properties & (SymbolPropertySet)SymbolProperty::Generic)
3887330f729Sjoerg     Info.Lang = SymbolLanguage::CXX;
3897330f729Sjoerg 
3907330f729Sjoerg   if (auto *attr = D->getExternalSourceSymbolAttr()) {
3917330f729Sjoerg     if (attr->getLanguage() == "Swift")
3927330f729Sjoerg       Info.Lang = SymbolLanguage::Swift;
3937330f729Sjoerg   }
3947330f729Sjoerg 
3957330f729Sjoerg   return Info;
3967330f729Sjoerg }
3977330f729Sjoerg 
getSymbolInfoForMacro(const MacroInfo &)3987330f729Sjoerg SymbolInfo index::getSymbolInfoForMacro(const MacroInfo &) {
3997330f729Sjoerg   SymbolInfo Info;
4007330f729Sjoerg   Info.Kind = SymbolKind::Macro;
4017330f729Sjoerg   Info.SubKind = SymbolSubKind::None;
4027330f729Sjoerg   Info.Properties = SymbolPropertySet();
4037330f729Sjoerg   Info.Lang = SymbolLanguage::C;
4047330f729Sjoerg   return Info;
4057330f729Sjoerg }
4067330f729Sjoerg 
applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,llvm::function_ref<bool (SymbolRole)> Fn)4077330f729Sjoerg bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
4087330f729Sjoerg                                    llvm::function_ref<bool(SymbolRole)> Fn) {
4097330f729Sjoerg #define APPLY_FOR_ROLE(Role) \
4107330f729Sjoerg   if (Roles & (unsigned)SymbolRole::Role) \
4117330f729Sjoerg     if (!Fn(SymbolRole::Role)) \
4127330f729Sjoerg       return false;
4137330f729Sjoerg 
4147330f729Sjoerg   APPLY_FOR_ROLE(Declaration);
4157330f729Sjoerg   APPLY_FOR_ROLE(Definition);
4167330f729Sjoerg   APPLY_FOR_ROLE(Reference);
4177330f729Sjoerg   APPLY_FOR_ROLE(Read);
4187330f729Sjoerg   APPLY_FOR_ROLE(Write);
4197330f729Sjoerg   APPLY_FOR_ROLE(Call);
4207330f729Sjoerg   APPLY_FOR_ROLE(Dynamic);
4217330f729Sjoerg   APPLY_FOR_ROLE(AddressOf);
4227330f729Sjoerg   APPLY_FOR_ROLE(Implicit);
4237330f729Sjoerg   APPLY_FOR_ROLE(Undefinition);
4247330f729Sjoerg   APPLY_FOR_ROLE(RelationChildOf);
4257330f729Sjoerg   APPLY_FOR_ROLE(RelationBaseOf);
4267330f729Sjoerg   APPLY_FOR_ROLE(RelationOverrideOf);
4277330f729Sjoerg   APPLY_FOR_ROLE(RelationReceivedBy);
4287330f729Sjoerg   APPLY_FOR_ROLE(RelationCalledBy);
4297330f729Sjoerg   APPLY_FOR_ROLE(RelationExtendedBy);
4307330f729Sjoerg   APPLY_FOR_ROLE(RelationAccessorOf);
4317330f729Sjoerg   APPLY_FOR_ROLE(RelationContainedBy);
4327330f729Sjoerg   APPLY_FOR_ROLE(RelationIBTypeOf);
4337330f729Sjoerg   APPLY_FOR_ROLE(RelationSpecializationOf);
4347330f729Sjoerg   APPLY_FOR_ROLE(NameReference);
4357330f729Sjoerg 
4367330f729Sjoerg #undef APPLY_FOR_ROLE
4377330f729Sjoerg 
4387330f729Sjoerg   return true;
4397330f729Sjoerg }
4407330f729Sjoerg 
applyForEachSymbolRole(SymbolRoleSet Roles,llvm::function_ref<void (SymbolRole)> Fn)4417330f729Sjoerg void index::applyForEachSymbolRole(SymbolRoleSet Roles,
4427330f729Sjoerg                                    llvm::function_ref<void(SymbolRole)> Fn) {
4437330f729Sjoerg   applyForEachSymbolRoleInterruptible(Roles, [&](SymbolRole r) -> bool {
4447330f729Sjoerg     Fn(r);
4457330f729Sjoerg     return true;
4467330f729Sjoerg   });
4477330f729Sjoerg }
4487330f729Sjoerg 
printSymbolRoles(SymbolRoleSet Roles,raw_ostream & OS)4497330f729Sjoerg void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
4507330f729Sjoerg   bool VisitedOnce = false;
4517330f729Sjoerg   applyForEachSymbolRole(Roles, [&](SymbolRole Role) {
4527330f729Sjoerg     if (VisitedOnce)
4537330f729Sjoerg       OS << ',';
4547330f729Sjoerg     else
4557330f729Sjoerg       VisitedOnce = true;
4567330f729Sjoerg     switch (Role) {
4577330f729Sjoerg     case SymbolRole::Declaration: OS << "Decl"; break;
4587330f729Sjoerg     case SymbolRole::Definition: OS << "Def"; break;
4597330f729Sjoerg     case SymbolRole::Reference: OS << "Ref"; break;
4607330f729Sjoerg     case SymbolRole::Read: OS << "Read"; break;
4617330f729Sjoerg     case SymbolRole::Write: OS << "Writ"; break;
4627330f729Sjoerg     case SymbolRole::Call: OS << "Call"; break;
4637330f729Sjoerg     case SymbolRole::Dynamic: OS << "Dyn"; break;
4647330f729Sjoerg     case SymbolRole::AddressOf: OS << "Addr"; break;
4657330f729Sjoerg     case SymbolRole::Implicit: OS << "Impl"; break;
4667330f729Sjoerg     case SymbolRole::Undefinition: OS << "Undef"; break;
4677330f729Sjoerg     case SymbolRole::RelationChildOf: OS << "RelChild"; break;
4687330f729Sjoerg     case SymbolRole::RelationBaseOf: OS << "RelBase"; break;
4697330f729Sjoerg     case SymbolRole::RelationOverrideOf: OS << "RelOver"; break;
4707330f729Sjoerg     case SymbolRole::RelationReceivedBy: OS << "RelRec"; break;
4717330f729Sjoerg     case SymbolRole::RelationCalledBy: OS << "RelCall"; break;
4727330f729Sjoerg     case SymbolRole::RelationExtendedBy: OS << "RelExt"; break;
4737330f729Sjoerg     case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
4747330f729Sjoerg     case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
4757330f729Sjoerg     case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
4767330f729Sjoerg     case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
4777330f729Sjoerg     case SymbolRole::NameReference: OS << "NameReference"; break;
4787330f729Sjoerg     }
4797330f729Sjoerg   });
4807330f729Sjoerg }
4817330f729Sjoerg 
printSymbolName(const Decl * D,const LangOptions & LO,raw_ostream & OS)4827330f729Sjoerg bool index::printSymbolName(const Decl *D, const LangOptions &LO,
4837330f729Sjoerg                             raw_ostream &OS) {
4847330f729Sjoerg   if (auto *ND = dyn_cast<NamedDecl>(D)) {
4857330f729Sjoerg     PrintingPolicy Policy(LO);
4867330f729Sjoerg     // Forward references can have different template argument names. Suppress
4877330f729Sjoerg     // the template argument names in constructors to make their name more
4887330f729Sjoerg     // stable.
4897330f729Sjoerg     Policy.SuppressTemplateArgsInCXXConstructors = true;
4907330f729Sjoerg     DeclarationName DeclName = ND->getDeclName();
4917330f729Sjoerg     if (DeclName.isEmpty())
4927330f729Sjoerg       return true;
4937330f729Sjoerg     DeclName.print(OS, Policy);
4947330f729Sjoerg     return false;
4957330f729Sjoerg   } else {
4967330f729Sjoerg     return true;
4977330f729Sjoerg   }
4987330f729Sjoerg }
4997330f729Sjoerg 
getSymbolKindString(SymbolKind K)5007330f729Sjoerg StringRef index::getSymbolKindString(SymbolKind K) {
5017330f729Sjoerg   switch (K) {
5027330f729Sjoerg   case SymbolKind::Unknown: return "<unknown>";
5037330f729Sjoerg   case SymbolKind::Module: return "module";
5047330f729Sjoerg   case SymbolKind::Namespace: return "namespace";
5057330f729Sjoerg   case SymbolKind::NamespaceAlias: return "namespace-alias";
5067330f729Sjoerg   case SymbolKind::Macro: return "macro";
5077330f729Sjoerg   case SymbolKind::Enum: return "enum";
5087330f729Sjoerg   case SymbolKind::Struct: return "struct";
5097330f729Sjoerg   case SymbolKind::Class: return "class";
5107330f729Sjoerg   case SymbolKind::Protocol: return "protocol";
5117330f729Sjoerg   case SymbolKind::Extension: return "extension";
5127330f729Sjoerg   case SymbolKind::Union: return "union";
5137330f729Sjoerg   case SymbolKind::TypeAlias: return "type-alias";
5147330f729Sjoerg   case SymbolKind::Function: return "function";
5157330f729Sjoerg   case SymbolKind::Variable: return "variable";
5167330f729Sjoerg   case SymbolKind::Field: return "field";
5177330f729Sjoerg   case SymbolKind::EnumConstant: return "enumerator";
5187330f729Sjoerg   case SymbolKind::InstanceMethod: return "instance-method";
5197330f729Sjoerg   case SymbolKind::ClassMethod: return "class-method";
5207330f729Sjoerg   case SymbolKind::StaticMethod: return "static-method";
5217330f729Sjoerg   case SymbolKind::InstanceProperty: return "instance-property";
5227330f729Sjoerg   case SymbolKind::ClassProperty: return "class-property";
5237330f729Sjoerg   case SymbolKind::StaticProperty: return "static-property";
5247330f729Sjoerg   case SymbolKind::Constructor: return "constructor";
5257330f729Sjoerg   case SymbolKind::Destructor: return "destructor";
5267330f729Sjoerg   case SymbolKind::ConversionFunction: return "conversion-func";
5277330f729Sjoerg   case SymbolKind::Parameter: return "param";
5287330f729Sjoerg   case SymbolKind::Using: return "using";
529*e038c9c4Sjoerg   case SymbolKind::TemplateTypeParm: return "template-type-param";
530*e038c9c4Sjoerg   case SymbolKind::TemplateTemplateParm: return "template-template-param";
531*e038c9c4Sjoerg   case SymbolKind::NonTypeTemplateParm: return "non-type-template-param";
5327330f729Sjoerg   }
5337330f729Sjoerg   llvm_unreachable("invalid symbol kind");
5347330f729Sjoerg }
5357330f729Sjoerg 
getSymbolSubKindString(SymbolSubKind K)5367330f729Sjoerg StringRef index::getSymbolSubKindString(SymbolSubKind K) {
5377330f729Sjoerg   switch (K) {
5387330f729Sjoerg   case SymbolSubKind::None: return "<none>";
5397330f729Sjoerg   case SymbolSubKind::CXXCopyConstructor: return "cxx-copy-ctor";
5407330f729Sjoerg   case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
5417330f729Sjoerg   case SymbolSubKind::AccessorGetter: return "acc-get";
5427330f729Sjoerg   case SymbolSubKind::AccessorSetter: return "acc-set";
5437330f729Sjoerg   case SymbolSubKind::UsingTypename: return "using-typename";
5447330f729Sjoerg   case SymbolSubKind::UsingValue: return "using-value";
5457330f729Sjoerg   }
5467330f729Sjoerg   llvm_unreachable("invalid symbol subkind");
5477330f729Sjoerg }
5487330f729Sjoerg 
getSymbolLanguageString(SymbolLanguage K)5497330f729Sjoerg StringRef index::getSymbolLanguageString(SymbolLanguage K) {
5507330f729Sjoerg   switch (K) {
5517330f729Sjoerg   case SymbolLanguage::C: return "C";
5527330f729Sjoerg   case SymbolLanguage::ObjC: return "ObjC";
5537330f729Sjoerg   case SymbolLanguage::CXX: return "C++";
5547330f729Sjoerg   case SymbolLanguage::Swift: return "Swift";
5557330f729Sjoerg   }
5567330f729Sjoerg   llvm_unreachable("invalid symbol language kind");
5577330f729Sjoerg }
5587330f729Sjoerg 
applyForEachSymbolProperty(SymbolPropertySet Props,llvm::function_ref<void (SymbolProperty)> Fn)5597330f729Sjoerg void index::applyForEachSymbolProperty(SymbolPropertySet Props,
5607330f729Sjoerg                                   llvm::function_ref<void(SymbolProperty)> Fn) {
5617330f729Sjoerg #define APPLY_FOR_PROPERTY(K)                                                  \
5627330f729Sjoerg   if (Props & (SymbolPropertySet)SymbolProperty::K)                            \
5637330f729Sjoerg   Fn(SymbolProperty::K)
5647330f729Sjoerg 
5657330f729Sjoerg   APPLY_FOR_PROPERTY(Generic);
5667330f729Sjoerg   APPLY_FOR_PROPERTY(TemplatePartialSpecialization);
5677330f729Sjoerg   APPLY_FOR_PROPERTY(TemplateSpecialization);
5687330f729Sjoerg   APPLY_FOR_PROPERTY(UnitTest);
5697330f729Sjoerg   APPLY_FOR_PROPERTY(IBAnnotated);
5707330f729Sjoerg   APPLY_FOR_PROPERTY(IBOutletCollection);
5717330f729Sjoerg   APPLY_FOR_PROPERTY(GKInspectable);
5727330f729Sjoerg   APPLY_FOR_PROPERTY(Local);
5737330f729Sjoerg   APPLY_FOR_PROPERTY(ProtocolInterface);
5747330f729Sjoerg 
5757330f729Sjoerg #undef APPLY_FOR_PROPERTY
5767330f729Sjoerg }
5777330f729Sjoerg 
printSymbolProperties(SymbolPropertySet Props,raw_ostream & OS)5787330f729Sjoerg void index::printSymbolProperties(SymbolPropertySet Props, raw_ostream &OS) {
5797330f729Sjoerg   bool VisitedOnce = false;
5807330f729Sjoerg   applyForEachSymbolProperty(Props, [&](SymbolProperty Prop) {
5817330f729Sjoerg     if (VisitedOnce)
5827330f729Sjoerg       OS << ',';
5837330f729Sjoerg     else
5847330f729Sjoerg       VisitedOnce = true;
5857330f729Sjoerg     switch (Prop) {
5867330f729Sjoerg     case SymbolProperty::Generic: OS << "Gen"; break;
5877330f729Sjoerg     case SymbolProperty::TemplatePartialSpecialization: OS << "TPS"; break;
5887330f729Sjoerg     case SymbolProperty::TemplateSpecialization: OS << "TS"; break;
5897330f729Sjoerg     case SymbolProperty::UnitTest: OS << "test"; break;
5907330f729Sjoerg     case SymbolProperty::IBAnnotated: OS << "IB"; break;
5917330f729Sjoerg     case SymbolProperty::IBOutletCollection: OS << "IBColl"; break;
5927330f729Sjoerg     case SymbolProperty::GKInspectable: OS << "GKI"; break;
5937330f729Sjoerg     case SymbolProperty::Local: OS << "local"; break;
5947330f729Sjoerg     case SymbolProperty::ProtocolInterface: OS << "protocol"; break;
5957330f729Sjoerg     }
5967330f729Sjoerg   });
5977330f729Sjoerg }
598