aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/ExtractAPI/API.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-04 19:20:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-08 19:02:26 +0000
commit81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch)
tree311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/clang/lib/ExtractAPI/API.cpp
parent5fff09660e06a66bed6482da9c70df328e16bbb6 (diff)
parent145449b1e420787bb99721a429341fa6be3adfb6 (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/ExtractAPI/API.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/ExtractAPI/API.cpp233
1 files changed, 233 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/ExtractAPI/API.cpp b/contrib/llvm-project/clang/lib/ExtractAPI/API.cpp
new file mode 100644
index 000000000000..073e36f320d3
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/ExtractAPI/API.cpp
@@ -0,0 +1,233 @@
+//===- ExtractAPI/API.cpp ---------------------------------------*- C++ -*-===//
+//
+// 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
+/// This file implements the APIRecord and derived record structs,
+/// and the APISet class.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/ExtractAPI/API.h"
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/CommentLexer.h"
+#include "clang/AST/RawCommentList.h"
+#include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+
+using namespace clang::extractapi;
+using namespace llvm;
+
+namespace {
+
+template <typename RecordTy, typename... CtorArgsTy>
+RecordTy *addTopLevelRecord(APISet::RecordMap<RecordTy> &RecordMap,
+ StringRef USR, CtorArgsTy &&...CtorArgs) {
+ auto Result = RecordMap.insert({USR, nullptr});
+
+ // Create the record if it does not already exist
+ if (Result.second)
+ Result.first->second =
+ std::make_unique<RecordTy>(USR, std::forward<CtorArgsTy>(CtorArgs)...);
+
+ return Result.first->second.get();
+}
+
+} // namespace
+
+GlobalVariableRecord *
+APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Fragments,
+ DeclarationFragments SubHeading) {
+ return addTopLevelRecord(GlobalVariables, USR, Name, Loc, Availability,
+ Linkage, Comment, Fragments, SubHeading);
+}
+
+GlobalFunctionRecord *APISet::addGlobalFunction(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Fragments,
+ DeclarationFragments SubHeading, FunctionSignature Signature) {
+ return addTopLevelRecord(GlobalFunctions, USR, Name, Loc, Availability,
+ Linkage, Comment, Fragments, SubHeading, Signature);
+}
+
+EnumConstantRecord *APISet::addEnumConstant(
+ EnumRecord *Enum, StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading) {
+ auto Record = std::make_unique<EnumConstantRecord>(
+ USR, Name, Loc, Availability, Comment, Declaration, SubHeading);
+ 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) {
+ return addTopLevelRecord(Enums, USR, Name, Loc, Availability, Comment,
+ Declaration, SubHeading);
+}
+
+StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name,
+ StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading) {
+ auto Record = std::make_unique<StructFieldRecord>(
+ USR, Name, Loc, Availability, Comment, Declaration, SubHeading);
+ 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) {
+ return addTopLevelRecord(Structs, USR, Name, Loc, Availability, Comment,
+ Declaration, SubHeading);
+}
+
+ObjCCategoryRecord *APISet::addObjCCategory(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ SymbolReference Interface) {
+ // Create the category record.
+ auto *Record = addTopLevelRecord(ObjCCategories, USR, Name, Loc, Availability,
+ Comment, Declaration, SubHeading, Interface);
+
+ // If this category is extending a known interface, associate it with the
+ // ObjCInterfaceRecord.
+ auto It = ObjCInterfaces.find(Interface.USR);
+ if (It != ObjCInterfaces.end())
+ It->second->Categories.push_back(Record);
+
+ return Record;
+}
+
+ObjCInterfaceRecord *APISet::addObjCInterface(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, SymbolReference SuperClass) {
+ return addTopLevelRecord(ObjCInterfaces, USR, Name, Loc, Availability,
+ Linkage, Comment, Declaration, SubHeading,
+ SuperClass);
+}
+
+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>(
+ USR, Name, 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>(
+ USR, Name, 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>(
+ USR, Name, Loc, Availability, Comment, Declaration, SubHeading, Access);
+ return Container->Ivars.emplace_back(std::move(Record)).get();
+}
+
+ObjCProtocolRecord *APISet::addObjCProtocol(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading) {
+ return addTopLevelRecord(ObjCProtocols, USR, Name, Loc, Availability, Comment,
+ Declaration, SubHeading);
+}
+
+MacroDefinitionRecord *
+APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading) {
+ return addTopLevelRecord(Macros, USR, Name, Loc, Declaration, SubHeading);
+}
+
+TypedefRecord *APISet::addTypedef(StringRef Name, StringRef USR,
+ PresumedLoc Loc,
+ const AvailabilityInfo &Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ SymbolReference UnderlyingType) {
+ return addTopLevelRecord(Typedefs, USR, Name, Loc, Availability, Comment,
+ Declaration, SubHeading, UnderlyingType);
+}
+
+StringRef APISet::recordUSR(const Decl *D) {
+ SmallString<128> USR;
+ index::generateUSRForDecl(D, USR);
+ return copyString(USR);
+}
+
+StringRef APISet::recordUSRForMacro(StringRef Name, SourceLocation SL,
+ const SourceManager &SM) {
+ SmallString<128> USR;
+ index::generateUSRForMacro(Name, SL, SM, USR);
+ return copyString(USR);
+}
+
+StringRef APISet::copyString(StringRef String) {
+ if (String.empty())
+ return {};
+
+ // No need to allocate memory and copy if the string has already been stored.
+ if (StringAllocator.identifyObject(String.data()))
+ return String;
+
+ void *Ptr = StringAllocator.Allocate(String.size(), 1);
+ memcpy(Ptr, String.data(), String.size());
+ return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
+}
+
+APIRecord::~APIRecord() {}
+
+ObjCContainerRecord::~ObjCContainerRecord() {}
+
+void GlobalFunctionRecord::anchor() {}
+void GlobalVariableRecord::anchor() {}
+void EnumConstantRecord::anchor() {}
+void EnumRecord::anchor() {}
+void StructFieldRecord::anchor() {}
+void StructRecord::anchor() {}
+void ObjCPropertyRecord::anchor() {}
+void ObjCInstanceVariableRecord::anchor() {}
+void ObjCMethodRecord::anchor() {}
+void ObjCCategoryRecord::anchor() {}
+void ObjCInterfaceRecord::anchor() {}
+void ObjCProtocolRecord::anchor() {}
+void MacroDefinitionRecord::anchor() {}
+void TypedefRecord::anchor() {}