Path: blob/main/contrib/llvm-project/clang/lib/ExtractAPI/API.cpp
35232 views
//===- ExtractAPI/API.cpp ---------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file implements the APIRecord and derived record structs,10/// and the APISet class.11///12//===----------------------------------------------------------------------===//1314#include "clang/ExtractAPI/API.h"15#include "clang/AST/RawCommentList.h"16#include "clang/Index/USRGeneration.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/Support/ErrorHandling.h"19#include <memory>2021using namespace clang::extractapi;22using namespace llvm;2324SymbolReference::SymbolReference(const APIRecord *R)25: Name(R->Name), USR(R->USR), Record(R) {}2627APIRecord *APIRecord::castFromRecordContext(const RecordContext *Ctx) {28switch (Ctx->getKind()) {29#define RECORD_CONTEXT(CLASS, KIND) \30case KIND: \31return static_cast<CLASS *>(const_cast<RecordContext *>(Ctx));32#include "clang/ExtractAPI/APIRecords.inc"33default:34return nullptr;35// llvm_unreachable("RecordContext derived class isn't propertly36// implemented");37}38}3940RecordContext *APIRecord::castToRecordContext(const APIRecord *Record) {41if (!Record)42return nullptr;43switch (Record->getKind()) {44#define RECORD_CONTEXT(CLASS, KIND) \45case KIND: \46return static_cast<CLASS *>(const_cast<APIRecord *>(Record));47#include "clang/ExtractAPI/APIRecords.inc"48default:49return nullptr;50// llvm_unreachable("RecordContext derived class isn't propertly51// implemented");52}53}5455bool RecordContext::IsWellFormed() const {56// Check that First and Last are both null or both non-null.57return (First == nullptr) == (Last == nullptr);58}5960void RecordContext::stealRecordChain(RecordContext &Other) {61assert(IsWellFormed());62// If we don't have an empty chain append Other's chain into ours.63if (First)64Last->NextInContext = Other.First;65else66First = Other.First;6768Last = Other.Last;6970// Delete Other's chain to ensure we don't accidentally traverse it.71Other.First = nullptr;72Other.Last = nullptr;73}7475void RecordContext::addToRecordChain(APIRecord *Record) const {76assert(IsWellFormed());77if (!First) {78First = Record;79Last = Record;80return;81}8283Last->NextInContext = Record;84Last = Record;85}8687APIRecord *APISet::findRecordForUSR(StringRef USR) const {88if (USR.empty())89return nullptr;9091auto FindIt = USRBasedLookupTable.find(USR);92if (FindIt != USRBasedLookupTable.end())93return FindIt->getSecond().get();9495return nullptr;96}9798StringRef APISet::copyString(StringRef String) {99if (String.empty())100return {};101102// No need to allocate memory and copy if the string has already been stored.103if (Allocator.identifyObject(String.data()))104return String;105106void *Ptr = Allocator.Allocate(String.size(), 1);107memcpy(Ptr, String.data(), String.size());108return StringRef(reinterpret_cast<const char *>(Ptr), String.size());109}110111SymbolReference APISet::createSymbolReference(StringRef Name, StringRef USR,112StringRef Source) {113return SymbolReference(copyString(Name), copyString(USR), copyString(Source));114}115116APIRecord::~APIRecord() {}117TagRecord::~TagRecord() {}118RecordRecord::~RecordRecord() {}119RecordFieldRecord::~RecordFieldRecord() {}120ObjCContainerRecord::~ObjCContainerRecord() {}121ObjCMethodRecord::~ObjCMethodRecord() {}122ObjCPropertyRecord::~ObjCPropertyRecord() {}123CXXMethodRecord::~CXXMethodRecord() {}124125void GlobalFunctionRecord::anchor() {}126void GlobalVariableRecord::anchor() {}127void EnumConstantRecord::anchor() {}128void EnumRecord::anchor() {}129void StructFieldRecord::anchor() {}130void StructRecord::anchor() {}131void UnionFieldRecord::anchor() {}132void UnionRecord::anchor() {}133void CXXFieldRecord::anchor() {}134void CXXClassRecord::anchor() {}135void CXXConstructorRecord::anchor() {}136void CXXDestructorRecord::anchor() {}137void CXXInstanceMethodRecord::anchor() {}138void CXXStaticMethodRecord::anchor() {}139void ObjCInstancePropertyRecord::anchor() {}140void ObjCClassPropertyRecord::anchor() {}141void ObjCInstanceVariableRecord::anchor() {}142void ObjCInstanceMethodRecord::anchor() {}143void ObjCClassMethodRecord::anchor() {}144void ObjCCategoryRecord::anchor() {}145void ObjCInterfaceRecord::anchor() {}146void ObjCProtocolRecord::anchor() {}147void MacroDefinitionRecord::anchor() {}148void TypedefRecord::anchor() {}149150151