189f6b26fSZixu Wang //===- ExtractAPI/API.cpp ---------------------------------------*- 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 implements the APIRecord and derived record structs, 1189f6b26fSZixu Wang /// and the APISet class. 1289f6b26fSZixu Wang /// 1389f6b26fSZixu Wang //===----------------------------------------------------------------------===// 1489f6b26fSZixu Wang 1589f6b26fSZixu Wang #include "clang/ExtractAPI/API.h" 1689f6b26fSZixu Wang #include "clang/AST/CommentCommandTraits.h" 1789f6b26fSZixu Wang #include "clang/AST/CommentLexer.h" 1889f6b26fSZixu Wang #include "clang/AST/RawCommentList.h" 1989f6b26fSZixu Wang #include "clang/Index/USRGeneration.h" 200ee06c31SDaniel Grumberg #include <memory> 2189f6b26fSZixu Wang 2289f6b26fSZixu Wang using namespace clang::extractapi; 2389f6b26fSZixu Wang using namespace llvm; 2489f6b26fSZixu Wang 2589f6b26fSZixu Wang GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR, 2689f6b26fSZixu Wang PresumedLoc Loc, 2789f6b26fSZixu Wang const AvailabilityInfo &Availability, 2889f6b26fSZixu Wang LinkageInfo Linkage, const DocComment &Comment, 2989f6b26fSZixu Wang DeclarationFragments Fragments, 3089f6b26fSZixu Wang DeclarationFragments SubHeading, 3189f6b26fSZixu Wang FunctionSignature Signature) { 3289f6b26fSZixu Wang auto Result = Globals.insert({Name, nullptr}); 3389f6b26fSZixu Wang if (Result.second) { 3489f6b26fSZixu Wang // Create the record if it does not already exist. 350ee06c31SDaniel Grumberg auto Record = std::make_unique<GlobalRecord>( 3689f6b26fSZixu Wang Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments, 370ee06c31SDaniel Grumberg SubHeading, Signature); 3889f6b26fSZixu Wang Result.first->second = std::move(Record); 3989f6b26fSZixu Wang } 4089f6b26fSZixu Wang return Result.first->second.get(); 4189f6b26fSZixu Wang } 4289f6b26fSZixu Wang 4389f6b26fSZixu Wang GlobalRecord * 4489f6b26fSZixu Wang APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc, 4589f6b26fSZixu Wang const AvailabilityInfo &Availability, LinkageInfo Linkage, 4689f6b26fSZixu Wang const DocComment &Comment, DeclarationFragments Fragments, 4789f6b26fSZixu Wang DeclarationFragments SubHeading) { 4889f6b26fSZixu Wang return addGlobal(GVKind::Variable, Name, USR, Loc, Availability, Linkage, 4989f6b26fSZixu Wang Comment, Fragments, SubHeading, {}); 5089f6b26fSZixu Wang } 5189f6b26fSZixu Wang 5289f6b26fSZixu Wang GlobalRecord * 5389f6b26fSZixu Wang APISet::addFunction(StringRef Name, StringRef USR, PresumedLoc Loc, 5489f6b26fSZixu Wang const AvailabilityInfo &Availability, LinkageInfo Linkage, 5589f6b26fSZixu Wang const DocComment &Comment, DeclarationFragments Fragments, 5689f6b26fSZixu Wang DeclarationFragments SubHeading, 5789f6b26fSZixu Wang FunctionSignature Signature) { 5889f6b26fSZixu Wang return addGlobal(GVKind::Function, Name, USR, Loc, Availability, Linkage, 5989f6b26fSZixu Wang Comment, Fragments, SubHeading, Signature); 6089f6b26fSZixu Wang } 6189f6b26fSZixu Wang 6271b4c226SZixu Wang EnumConstantRecord *APISet::addEnumConstant( 6371b4c226SZixu Wang EnumRecord *Enum, StringRef Name, StringRef USR, PresumedLoc Loc, 6471b4c226SZixu Wang const AvailabilityInfo &Availability, const DocComment &Comment, 6571b4c226SZixu Wang DeclarationFragments Declaration, DeclarationFragments SubHeading) { 660ee06c31SDaniel Grumberg auto Record = std::make_unique<EnumConstantRecord>( 670ee06c31SDaniel Grumberg Name, USR, Loc, Availability, Comment, Declaration, SubHeading); 6871b4c226SZixu Wang return Enum->Constants.emplace_back(std::move(Record)).get(); 6971b4c226SZixu Wang } 7071b4c226SZixu Wang 7171b4c226SZixu Wang EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc, 7271b4c226SZixu Wang const AvailabilityInfo &Availability, 7371b4c226SZixu Wang const DocComment &Comment, 7471b4c226SZixu Wang DeclarationFragments Declaration, 7571b4c226SZixu Wang DeclarationFragments SubHeading) { 7671b4c226SZixu Wang auto Result = Enums.insert({Name, nullptr}); 7771b4c226SZixu Wang if (Result.second) { 7871b4c226SZixu Wang // Create the record if it does not already exist. 790ee06c31SDaniel Grumberg auto Record = std::make_unique<EnumRecord>( 800ee06c31SDaniel Grumberg Name, USR, Loc, Availability, Comment, Declaration, SubHeading); 8171b4c226SZixu Wang Result.first->second = std::move(Record); 8271b4c226SZixu Wang } 8371b4c226SZixu Wang return Result.first->second.get(); 8471b4c226SZixu Wang } 8571b4c226SZixu Wang 865bb5704cSZixu Wang StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name, 875bb5704cSZixu Wang StringRef USR, PresumedLoc Loc, 885bb5704cSZixu Wang const AvailabilityInfo &Availability, 895bb5704cSZixu Wang const DocComment &Comment, 905bb5704cSZixu Wang DeclarationFragments Declaration, 915bb5704cSZixu Wang DeclarationFragments SubHeading) { 920ee06c31SDaniel Grumberg auto Record = std::make_unique<StructFieldRecord>( 930ee06c31SDaniel Grumberg Name, USR, Loc, Availability, Comment, Declaration, SubHeading); 945bb5704cSZixu Wang return Struct->Fields.emplace_back(std::move(Record)).get(); 955bb5704cSZixu Wang } 965bb5704cSZixu Wang 975bb5704cSZixu Wang StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc, 985bb5704cSZixu Wang const AvailabilityInfo &Availability, 995bb5704cSZixu Wang const DocComment &Comment, 1005bb5704cSZixu Wang DeclarationFragments Declaration, 1015bb5704cSZixu Wang DeclarationFragments SubHeading) { 1025bb5704cSZixu Wang auto Result = Structs.insert({Name, nullptr}); 1035bb5704cSZixu Wang if (Result.second) { 1045bb5704cSZixu Wang // Create the record if it does not already exist. 1050ee06c31SDaniel Grumberg auto Record = std::make_unique<StructRecord>( 1060ee06c31SDaniel Grumberg Name, USR, Loc, Availability, Comment, Declaration, SubHeading); 1075bb5704cSZixu Wang Result.first->second = std::move(Record); 1085bb5704cSZixu Wang } 1095bb5704cSZixu Wang return Result.first->second.get(); 1105bb5704cSZixu Wang } 1115bb5704cSZixu Wang 1129b36e126SZixu Wang ObjCInterfaceRecord *APISet::addObjCInterface( 1139b36e126SZixu Wang StringRef Name, StringRef USR, PresumedLoc Loc, 1149b36e126SZixu Wang const AvailabilityInfo &Availability, LinkageInfo Linkage, 1159b36e126SZixu Wang const DocComment &Comment, DeclarationFragments Declaration, 1169b36e126SZixu Wang DeclarationFragments SubHeading, SymbolReference SuperClass) { 1179b36e126SZixu Wang auto Result = ObjCInterfaces.insert({Name, nullptr}); 1189b36e126SZixu Wang if (Result.second) { 1199b36e126SZixu Wang // Create the record if it does not already exist. 1209b36e126SZixu Wang auto Record = std::make_unique<ObjCInterfaceRecord>( 1219b36e126SZixu Wang Name, USR, Loc, Availability, Linkage, Comment, Declaration, SubHeading, 1229b36e126SZixu Wang SuperClass); 1239b36e126SZixu Wang Result.first->second = std::move(Record); 1249b36e126SZixu Wang } 1259b36e126SZixu Wang return Result.first->second.get(); 1269b36e126SZixu Wang } 1279b36e126SZixu Wang 1289b36e126SZixu Wang ObjCMethodRecord *APISet::addObjCMethod( 1299b36e126SZixu Wang ObjCContainerRecord *Container, StringRef Name, StringRef USR, 1309b36e126SZixu Wang PresumedLoc Loc, const AvailabilityInfo &Availability, 1319b36e126SZixu Wang const DocComment &Comment, DeclarationFragments Declaration, 1329b36e126SZixu Wang DeclarationFragments SubHeading, FunctionSignature Signature, 1339b36e126SZixu Wang bool IsInstanceMethod) { 1349b36e126SZixu Wang auto Record = std::make_unique<ObjCMethodRecord>( 1359b36e126SZixu Wang Name, USR, Loc, Availability, Comment, Declaration, SubHeading, Signature, 1369b36e126SZixu Wang IsInstanceMethod); 1379b36e126SZixu Wang return Container->Methods.emplace_back(std::move(Record)).get(); 1389b36e126SZixu Wang } 1399b36e126SZixu Wang 1409b36e126SZixu Wang ObjCPropertyRecord *APISet::addObjCProperty( 1419b36e126SZixu Wang ObjCContainerRecord *Container, StringRef Name, StringRef USR, 1429b36e126SZixu Wang PresumedLoc Loc, const AvailabilityInfo &Availability, 1439b36e126SZixu Wang const DocComment &Comment, DeclarationFragments Declaration, 1449b36e126SZixu Wang DeclarationFragments SubHeading, 1459b36e126SZixu Wang ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName, 1469b36e126SZixu Wang StringRef SetterName, bool IsOptional) { 1479b36e126SZixu Wang auto Record = std::make_unique<ObjCPropertyRecord>( 1489b36e126SZixu Wang Name, USR, Loc, Availability, Comment, Declaration, SubHeading, 1499b36e126SZixu Wang Attributes, GetterName, SetterName, IsOptional); 1509b36e126SZixu Wang return Container->Properties.emplace_back(std::move(Record)).get(); 1519b36e126SZixu Wang } 1529b36e126SZixu Wang 1539b36e126SZixu Wang ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable( 1549b36e126SZixu Wang ObjCContainerRecord *Container, StringRef Name, StringRef USR, 1559b36e126SZixu Wang PresumedLoc Loc, const AvailabilityInfo &Availability, 1569b36e126SZixu Wang const DocComment &Comment, DeclarationFragments Declaration, 1579b36e126SZixu Wang DeclarationFragments SubHeading, 1589b36e126SZixu Wang ObjCInstanceVariableRecord::AccessControl Access) { 1599b36e126SZixu Wang auto Record = std::make_unique<ObjCInstanceVariableRecord>( 1609b36e126SZixu Wang Name, USR, Loc, Availability, Comment, Declaration, SubHeading, Access); 1619b36e126SZixu Wang return Container->Ivars.emplace_back(std::move(Record)).get(); 1629b36e126SZixu Wang } 1639b36e126SZixu Wang 164*d1d34bafSZixu Wang ObjCProtocolRecord *APISet::addObjCProtocol( 165*d1d34bafSZixu Wang StringRef Name, StringRef USR, PresumedLoc Loc, 166*d1d34bafSZixu Wang const AvailabilityInfo &Availability, const DocComment &Comment, 167*d1d34bafSZixu Wang DeclarationFragments Declaration, DeclarationFragments SubHeading) { 168*d1d34bafSZixu Wang auto Result = ObjCProtocols.insert({Name, nullptr}); 169*d1d34bafSZixu Wang if (Result.second) { 170*d1d34bafSZixu Wang // Create the record if it does not already exist. 171*d1d34bafSZixu Wang auto Record = std::make_unique<ObjCProtocolRecord>( 172*d1d34bafSZixu Wang Name, USR, Loc, Availability, Comment, Declaration, SubHeading); 173*d1d34bafSZixu Wang Result.first->second = std::move(Record); 174*d1d34bafSZixu Wang } 175*d1d34bafSZixu Wang return Result.first->second.get(); 176*d1d34bafSZixu Wang } 177*d1d34bafSZixu Wang 17889f6b26fSZixu Wang StringRef APISet::recordUSR(const Decl *D) { 17989f6b26fSZixu Wang SmallString<128> USR; 18089f6b26fSZixu Wang index::generateUSRForDecl(D, USR); 18189f6b26fSZixu Wang return copyString(USR); 18289f6b26fSZixu Wang } 18389f6b26fSZixu Wang 18489f6b26fSZixu Wang StringRef APISet::copyString(StringRef String) { 18589f6b26fSZixu Wang if (String.empty()) 18689f6b26fSZixu Wang return {}; 18789f6b26fSZixu Wang 18889f6b26fSZixu Wang // No need to allocate memory and copy if the string has already been stored. 1890ee06c31SDaniel Grumberg if (StringAllocator.identifyObject(String.data())) 19089f6b26fSZixu Wang return String; 19189f6b26fSZixu Wang 1920ee06c31SDaniel Grumberg void *Ptr = StringAllocator.Allocate(String.size(), 1); 19389f6b26fSZixu Wang memcpy(Ptr, String.data(), String.size()); 19489f6b26fSZixu Wang return StringRef(reinterpret_cast<const char *>(Ptr), String.size()); 19589f6b26fSZixu Wang } 19689f6b26fSZixu Wang 19789f6b26fSZixu Wang APIRecord::~APIRecord() {} 19889f6b26fSZixu Wang 1999b36e126SZixu Wang ObjCContainerRecord::~ObjCContainerRecord() {} 2009b36e126SZixu Wang 20189f6b26fSZixu Wang void GlobalRecord::anchor() {} 202e5a7d272SZixu Wang void EnumConstantRecord::anchor() {} 203e5a7d272SZixu Wang void EnumRecord::anchor() {} 204e5a7d272SZixu Wang void StructFieldRecord::anchor() {} 205e5a7d272SZixu Wang void StructRecord::anchor() {} 2069b36e126SZixu Wang void ObjCPropertyRecord::anchor() {} 2079b36e126SZixu Wang void ObjCInstanceVariableRecord::anchor() {} 2089b36e126SZixu Wang void ObjCMethodRecord::anchor() {} 2099b36e126SZixu Wang void ObjCInterfaceRecord::anchor() {} 210*d1d34bafSZixu Wang void ObjCProtocolRecord::anchor() {} 211