1 //===- ExtractAPI/API.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements the APIRecord and derived record structs, 11 /// and the APISet class. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/ExtractAPI/API.h" 16 #include "clang/AST/RawCommentList.h" 17 #include "clang/Basic/Module.h" 18 #include "clang/Index/USRGeneration.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include <memory> 22 23 using namespace clang::extractapi; 24 using namespace llvm; 25 26 SymbolReference::SymbolReference(const APIRecord *R) 27 : Name(R->Name), USR(R->USR), Record(R) {} 28 29 APIRecord *APIRecord::castFromRecordContext(const RecordContext *Ctx) { 30 switch (Ctx->getKind()) { 31 #define RECORD_CONTEXT(CLASS, KIND) \ 32 case KIND: \ 33 return static_cast<CLASS *>(const_cast<RecordContext *>(Ctx)); 34 #include "clang/ExtractAPI/APIRecords.inc" 35 default: 36 return nullptr; 37 // llvm_unreachable("RecordContext derived class isn't propertly 38 // implemented"); 39 } 40 } 41 42 RecordContext *APIRecord::castToRecordContext(const APIRecord *Record) { 43 if (!Record) 44 return nullptr; 45 switch (Record->getKind()) { 46 #define RECORD_CONTEXT(CLASS, KIND) \ 47 case KIND: \ 48 return static_cast<CLASS *>(const_cast<APIRecord *>(Record)); 49 #include "clang/ExtractAPI/APIRecords.inc" 50 default: 51 return nullptr; 52 // llvm_unreachable("RecordContext derived class isn't propertly 53 // implemented"); 54 } 55 } 56 57 void RecordContext::addToRecordChain(APIRecord *Record) const { 58 if (!First) { 59 First = Record; 60 Last = Record; 61 return; 62 } 63 64 Last->NextInContext = Record; 65 Last = Record; 66 } 67 68 APIRecord *APISet::findRecordForUSR(StringRef USR) const { 69 if (USR.empty()) 70 return nullptr; 71 72 auto FindIt = USRBasedLookupTable.find(USR); 73 if (FindIt != USRBasedLookupTable.end()) 74 return FindIt->getSecond().get(); 75 76 return nullptr; 77 } 78 79 StringRef APISet::copyString(StringRef String) { 80 if (String.empty()) 81 return {}; 82 83 // No need to allocate memory and copy if the string has already been stored. 84 if (Allocator.identifyObject(String.data())) 85 return String; 86 87 void *Ptr = Allocator.Allocate(String.size(), 1); 88 memcpy(Ptr, String.data(), String.size()); 89 return StringRef(reinterpret_cast<const char *>(Ptr), String.size()); 90 } 91 92 SymbolReference APISet::createSymbolReference(StringRef Name, StringRef USR, 93 StringRef Source) { 94 return SymbolReference(copyString(Name), copyString(USR), copyString(Source)); 95 } 96 97 APIRecord::~APIRecord() {} 98 RecordRecord::~RecordRecord() {} 99 RecordFieldRecord::~RecordFieldRecord() {} 100 ObjCContainerRecord::~ObjCContainerRecord() {} 101 ObjCMethodRecord::~ObjCMethodRecord() {} 102 ObjCPropertyRecord::~ObjCPropertyRecord() {} 103 CXXMethodRecord::~CXXMethodRecord() {} 104 105 void GlobalFunctionRecord::anchor() {} 106 void GlobalVariableRecord::anchor() {} 107 void EnumConstantRecord::anchor() {} 108 void EnumRecord::anchor() {} 109 void StructFieldRecord::anchor() {} 110 void StructRecord::anchor() {} 111 void UnionFieldRecord::anchor() {} 112 void UnionRecord::anchor() {} 113 void CXXFieldRecord::anchor() {} 114 void CXXClassRecord::anchor() {} 115 void CXXConstructorRecord::anchor() {} 116 void CXXDestructorRecord::anchor() {} 117 void CXXInstanceMethodRecord::anchor() {} 118 void CXXStaticMethodRecord::anchor() {} 119 void ObjCInstancePropertyRecord::anchor() {} 120 void ObjCClassPropertyRecord::anchor() {} 121 void ObjCInstanceVariableRecord::anchor() {} 122 void ObjCInstanceMethodRecord::anchor() {} 123 void ObjCClassMethodRecord::anchor() {} 124 void ObjCCategoryRecord::anchor() {} 125 void ObjCInterfaceRecord::anchor() {} 126 void ObjCProtocolRecord::anchor() {} 127 void MacroDefinitionRecord::anchor() {} 128 void TypedefRecord::anchor() {} 129