1*89f6b26fSZixu Wang //===- ExtractAPI/API.cpp ---------------------------------------*- C++ -*-===//
2*89f6b26fSZixu Wang //
3*89f6b26fSZixu Wang // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*89f6b26fSZixu Wang // See https://llvm.org/LICENSE.txt for license information.
5*89f6b26fSZixu Wang // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*89f6b26fSZixu Wang //
7*89f6b26fSZixu Wang //===----------------------------------------------------------------------===//
8*89f6b26fSZixu Wang ///
9*89f6b26fSZixu Wang /// \file
10*89f6b26fSZixu Wang /// This file implements the APIRecord and derived record structs,
11*89f6b26fSZixu Wang /// and the APISet class.
12*89f6b26fSZixu Wang ///
13*89f6b26fSZixu Wang //===----------------------------------------------------------------------===//
14*89f6b26fSZixu Wang 
15*89f6b26fSZixu Wang #include "clang/ExtractAPI/API.h"
16*89f6b26fSZixu Wang #include "clang/AST/CommentCommandTraits.h"
17*89f6b26fSZixu Wang #include "clang/AST/CommentLexer.h"
18*89f6b26fSZixu Wang #include "clang/AST/RawCommentList.h"
19*89f6b26fSZixu Wang #include "clang/Index/USRGeneration.h"
20*89f6b26fSZixu Wang #include "llvm/Support/Allocator.h"
21*89f6b26fSZixu Wang 
22*89f6b26fSZixu Wang using namespace clang::extractapi;
23*89f6b26fSZixu Wang using namespace llvm;
24*89f6b26fSZixu Wang 
25*89f6b26fSZixu Wang GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR,
26*89f6b26fSZixu Wang                                 PresumedLoc Loc,
27*89f6b26fSZixu Wang                                 const AvailabilityInfo &Availability,
28*89f6b26fSZixu Wang                                 LinkageInfo Linkage, const DocComment &Comment,
29*89f6b26fSZixu Wang                                 DeclarationFragments Fragments,
30*89f6b26fSZixu Wang                                 DeclarationFragments SubHeading,
31*89f6b26fSZixu Wang                                 FunctionSignature Signature) {
32*89f6b26fSZixu Wang   auto Result = Globals.insert({Name, nullptr});
33*89f6b26fSZixu Wang   if (Result.second) {
34*89f6b26fSZixu Wang     // Create the record if it does not already exist.
35*89f6b26fSZixu Wang     auto Record = APIRecordUniquePtr<GlobalRecord>(new (Allocator) GlobalRecord{
36*89f6b26fSZixu Wang         Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments,
37*89f6b26fSZixu Wang         SubHeading, Signature});
38*89f6b26fSZixu Wang     Result.first->second = std::move(Record);
39*89f6b26fSZixu Wang   }
40*89f6b26fSZixu Wang   return Result.first->second.get();
41*89f6b26fSZixu Wang }
42*89f6b26fSZixu Wang 
43*89f6b26fSZixu Wang GlobalRecord *
44*89f6b26fSZixu Wang APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
45*89f6b26fSZixu Wang                      const AvailabilityInfo &Availability, LinkageInfo Linkage,
46*89f6b26fSZixu Wang                      const DocComment &Comment, DeclarationFragments Fragments,
47*89f6b26fSZixu Wang                      DeclarationFragments SubHeading) {
48*89f6b26fSZixu Wang   return addGlobal(GVKind::Variable, Name, USR, Loc, Availability, Linkage,
49*89f6b26fSZixu Wang                    Comment, Fragments, SubHeading, {});
50*89f6b26fSZixu Wang }
51*89f6b26fSZixu Wang 
52*89f6b26fSZixu Wang GlobalRecord *
53*89f6b26fSZixu Wang APISet::addFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
54*89f6b26fSZixu Wang                     const AvailabilityInfo &Availability, LinkageInfo Linkage,
55*89f6b26fSZixu Wang                     const DocComment &Comment, DeclarationFragments Fragments,
56*89f6b26fSZixu Wang                     DeclarationFragments SubHeading,
57*89f6b26fSZixu Wang                     FunctionSignature Signature) {
58*89f6b26fSZixu Wang   return addGlobal(GVKind::Function, Name, USR, Loc, Availability, Linkage,
59*89f6b26fSZixu Wang                    Comment, Fragments, SubHeading, Signature);
60*89f6b26fSZixu Wang }
61*89f6b26fSZixu Wang 
62*89f6b26fSZixu Wang StringRef APISet::recordUSR(const Decl *D) {
63*89f6b26fSZixu Wang   SmallString<128> USR;
64*89f6b26fSZixu Wang   index::generateUSRForDecl(D, USR);
65*89f6b26fSZixu Wang   return copyString(USR);
66*89f6b26fSZixu Wang }
67*89f6b26fSZixu Wang 
68*89f6b26fSZixu Wang StringRef APISet::copyString(StringRef String) {
69*89f6b26fSZixu Wang   if (String.empty())
70*89f6b26fSZixu Wang     return {};
71*89f6b26fSZixu Wang 
72*89f6b26fSZixu Wang   // No need to allocate memory and copy if the string has already been stored.
73*89f6b26fSZixu Wang   if (Allocator.identifyObject(String.data()))
74*89f6b26fSZixu Wang     return String;
75*89f6b26fSZixu Wang 
76*89f6b26fSZixu Wang   void *Ptr = Allocator.Allocate(String.size(), 1);
77*89f6b26fSZixu Wang   memcpy(Ptr, String.data(), String.size());
78*89f6b26fSZixu Wang   return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
79*89f6b26fSZixu Wang }
80*89f6b26fSZixu Wang 
81*89f6b26fSZixu Wang APIRecord::~APIRecord() {}
82*89f6b26fSZixu Wang 
83*89f6b26fSZixu Wang void GlobalRecord::anchor() {}
84