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" 2089f6b26fSZixu Wang #include "llvm/Support/Allocator.h" 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. 3589f6b26fSZixu Wang auto Record = APIRecordUniquePtr<GlobalRecord>(new (Allocator) GlobalRecord{ 3689f6b26fSZixu Wang Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments, 3789f6b26fSZixu Wang 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 62*71b4c226SZixu Wang EnumConstantRecord *APISet::addEnumConstant( 63*71b4c226SZixu Wang EnumRecord *Enum, StringRef Name, StringRef USR, PresumedLoc Loc, 64*71b4c226SZixu Wang const AvailabilityInfo &Availability, const DocComment &Comment, 65*71b4c226SZixu Wang DeclarationFragments Declaration, DeclarationFragments SubHeading) { 66*71b4c226SZixu Wang auto Record = 67*71b4c226SZixu Wang APIRecordUniquePtr<EnumConstantRecord>(new (Allocator) EnumConstantRecord{ 68*71b4c226SZixu Wang Name, USR, Loc, Availability, Comment, Declaration, SubHeading}); 69*71b4c226SZixu Wang return Enum->Constants.emplace_back(std::move(Record)).get(); 70*71b4c226SZixu Wang } 71*71b4c226SZixu Wang 72*71b4c226SZixu Wang EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc, 73*71b4c226SZixu Wang const AvailabilityInfo &Availability, 74*71b4c226SZixu Wang const DocComment &Comment, 75*71b4c226SZixu Wang DeclarationFragments Declaration, 76*71b4c226SZixu Wang DeclarationFragments SubHeading) { 77*71b4c226SZixu Wang auto Result = Enums.insert({Name, nullptr}); 78*71b4c226SZixu Wang if (Result.second) { 79*71b4c226SZixu Wang // Create the record if it does not already exist. 80*71b4c226SZixu Wang auto Record = APIRecordUniquePtr<EnumRecord>(new (Allocator) EnumRecord{ 81*71b4c226SZixu Wang Name, USR, Loc, Availability, Comment, Declaration, SubHeading}); 82*71b4c226SZixu Wang Result.first->second = std::move(Record); 83*71b4c226SZixu Wang } 84*71b4c226SZixu Wang return Result.first->second.get(); 85*71b4c226SZixu Wang } 86*71b4c226SZixu Wang 8789f6b26fSZixu Wang StringRef APISet::recordUSR(const Decl *D) { 8889f6b26fSZixu Wang SmallString<128> USR; 8989f6b26fSZixu Wang index::generateUSRForDecl(D, USR); 9089f6b26fSZixu Wang return copyString(USR); 9189f6b26fSZixu Wang } 9289f6b26fSZixu Wang 9389f6b26fSZixu Wang StringRef APISet::copyString(StringRef String) { 9489f6b26fSZixu Wang if (String.empty()) 9589f6b26fSZixu Wang return {}; 9689f6b26fSZixu Wang 9789f6b26fSZixu Wang // No need to allocate memory and copy if the string has already been stored. 9889f6b26fSZixu Wang if (Allocator.identifyObject(String.data())) 9989f6b26fSZixu Wang return String; 10089f6b26fSZixu Wang 10189f6b26fSZixu Wang void *Ptr = Allocator.Allocate(String.size(), 1); 10289f6b26fSZixu Wang memcpy(Ptr, String.data(), String.size()); 10389f6b26fSZixu Wang return StringRef(reinterpret_cast<const char *>(Ptr), String.size()); 10489f6b26fSZixu Wang } 10589f6b26fSZixu Wang 10689f6b26fSZixu Wang APIRecord::~APIRecord() {} 10789f6b26fSZixu Wang 10889f6b26fSZixu Wang void GlobalRecord::anchor() {} 109