clang  19.0.0git
API.cpp
Go to the documentation of this file.
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"
17 #include "clang/Basic/Module.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 
27  : Name(R->Name), USR(R->USR), Record(R) {}
28 
30  switch (Ctx->getKind()) {
31 #define RECORD_CONTEXT(CLASS, KIND) \
32  case KIND: \
33  return static_cast<CLASS *>(const_cast<RecordContext *>(Ctx));
35  default:
36  return nullptr;
37  // llvm_unreachable("RecordContext derived class isn't propertly
38  // implemented");
39  }
40 }
41 
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));
50  default:
51  return nullptr;
52  // llvm_unreachable("RecordContext derived class isn't propertly
53  // implemented");
54  }
55 }
56 
57 bool RecordContext::IsWellFormed() const {
58  // Check that First and Last are both null or both non-null.
59  return (First == nullptr) == (Last == nullptr);
60 }
61 
63  assert(IsWellFormed());
64  // If we don't have an empty chain append Other's chain into ours.
65  if (First)
66  Last->NextInContext = Other.First;
67  else
68  First = Other.First;
69 
70  Last = Other.Last;
71 
72  // Delete Other's chain to ensure we don't accidentally traverse it.
73  Other.First = nullptr;
74  Other.Last = nullptr;
75 }
76 
78  assert(IsWellFormed());
79  if (!First) {
80  First = Record;
81  Last = Record;
82  return;
83  }
84 
85  Last->NextInContext = Record;
86  Last = Record;
87 }
88 
89 APIRecord *APISet::findRecordForUSR(StringRef USR) const {
90  if (USR.empty())
91  return nullptr;
92 
93  auto FindIt = USRBasedLookupTable.find(USR);
94  if (FindIt != USRBasedLookupTable.end())
95  return FindIt->getSecond().get();
96 
97  return nullptr;
98 }
99 
100 StringRef APISet::copyString(StringRef String) {
101  if (String.empty())
102  return {};
103 
104  // No need to allocate memory and copy if the string has already been stored.
105  if (Allocator.identifyObject(String.data()))
106  return String;
107 
108  void *Ptr = Allocator.Allocate(String.size(), 1);
109  memcpy(Ptr, String.data(), String.size());
110  return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
111 }
112 
113 SymbolReference APISet::createSymbolReference(StringRef Name, StringRef USR,
114  StringRef Source) {
115  return SymbolReference(copyString(Name), copyString(USR), copyString(Source));
116 }
117 
126 
127 void GlobalFunctionRecord::anchor() {}
128 void GlobalVariableRecord::anchor() {}
129 void EnumConstantRecord::anchor() {}
130 void EnumRecord::anchor() {}
131 void StructFieldRecord::anchor() {}
132 void StructRecord::anchor() {}
133 void UnionFieldRecord::anchor() {}
134 void UnionRecord::anchor() {}
135 void CXXFieldRecord::anchor() {}
136 void CXXClassRecord::anchor() {}
137 void CXXConstructorRecord::anchor() {}
138 void CXXDestructorRecord::anchor() {}
139 void CXXInstanceMethodRecord::anchor() {}
140 void CXXStaticMethodRecord::anchor() {}
141 void ObjCInstancePropertyRecord::anchor() {}
142 void ObjCClassPropertyRecord::anchor() {}
143 void ObjCInstanceVariableRecord::anchor() {}
144 void ObjCInstanceMethodRecord::anchor() {}
145 void ObjCClassMethodRecord::anchor() {}
146 void ObjCCategoryRecord::anchor() {}
147 void ObjCInterfaceRecord::anchor() {}
148 void ObjCProtocolRecord::anchor() {}
149 void MacroDefinitionRecord::anchor() {}
150 void TypedefRecord::anchor() {}
This file defines the APIRecord-based structs and the APISet class.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Module class, which describes a module in the source code.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
SymbolReference createSymbolReference(StringRef Name, StringRef USR, StringRef Source="")
Definition: API.cpp:113
StringRef copyString(StringRef String)
Copy String into the Allocator in this APISet.
Definition: API.cpp:100
APIRecord * findRecordForUSR(StringRef USR) const
Finds the APIRecord for a given USR.
Definition: API.cpp:89
Base class used for specific record types that have children records this is analogous to the DeclCon...
Definition: API.h:313
APIRecord::RecordKind getKind() const
Definition: API.h:331
void stealRecordChain(RecordContext &Other)
Append Other children chain into ours and empty out Other's record chain.
Definition: API.cpp:62
void addToRecordChain(APIRecord *) const
Definition: API.cpp:77
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
The base representation of an API record. Holds common symbol information.
Definition: API.h:192
virtual ~APIRecord()=0
Definition: API.cpp:118
static APIRecord * castFromRecordContext(const RecordContext *Ctx)
Definition: API.cpp:29
static RecordContext * castToRecordContext(const APIRecord *Record)
Definition: API.cpp:42
virtual ~TagRecord()=0
Definition: API.cpp:119