2022-03-21 00:53:28 -07:00
|
|
|
//===- ExtractAPI/API.cpp ---------------------------------------*- C++ -*-===//
|
2022-02-10 13:42:35 -08:00
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \file
|
2022-03-21 00:53:28 -07:00
|
|
|
/// This file implements the APIRecord and derived record structs,
|
|
|
|
/// and the APISet class.
|
2022-02-10 13:42:35 -08:00
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2022-03-21 00:53:28 -07:00
|
|
|
#include "clang/ExtractAPI/API.h"
|
2022-02-10 13:42:35 -08:00
|
|
|
#include "clang/AST/CommentCommandTraits.h"
|
|
|
|
#include "clang/AST/CommentLexer.h"
|
|
|
|
#include "clang/AST/RawCommentList.h"
|
|
|
|
#include "clang/Index/USRGeneration.h"
|
2022-03-23 15:03:02 +00:00
|
|
|
#include <memory>
|
2022-02-10 13:42:35 -08:00
|
|
|
|
2022-03-21 00:53:28 -07:00
|
|
|
using namespace clang::extractapi;
|
|
|
|
using namespace llvm;
|
2022-02-10 13:42:35 -08:00
|
|
|
|
2022-03-16 16:01:50 -07:00
|
|
|
GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR,
|
|
|
|
PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability,
|
|
|
|
LinkageInfo Linkage, const DocComment &Comment,
|
|
|
|
DeclarationFragments Fragments,
|
|
|
|
DeclarationFragments SubHeading,
|
|
|
|
FunctionSignature Signature) {
|
2022-02-10 13:42:35 -08:00
|
|
|
auto Result = Globals.insert({Name, nullptr});
|
|
|
|
if (Result.second) {
|
2022-03-21 00:53:28 -07:00
|
|
|
// Create the record if it does not already exist.
|
2022-03-23 15:03:02 +00:00
|
|
|
auto Record = std::make_unique<GlobalRecord>(
|
2022-03-18 23:54:56 +00:00
|
|
|
Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments,
|
2022-03-23 15:03:02 +00:00
|
|
|
SubHeading, Signature);
|
2022-03-18 23:54:56 +00:00
|
|
|
Result.first->second = std::move(Record);
|
2022-02-10 13:42:35 -08:00
|
|
|
}
|
2022-03-18 23:54:56 +00:00
|
|
|
return Result.first->second.get();
|
2022-02-10 13:42:35 -08:00
|
|
|
}
|
|
|
|
|
2022-03-16 16:01:50 -07:00
|
|
|
GlobalRecord *
|
|
|
|
APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
|
|
|
const DocComment &Comment, DeclarationFragments Fragments,
|
|
|
|
DeclarationFragments SubHeading) {
|
2022-02-10 13:42:35 -08:00
|
|
|
return addGlobal(GVKind::Variable, Name, USR, Loc, Availability, Linkage,
|
|
|
|
Comment, Fragments, SubHeading, {});
|
|
|
|
}
|
|
|
|
|
2022-03-16 16:01:50 -07:00
|
|
|
GlobalRecord *
|
|
|
|
APISet::addFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
|
|
|
const DocComment &Comment, DeclarationFragments Fragments,
|
|
|
|
DeclarationFragments SubHeading,
|
|
|
|
FunctionSignature Signature) {
|
2022-02-10 13:42:35 -08:00
|
|
|
return addGlobal(GVKind::Function, Name, USR, Loc, Availability, Linkage,
|
|
|
|
Comment, Fragments, SubHeading, Signature);
|
|
|
|
}
|
|
|
|
|
2022-03-16 17:49:31 -07:00
|
|
|
EnumConstantRecord *APISet::addEnumConstant(
|
|
|
|
EnumRecord *Enum, StringRef Name, StringRef USR, PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability, const DocComment &Comment,
|
|
|
|
DeclarationFragments Declaration, DeclarationFragments SubHeading) {
|
2022-03-23 15:03:02 +00:00
|
|
|
auto Record = std::make_unique<EnumConstantRecord>(
|
|
|
|
Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
|
2022-03-16 17:49:31 -07:00
|
|
|
return Enum->Constants.emplace_back(std::move(Record)).get();
|
|
|
|
}
|
|
|
|
|
|
|
|
EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability,
|
|
|
|
const DocComment &Comment,
|
|
|
|
DeclarationFragments Declaration,
|
|
|
|
DeclarationFragments SubHeading) {
|
|
|
|
auto Result = Enums.insert({Name, nullptr});
|
|
|
|
if (Result.second) {
|
|
|
|
// Create the record if it does not already exist.
|
2022-03-23 15:03:02 +00:00
|
|
|
auto Record = std::make_unique<EnumRecord>(
|
|
|
|
Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
|
2022-03-16 17:49:31 -07:00
|
|
|
Result.first->second = std::move(Record);
|
|
|
|
}
|
|
|
|
return Result.first->second.get();
|
|
|
|
}
|
|
|
|
|
2022-03-21 19:11:29 -07:00
|
|
|
StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name,
|
|
|
|
StringRef USR, PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability,
|
|
|
|
const DocComment &Comment,
|
|
|
|
DeclarationFragments Declaration,
|
|
|
|
DeclarationFragments SubHeading) {
|
2022-03-23 15:03:02 +00:00
|
|
|
auto Record = std::make_unique<StructFieldRecord>(
|
|
|
|
Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
|
2022-03-21 19:11:29 -07:00
|
|
|
return Struct->Fields.emplace_back(std::move(Record)).get();
|
|
|
|
}
|
|
|
|
|
|
|
|
StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability,
|
|
|
|
const DocComment &Comment,
|
|
|
|
DeclarationFragments Declaration,
|
|
|
|
DeclarationFragments SubHeading) {
|
|
|
|
auto Result = Structs.insert({Name, nullptr});
|
|
|
|
if (Result.second) {
|
|
|
|
// Create the record if it does not already exist.
|
2022-03-23 15:03:02 +00:00
|
|
|
auto Record = std::make_unique<StructRecord>(
|
|
|
|
Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
|
2022-03-21 19:11:29 -07:00
|
|
|
Result.first->second = std::move(Record);
|
|
|
|
}
|
|
|
|
return Result.first->second.get();
|
|
|
|
}
|
|
|
|
|
2022-03-24 18:19:30 -07:00
|
|
|
ObjCInterfaceRecord *APISet::addObjCInterface(
|
|
|
|
StringRef Name, StringRef USR, PresumedLoc Loc,
|
|
|
|
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
|
|
|
const DocComment &Comment, DeclarationFragments Declaration,
|
|
|
|
DeclarationFragments SubHeading, SymbolReference SuperClass) {
|
|
|
|
auto Result = ObjCInterfaces.insert({Name, nullptr});
|
|
|
|
if (Result.second) {
|
|
|
|
// Create the record if it does not already exist.
|
|
|
|
auto Record = std::make_unique<ObjCInterfaceRecord>(
|
|
|
|
Name, USR, Loc, Availability, Linkage, Comment, Declaration, SubHeading,
|
|
|
|
SuperClass);
|
|
|
|
Result.first->second = std::move(Record);
|
|
|
|
}
|
|
|
|
return Result.first->second.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMethodRecord *APISet::addObjCMethod(
|
|
|
|
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
|
|
|
PresumedLoc Loc, const AvailabilityInfo &Availability,
|
|
|
|
const DocComment &Comment, DeclarationFragments Declaration,
|
|
|
|
DeclarationFragments SubHeading, FunctionSignature Signature,
|
|
|
|
bool IsInstanceMethod) {
|
|
|
|
auto Record = std::make_unique<ObjCMethodRecord>(
|
|
|
|
Name, USR, Loc, Availability, Comment, Declaration, SubHeading, Signature,
|
|
|
|
IsInstanceMethod);
|
|
|
|
return Container->Methods.emplace_back(std::move(Record)).get();
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCPropertyRecord *APISet::addObjCProperty(
|
|
|
|
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
|
|
|
PresumedLoc Loc, const AvailabilityInfo &Availability,
|
|
|
|
const DocComment &Comment, DeclarationFragments Declaration,
|
|
|
|
DeclarationFragments SubHeading,
|
|
|
|
ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName,
|
|
|
|
StringRef SetterName, bool IsOptional) {
|
|
|
|
auto Record = std::make_unique<ObjCPropertyRecord>(
|
|
|
|
Name, USR, Loc, Availability, Comment, Declaration, SubHeading,
|
|
|
|
Attributes, GetterName, SetterName, IsOptional);
|
|
|
|
return Container->Properties.emplace_back(std::move(Record)).get();
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable(
|
|
|
|
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
|
|
|
PresumedLoc Loc, const AvailabilityInfo &Availability,
|
|
|
|
const DocComment &Comment, DeclarationFragments Declaration,
|
|
|
|
DeclarationFragments SubHeading,
|
|
|
|
ObjCInstanceVariableRecord::AccessControl Access) {
|
|
|
|
auto Record = std::make_unique<ObjCInstanceVariableRecord>(
|
|
|
|
Name, USR, Loc, Availability, Comment, Declaration, SubHeading, Access);
|
|
|
|
return Container->Ivars.emplace_back(std::move(Record)).get();
|
|
|
|
}
|
|
|
|
|
2022-03-16 16:01:50 -07:00
|
|
|
StringRef APISet::recordUSR(const Decl *D) {
|
2022-02-10 13:42:35 -08:00
|
|
|
SmallString<128> USR;
|
|
|
|
index::generateUSRForDecl(D, USR);
|
|
|
|
return copyString(USR);
|
|
|
|
}
|
|
|
|
|
2022-03-21 00:53:28 -07:00
|
|
|
StringRef APISet::copyString(StringRef String) {
|
2022-02-10 13:42:35 -08:00
|
|
|
if (String.empty())
|
|
|
|
return {};
|
|
|
|
|
2022-03-21 00:53:28 -07:00
|
|
|
// No need to allocate memory and copy if the string has already been stored.
|
2022-03-23 15:03:02 +00:00
|
|
|
if (StringAllocator.identifyObject(String.data()))
|
2022-02-10 13:42:35 -08:00
|
|
|
return String;
|
|
|
|
|
2022-03-23 15:03:02 +00:00
|
|
|
void *Ptr = StringAllocator.Allocate(String.size(), 1);
|
2022-02-10 13:42:35 -08:00
|
|
|
memcpy(Ptr, String.data(), String.size());
|
|
|
|
return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
|
|
|
|
}
|
|
|
|
|
2022-03-21 00:53:28 -07:00
|
|
|
APIRecord::~APIRecord() {}
|
2022-02-10 13:42:35 -08:00
|
|
|
|
2022-03-24 18:19:30 -07:00
|
|
|
ObjCContainerRecord::~ObjCContainerRecord() {}
|
|
|
|
|
2022-03-21 00:53:28 -07:00
|
|
|
void GlobalRecord::anchor() {}
|
2022-03-24 14:30:14 -07:00
|
|
|
void EnumConstantRecord::anchor() {}
|
|
|
|
void EnumRecord::anchor() {}
|
|
|
|
void StructFieldRecord::anchor() {}
|
|
|
|
void StructRecord::anchor() {}
|
2022-03-24 18:19:30 -07:00
|
|
|
void ObjCPropertyRecord::anchor() {}
|
|
|
|
void ObjCInstanceVariableRecord::anchor() {}
|
|
|
|
void ObjCMethodRecord::anchor() {}
|
|
|
|
void ObjCInterfaceRecord::anchor() {}
|