13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/StringMap.h"
15#include "llvm/Bitstream/BitstreamWriter.h"
16#include "llvm/Support/DJB.h"
17#include "llvm/Support/OnDiskHashTable.h"
18#include "llvm/Support/VersionTuple.h"
26 using VersionedSmallVector =
29 std::string ModuleName;
36 llvm::StringMap<IdentifierID> IdentifierIDs;
45 std::pair<unsigned, VersionedSmallVector<ContextInfo>>>
51 llvm::DenseMap<uint32_t, uint32_t> ParentContexts;
54 llvm::DenseMap<unsigned, uint8_t> ContextKinds;
57 llvm::DenseMap<unsigned, unsigned> ContextNames;
64 std::tuple<unsigned, unsigned, char>,
79 llvm::DenseMap<std::tuple<unsigned, unsigned, char>,
91 llvm::DenseMap<StoredObjCSelector, SelectorID> SelectorIDs;
132 if (Identifier.empty())
136 return IdentifierIDs.try_emplace(Identifier, IdentifierIDs.size() + 1)
150 return SelectorIDs.try_emplace(
Selector, SelectorIDs.size()).first->second;
154 void writeBlockInfoBlock(llvm::BitstreamWriter &Stream);
155 void writeControlBlock(llvm::BitstreamWriter &Stream);
156 void writeIdentifierBlock(llvm::BitstreamWriter &Stream);
157 void writeContextBlock(llvm::BitstreamWriter &Stream);
158 void writeObjCPropertyBlock(llvm::BitstreamWriter &Stream);
159 void writeObjCMethodBlock(llvm::BitstreamWriter &Stream);
160 void writeCXXMethodBlock(llvm::BitstreamWriter &Stream);
161 void writeFieldBlock(llvm::BitstreamWriter &Stream);
162 void writeObjCSelectorBlock(llvm::BitstreamWriter &Stream);
163 void writeGlobalVariableBlock(llvm::BitstreamWriter &Stream);
164 void writeGlobalFunctionBlock(llvm::BitstreamWriter &Stream);
165 void writeEnumConstantBlock(llvm::BitstreamWriter &Stream);
166 void writeTagBlock(llvm::BitstreamWriter &Stream);
167 void writeTypedefBlock(llvm::BitstreamWriter &Stream);
171 : ModuleName(
std::string(ModuleName)), SourceFile(SF) {}
180 llvm::BitstreamWriter Stream(Buffer);
184 Stream.Emit(Byte, 8);
187 writeBlockInfoBlock(Stream);
188 writeControlBlock(Stream);
189 writeIdentifierBlock(Stream);
190 writeContextBlock(Stream);
191 writeObjCPropertyBlock(Stream);
192 writeObjCMethodBlock(Stream);
193 writeCXXMethodBlock(Stream);
194 writeFieldBlock(Stream);
195 writeObjCSelectorBlock(Stream);
196 writeGlobalVariableBlock(Stream);
197 writeGlobalFunctionBlock(Stream);
198 writeEnumConstantBlock(Stream);
199 writeTagBlock(Stream);
200 writeTypedefBlock(Stream);
203 OS.write(Buffer.data(), Buffer.size());
209void emitBlockID(llvm::BitstreamWriter &Stream,
unsigned ID,
210 llvm::StringRef Name) {
211 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID,
218 llvm::bitc::BLOCKINFO_CODE_BLOCKNAME,
220 const_cast<unsigned char *
>(
221 reinterpret_cast<const unsigned char *
>(Name.data())),
226void emitRecordID(llvm::BitstreamWriter &Stream,
unsigned ID,
227 llvm::StringRef Name) {
228 assert(ID < 256 &&
"can't fit record ID in next to name");
231 Buffer.resize(Name.size() + 1);
233 memcpy(Buffer.data() + 1, Name.data(), Name.size());
235 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Buffer);
239void APINotesWriter::Implementation::writeBlockInfoBlock(
240 llvm::BitstreamWriter &Stream) {
241 llvm::BCBlockRAII Scope(Stream, llvm::bitc::BLOCKINFO_BLOCK_ID, 2);
243#define BLOCK(Block) emitBlockID(Stream, Block##_ID, #Block)
244#define BLOCK_RECORD(NameSpace, Block) \
245 emitRecordID(Stream, NameSpace::Block, #Block)
246 BLOCK(CONTROL_BLOCK);
250 BLOCK(IDENTIFIER_BLOCK);
253 BLOCK(OBJC_CONTEXT_BLOCK);
256 BLOCK(OBJC_PROPERTY_BLOCK);
259 BLOCK(OBJC_METHOD_BLOCK);
262 BLOCK(OBJC_SELECTOR_BLOCK);
265 BLOCK(GLOBAL_VARIABLE_BLOCK);
266 BLOCK_RECORD(global_variable_block, GLOBAL_VARIABLE_DATA);
268 BLOCK(GLOBAL_FUNCTION_BLOCK);
269 BLOCK_RECORD(global_function_block, GLOBAL_FUNCTION_DATA);
274void APINotesWriter::Implementation::writeControlBlock(
275 llvm::BitstreamWriter &Stream) {
282 ModuleName.emit(Scratch, this->ModuleName);
286 SourceFile.emit(Scratch, this->SourceFile->
getSize(),
287 this->SourceFile->getModificationTime());
293class IdentifierTableInfo {
295 using key_type = StringRef;
296 using key_type_ref = key_type;
298 using data_type_ref =
const data_type &;
300 using offset_type = unsigned;
302 hash_value_type
ComputeHash(key_type_ref Key) {
return llvm::djbHash(Key); }
304 std::pair<unsigned, unsigned>
305 EmitKeyDataLength(raw_ostream &OS, key_type_ref Key, data_type_ref) {
309 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
310 writer.write<uint16_t>(KeyLength);
311 writer.write<uint16_t>(DataLength);
312 return {KeyLength, DataLength};
315 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
OS << Key; }
317 void EmitData(raw_ostream &OS, key_type_ref, data_type_ref Data,
unsigned) {
318 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
324void APINotesWriter::Implementation::writeIdentifierBlock(
325 llvm::BitstreamWriter &Stream) {
328 if (IdentifierIDs.empty())
331 llvm::SmallString<4096> HashTableBlob;
334 llvm::OnDiskChainedHashTableGenerator<IdentifierTableInfo>
Generator;
335 for (
auto &II : IdentifierIDs)
338 llvm::raw_svector_ostream BlobStream(HashTableBlob);
340 llvm::support::endian::write<uint32_t>(BlobStream, 0,
341 llvm::endianness::little);
346 IdentifierData.emit(Scratch, Offset, HashTableBlob);
351class ContextIDTableInfo {
353 using key_type = ContextTableKey;
354 using key_type_ref = key_type;
355 using data_type = unsigned;
356 using data_type_ref =
const data_type &;
357 using hash_value_type =
size_t;
358 using offset_type = unsigned;
361 return static_cast<size_t>(Key.hashValue());
364 std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &OS, key_type_ref,
369 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
370 writer.write<uint16_t>(KeyLength);
371 writer.write<uint16_t>(DataLength);
372 return {KeyLength, DataLength};
375 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
376 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
377 writer.write<
uint32_t>(Key.parentContextID);
378 writer.write<uint8_t>(Key.contextKind);
379 writer.write<
uint32_t>(Key.contextID);
382 void EmitData(raw_ostream &OS, key_type_ref, data_type_ref Data,
unsigned) {
383 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
390template <
typename T>
struct MakeDependent {
typedef T Type; };
394unsigned getVersionTupleSize(
const VersionTuple &VT) {
395 unsigned size =
sizeof(uint8_t) +
sizeof(uint32_t);
398 if (VT.getSubminor())
407unsigned getVersionedInfoSize(
408 const llvm::SmallVectorImpl<std::pair<llvm::VersionTuple, T>> &VI,
409 llvm::function_ref<
unsigned(
const typename MakeDependent<T>::Type &)>
411 unsigned result =
sizeof(uint16_t);
412 for (
const auto &E : VI) {
413 result += getVersionTupleSize(E.first);
414 result += getInfoSize(E.second);
420void emitVersionTuple(raw_ostream &OS,
const VersionTuple &VT) {
421 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
427 else if (VT.getSubminor())
429 else if (VT.getMinor())
433 writer.write<uint8_t>(descriptor);
436 writer.write<
uint32_t>(VT.getMajor());
437 if (
auto minor = VT.getMinor())
439 if (
auto subminor = VT.getSubminor())
441 if (
auto build = VT.getBuild())
447void emitVersionedInfo(
448 raw_ostream &OS, llvm::SmallVectorImpl<std::pair<VersionTuple, T>> &VI,
449 llvm::function_ref<
void(raw_ostream &,
450 const typename MakeDependent<T>::Type &)>
452 std::sort(VI.begin(), VI.end(),
453 [](
const std::pair<VersionTuple, T> &LHS,
454 const std::pair<VersionTuple, T> &RHS) ->
bool {
455 assert((&LHS == &RHS || LHS.first != RHS.first) &&
456 "two entries for the same version");
457 return LHS.first < RHS.first;
460 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
461 writer.write<uint16_t>(VI.size());
462 for (
const auto &E : VI) {
463 emitVersionTuple(OS, E.first);
464 emitInfo(OS, E.second);
469template <
typename Derived,
typename KeyType,
typename UnversionedDataType>
470class VersionedTableInfo {
471 Derived &asDerived() {
return *
static_cast<Derived *
>(
this); }
473 const Derived &asDerived()
const {
474 return *
static_cast<const Derived *
>(
this);
478 using key_type = KeyType;
479 using key_type_ref = key_type;
481 llvm::SmallVector<std::pair<llvm::VersionTuple, UnversionedDataType>, 1>;
482 using data_type_ref = data_type &;
483 using hash_value_type =
size_t;
484 using offset_type = unsigned;
486 std::pair<unsigned, unsigned>
487 EmitKeyDataLength(raw_ostream &OS, key_type_ref Key, data_type_ref Data) {
488 uint32_t KeyLength = asDerived().getKeyLength(Key);
490 getVersionedInfoSize(Data, [
this](
const UnversionedDataType &UI) {
491 return asDerived().getUnversionedInfoSize(UI);
494 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
495 writer.write<uint16_t>(KeyLength);
496 writer.write<uint16_t>(DataLength);
497 return {KeyLength, DataLength};
500 void EmitData(raw_ostream &OS, key_type_ref, data_type_ref Data,
unsigned) {
502 OS, Data, [
this](llvm::raw_ostream &OS,
const UnversionedDataType &UI) {
503 asDerived().emitUnversionedInfo(OS, UI);
509void emitCommonEntityInfo(raw_ostream &OS,
const CommonEntityInfo &CEI) {
510 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
513 if (
auto safety = CEI.getSwiftSafety()) {
514 payload =
static_cast<unsigned>(*safety);
519 if (
auto swiftPrivate = CEI.isSwiftPrivate()) {
525 payload |= CEI.Unavailable;
527 payload |= CEI.UnavailableInSwift;
529 writer.write<uint8_t>(payload);
531 writer.write<uint16_t>(CEI.UnavailableMsg.size());
532 OS.write(CEI.UnavailableMsg.c_str(), CEI.UnavailableMsg.size());
534 writer.write<uint16_t>(CEI.SwiftName.size());
535 OS.write(CEI.SwiftName.c_str(), CEI.SwiftName.size());
540unsigned getCommonEntityInfoSize(
const CommonEntityInfo &CEI) {
541 return 5 + CEI.UnavailableMsg.size() + CEI.SwiftName.size();
546unsigned getCommonTypeInfoSize(
const CommonTypeInfo &CTI) {
547 return 2 + (CTI.getSwiftBridge() ? CTI.getSwiftBridge()->size() : 0) + 2 +
548 (CTI.getNSErrorDomain() ? CTI.getNSErrorDomain()->size() : 0) + 2 +
549 (CTI.getSwiftConformance() ? CTI.getSwiftConformance()->size() : 0) +
550 getCommonEntityInfoSize(CTI);
554void emitCommonTypeInfo(raw_ostream &OS,
const CommonTypeInfo &CTI) {
555 emitCommonEntityInfo(OS, CTI);
557 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
558 if (
auto swiftBridge = CTI.getSwiftBridge()) {
559 writer.write<uint16_t>(swiftBridge->size() + 1);
560 OS.write(swiftBridge->c_str(), swiftBridge->size());
562 writer.write<uint16_t>(0);
564 if (
auto nsErrorDomain = CTI.getNSErrorDomain()) {
565 writer.write<uint16_t>(nsErrorDomain->size() + 1);
566 OS.write(nsErrorDomain->c_str(), CTI.getNSErrorDomain()->size());
568 writer.write<uint16_t>(0);
570 if (
auto conformance = CTI.getSwiftConformance()) {
571 writer.write<uint16_t>(conformance->size() + 1);
572 OS.write(conformance->c_str(), conformance->size());
574 writer.write<uint16_t>(0);
579class ContextInfoTableInfo
580 :
public VersionedTableInfo<ContextInfoTableInfo, unsigned, ContextInfo> {
582 unsigned getKeyLength(key_type_ref) {
return sizeof(
uint32_t); }
584 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
585 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
593 unsigned getUnversionedInfoSize(
const ContextInfo &OCI) {
594 return getCommonTypeInfoSize(OCI) + 1;
597 void emitUnversionedInfo(raw_ostream &OS,
const ContextInfo &OCI) {
598 emitCommonTypeInfo(OS, OCI);
601 if (
auto swiftImportAsNonGeneric = OCI.getSwiftImportAsNonGeneric())
602 payload |= (0x01 << 1) | (uint8_t)swiftImportAsNonGeneric.value();
604 if (
auto swiftObjCMembers = OCI.getSwiftObjCMembers())
605 payload |= (0x01 << 1) | (uint8_t)swiftObjCMembers.value();
607 if (
auto nullable = OCI.getDefaultNullability())
608 payload |= (0x01 << 2) |
static_cast<uint8_t
>(*nullable);
609 payload = (payload << 1) | (OCI.hasDesignatedInits() ? 1 : 0);
616void APINotesWriter::Implementation::writeContextBlock(
617 llvm::BitstreamWriter &Stream) {
620 if (Contexts.empty())
624 llvm::SmallString<4096> HashTableBlob;
627 llvm::OnDiskChainedHashTableGenerator<ContextIDTableInfo>
Generator;
628 for (
auto &OC : Contexts)
629 Generator.insert(OC.first, OC.second.first);
631 llvm::raw_svector_ostream BlobStream(HashTableBlob);
633 llvm::support::endian::write<uint32_t>(BlobStream, 0,
634 llvm::endianness::little);
639 ContextID.emit(Scratch, Offset, HashTableBlob);
643 llvm::SmallString<4096> HashTableBlob;
646 llvm::OnDiskChainedHashTableGenerator<ContextInfoTableInfo>
Generator;
647 for (
auto &OC : Contexts)
648 Generator.insert(OC.second.first, OC.second.second);
650 llvm::raw_svector_ostream BlobStream(HashTableBlob);
652 llvm::support::endian::write<uint32_t>(BlobStream, 0,
653 llvm::endianness::little);
658 ContextInfo.emit(Scratch, Offset, HashTableBlob);
665unsigned getVariableInfoSize(
const VariableInfo &VI) {
666 return 2 + getCommonEntityInfoSize(VI) + 2 + VI.getType().size();
668unsigned getParamInfoSize(
const ParamInfo &PI);
671void emitVariableInfo(raw_ostream &OS,
const VariableInfo &VI) {
672 emitCommonEntityInfo(OS, VI);
674 uint8_t
bytes[2] = {0, 0};
675 if (
auto nullable = VI.getNullability()) {
677 bytes[1] =
static_cast<uint8_t
>(*nullable);
682 OS.write(
reinterpret_cast<const char *
>(
bytes), 2);
684 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
685 writer.write<uint16_t>(VI.getType().size());
686 OS.write(VI.getType().data(), VI.getType().size());
690class ObjCPropertyTableInfo
691 :
public VersionedTableInfo<ObjCPropertyTableInfo,
692 std::tuple<unsigned, unsigned, char>,
695 unsigned getKeyLength(key_type_ref) {
696 return sizeof(
uint32_t) +
sizeof(uint32_t) +
sizeof(uint8_t);
699 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
700 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
701 writer.write<
uint32_t>(std::get<0>(Key));
702 writer.write<
uint32_t>(std::get<1>(Key));
703 writer.write<uint8_t>(std::get<2>(Key));
710 unsigned getUnversionedInfoSize(
const ObjCPropertyInfo &OPI) {
711 return getVariableInfoSize(OPI) + 1;
714 void emitUnversionedInfo(raw_ostream &OS,
const ObjCPropertyInfo &OPI) {
715 emitVariableInfo(OS, OPI);
718 if (
auto value = OPI.getSwiftImportAsAccessors()) {
720 flags |= value.value() << 1;
727void APINotesWriter::Implementation::writeObjCPropertyBlock(
728 llvm::BitstreamWriter &Stream) {
731 if (ObjCProperties.empty())
735 llvm::SmallString<4096> HashTableBlob;
738 llvm::OnDiskChainedHashTableGenerator<ObjCPropertyTableInfo>
Generator;
739 for (
auto &OP : ObjCProperties)
742 llvm::raw_svector_ostream BlobStream(HashTableBlob);
744 llvm::support::endian::write<uint32_t>(BlobStream, 0,
745 llvm::endianness::little);
750 ObjCPropertyData.emit(Scratch, Offset, HashTableBlob);
755unsigned getFunctionInfoSize(
const FunctionInfo &);
756void emitFunctionInfo(llvm::raw_ostream &,
const FunctionInfo &);
757void emitParamInfo(raw_ostream &OS,
const ParamInfo &PI);
760class ObjCMethodTableInfo
761 :
public VersionedTableInfo<ObjCMethodTableInfo,
762 std::tuple<unsigned, unsigned, char>,
765 unsigned getKeyLength(key_type_ref) {
766 return sizeof(
uint32_t) +
sizeof(uint32_t) +
sizeof(uint8_t);
769 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
770 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
771 writer.write<
uint32_t>(std::get<0>(Key));
772 writer.write<
uint32_t>(std::get<1>(Key));
773 writer.write<uint8_t>(std::get<2>(Key));
780 unsigned getUnversionedInfoSize(
const ObjCMethodInfo &OMI) {
781 auto size = getFunctionInfoSize(OMI) + 1;
783 size += getParamInfoSize(*OMI.Self);
787 void emitUnversionedInfo(raw_ostream &OS,
const ObjCMethodInfo &OMI) {
789 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
790 flags = (flags << 1) | OMI.DesignatedInit;
791 flags = (flags << 1) | OMI.RequiredInit;
792 flags = (flags << 1) | static_cast<bool>(OMI.Self);
793 writer.write<uint8_t>(flags);
795 emitFunctionInfo(OS, OMI);
798 emitParamInfo(OS, *OMI.Self);
803class CXXMethodTableInfo
804 :
public VersionedTableInfo<CXXMethodTableInfo, SingleDeclTableKey,
807 unsigned getKeyLength(key_type_ref) {
808 return sizeof(
uint32_t) +
sizeof(uint32_t);
811 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
812 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
813 writer.write<
uint32_t>(Key.parentContextID);
818 return static_cast<size_t>(key.hashValue());
821 unsigned getUnversionedInfoSize(
const CXXMethodInfo &MI) {
822 auto size = getFunctionInfoSize(MI) + 1;
824 size += getParamInfoSize(*MI.This);
828 void emitUnversionedInfo(raw_ostream &OS,
const CXXMethodInfo &MI) {
830 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
831 flags = (flags << 1) | static_cast<bool>(MI.This);
832 writer.write<uint8_t>(flags);
834 emitFunctionInfo(OS, MI);
836 emitParamInfo(OS, *MI.This);
841void APINotesWriter::Implementation::writeObjCMethodBlock(
842 llvm::BitstreamWriter &Stream) {
845 if (ObjCMethods.empty())
849 llvm::SmallString<4096> HashTableBlob;
852 llvm::OnDiskChainedHashTableGenerator<ObjCMethodTableInfo>
Generator;
853 for (
auto &OM : ObjCMethods)
856 llvm::raw_svector_ostream BlobStream(HashTableBlob);
858 llvm::support::endian::write<uint32_t>(BlobStream, 0,
859 llvm::endianness::little);
864 ObjCMethodData.emit(Scratch, Offset, HashTableBlob);
868void APINotesWriter::Implementation::writeCXXMethodBlock(
869 llvm::BitstreamWriter &Stream) {
872 if (CXXMethods.empty())
876 llvm::SmallString<4096> HashTableBlob;
879 llvm::OnDiskChainedHashTableGenerator<CXXMethodTableInfo>
Generator;
880 for (
auto &MD : CXXMethods)
883 llvm::raw_svector_ostream BlobStream(HashTableBlob);
885 llvm::support::endian::write<uint32_t>(BlobStream, 0,
886 llvm::endianness::little);
891 CXXMethodData.emit(Scratch, Offset, HashTableBlob);
898 :
public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
900 unsigned getKeyLength(key_type_ref) {
901 return sizeof(
uint32_t) +
sizeof(uint32_t);
904 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
905 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
906 writer.write<
uint32_t>(Key.parentContextID);
911 return static_cast<size_t>(key.hashValue());
914 unsigned getUnversionedInfoSize(
const FieldInfo &FI) {
915 return getVariableInfoSize(FI);
918 void emitUnversionedInfo(raw_ostream &OS,
const FieldInfo &FI) {
919 emitVariableInfo(OS, FI);
924void APINotesWriter::Implementation::writeFieldBlock(
925 llvm::BitstreamWriter &Stream) {
932 llvm::SmallString<4096> HashTableBlob;
935 llvm::OnDiskChainedHashTableGenerator<FieldTableInfo>
Generator;
936 for (
auto &FD : Fields)
939 llvm::raw_svector_ostream BlobStream(HashTableBlob);
941 llvm::support::endian::write<uint32_t>(BlobStream, 0,
942 llvm::endianness::little);
947 FieldData.emit(Scratch, Offset, HashTableBlob);
953class ObjCSelectorTableInfo {
955 using key_type = StoredObjCSelector;
956 using key_type_ref =
const key_type &;
958 using data_type_ref = data_type;
959 using hash_value_type = unsigned;
960 using offset_type = unsigned;
963 return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(Key);
966 std::pair<unsigned, unsigned>
967 EmitKeyDataLength(raw_ostream &OS, key_type_ref Key, data_type_ref) {
969 sizeof(uint16_t) +
sizeof(uint32_t) * Key.Identifiers.size();
972 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
973 writer.write<uint16_t>(KeyLength);
974 writer.write<uint16_t>(DataLength);
975 return {KeyLength, DataLength};
978 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
979 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
980 writer.write<uint16_t>(Key.NumArgs);
981 for (
auto Identifier : Key.Identifiers)
985 void EmitData(raw_ostream &OS, key_type_ref, data_type_ref Data,
unsigned) {
986 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
992void APINotesWriter::Implementation::writeObjCSelectorBlock(
993 llvm::BitstreamWriter &Stream) {
996 if (SelectorIDs.empty())
1000 llvm::SmallString<4096> HashTableBlob;
1003 llvm::OnDiskChainedHashTableGenerator<ObjCSelectorTableInfo>
Generator;
1004 for (
auto &S : SelectorIDs)
1007 llvm::raw_svector_ostream BlobStream(HashTableBlob);
1009 llvm::support::endian::write<uint32_t>(BlobStream, 0,
1010 llvm::endianness::little);
1015 ObjCSelectorData.emit(Scratch, Offset, HashTableBlob);
1021class GlobalVariableTableInfo
1022 :
public VersionedTableInfo<GlobalVariableTableInfo, SingleDeclTableKey,
1023 GlobalVariableInfo> {
1025 unsigned getKeyLength(key_type_ref) {
1026 return sizeof(
uint32_t) +
sizeof(uint32_t);
1029 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
1030 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1031 writer.write<
uint32_t>(Key.parentContextID);
1032 writer.write<
uint32_t>(Key.nameID);
1036 return static_cast<size_t>(Key.hashValue());
1039 unsigned getUnversionedInfoSize(
const GlobalVariableInfo &GVI) {
1040 return getVariableInfoSize(GVI);
1043 void emitUnversionedInfo(raw_ostream &OS,
const GlobalVariableInfo &GVI) {
1044 emitVariableInfo(OS, GVI);
1049void APINotesWriter::Implementation::writeGlobalVariableBlock(
1050 llvm::BitstreamWriter &Stream) {
1053 if (GlobalVariables.empty())
1057 llvm::SmallString<4096> HashTableBlob;
1060 llvm::OnDiskChainedHashTableGenerator<GlobalVariableTableInfo>
Generator;
1061 for (
auto &GV : GlobalVariables)
1064 llvm::raw_svector_ostream BlobStream(HashTableBlob);
1066 llvm::support::endian::write<uint32_t>(BlobStream, 0,
1067 llvm::endianness::little);
1072 GlobalVariableData.emit(Scratch, Offset, HashTableBlob);
1077void emitBoundsSafetyInfo(raw_ostream &OS,
const BoundsSafetyInfo &BSI) {
1078 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1080 if (
auto kind = BSI.getKind()) {
1083 flags |= (uint8_t)*
kind << 1;
1086 if (
auto level = BSI.getLevel()) {
1087 assert(*level < (1u << 3));
1089 flags |= (uint8_t)*level << 1;
1092 writer.write<uint8_t>(flags);
1093 writer.write<uint16_t>(BSI.ExternalBounds.size());
1095 ArrayRef<char>{BSI.ExternalBounds.data(), BSI.ExternalBounds.size()});
1098unsigned getBoundsSafetyInfoSize(
const BoundsSafetyInfo &BSI) {
1099 return 1 +
sizeof(uint16_t) + BSI.ExternalBounds.size();
1102unsigned getParamInfoSize(
const ParamInfo &PI) {
1103 unsigned BSISize = 0;
1104 if (
auto BSI = PI.BoundsSafety)
1105 BSISize = getBoundsSafetyInfoSize(*BSI);
1106 return getVariableInfoSize(PI) + 1 + BSISize;
1109void emitParamInfo(raw_ostream &OS,
const ParamInfo &PI) {
1110 emitVariableInfo(OS, PI);
1113 if (PI.BoundsSafety)
1116 if (
auto noescape = PI.isNoEscape()) {
1122 if (
auto lifetimebound = PI.isLifetimebound()) {
1128 if (
auto RCC = PI.getRetainCountConvention())
1129 flags |=
static_cast<uint8_t
>(RCC.value()) + 1;
1131 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1132 writer.write<uint8_t>(flags);
1133 if (
auto BSI = PI.BoundsSafety)
1134 emitBoundsSafetyInfo(OS, *BSI);
1139unsigned getFunctionInfoSize(
const FunctionInfo &FI) {
1140 unsigned size = getCommonEntityInfoSize(FI) + 2 +
sizeof(
uint64_t);
1141 size +=
sizeof(uint16_t);
1142 for (
const auto &P : FI.Params)
1143 size += getParamInfoSize(P);
1144 size +=
sizeof(uint16_t) + FI.ResultType.size();
1145 size +=
sizeof(uint16_t) + FI.SwiftReturnOwnership.size();
1150void emitFunctionInfo(raw_ostream &OS,
const FunctionInfo &FI) {
1151 emitCommonEntityInfo(OS, FI);
1154 flags |= FI.NullabilityAudited;
1156 if (
auto RCC = FI.getRetainCountConvention())
1157 flags |=
static_cast<uint8_t
>(RCC.value()) + 1;
1159 flags |= FI.UnsafeBufferUsage;
1161 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1163 writer.write<uint8_t>(flags);
1164 writer.write<uint8_t>(FI.NumAdjustedNullable);
1165 writer.write<
uint64_t>(FI.NullabilityPayload);
1167 writer.write<uint16_t>(FI.Params.size());
1168 for (
const auto &PI : FI.Params)
1169 emitParamInfo(OS, PI);
1171 writer.write<uint16_t>(FI.ResultType.size());
1172 writer.write(ArrayRef<char>{FI.ResultType});
1173 writer.write<uint16_t>(FI.SwiftReturnOwnership.size());
1174 writer.write(ArrayRef<char>{FI.SwiftReturnOwnership});
1178class GlobalFunctionTableInfo
1179 :
public VersionedTableInfo<GlobalFunctionTableInfo, SingleDeclTableKey,
1180 GlobalFunctionInfo> {
1182 unsigned getKeyLength(key_type_ref) {
1183 return sizeof(
uint32_t) +
sizeof(uint32_t);
1186 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
1187 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1188 writer.write<
uint32_t>(Key.parentContextID);
1189 writer.write<
uint32_t>(Key.nameID);
1193 return static_cast<size_t>(Key.hashValue());
1196 unsigned getUnversionedInfoSize(
const GlobalFunctionInfo &GFI) {
1197 return getFunctionInfoSize(GFI);
1200 void emitUnversionedInfo(raw_ostream &OS,
const GlobalFunctionInfo &GFI) {
1201 emitFunctionInfo(OS, GFI);
1206void APINotesWriter::Implementation::writeGlobalFunctionBlock(
1207 llvm::BitstreamWriter &Stream) {
1210 if (GlobalFunctions.empty())
1214 llvm::SmallString<4096> HashTableBlob;
1217 llvm::OnDiskChainedHashTableGenerator<GlobalFunctionTableInfo>
Generator;
1218 for (
auto &F : GlobalFunctions)
1221 llvm::raw_svector_ostream BlobStream(HashTableBlob);
1223 llvm::support::endian::write<uint32_t>(BlobStream, 0,
1224 llvm::endianness::little);
1229 GlobalFunctionData.emit(Scratch, Offset, HashTableBlob);
1235class EnumConstantTableInfo
1236 :
public VersionedTableInfo<EnumConstantTableInfo, unsigned,
1239 unsigned getKeyLength(key_type_ref) {
return sizeof(
uint32_t); }
1241 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
1242 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1250 unsigned getUnversionedInfoSize(
const EnumConstantInfo &ECI) {
1251 return getCommonEntityInfoSize(ECI);
1254 void emitUnversionedInfo(raw_ostream &OS,
const EnumConstantInfo &ECI) {
1255 emitCommonEntityInfo(OS, ECI);
1260void APINotesWriter::Implementation::writeEnumConstantBlock(
1261 llvm::BitstreamWriter &Stream) {
1264 if (EnumConstants.empty())
1268 llvm::SmallString<4096> HashTableBlob;
1271 llvm::OnDiskChainedHashTableGenerator<EnumConstantTableInfo>
Generator;
1272 for (
auto &EC : EnumConstants)
1275 llvm::raw_svector_ostream BlobStream(HashTableBlob);
1277 llvm::support::endian::write<uint32_t>(BlobStream, 0,
1278 llvm::endianness::little);
1283 EnumConstantData.emit(Scratch, Offset, HashTableBlob);
1288template <
typename Derived,
typename UnversionedDataType>
1289class CommonTypeTableInfo
1290 :
public VersionedTableInfo<Derived, SingleDeclTableKey,
1291 UnversionedDataType> {
1293 using key_type_ref =
typename CommonTypeTableInfo::key_type_ref;
1294 using hash_value_type =
typename CommonTypeTableInfo::hash_value_type;
1296 unsigned getKeyLength(key_type_ref) {
1297 return sizeof(
uint32_t) +
sizeof(IdentifierID);
1300 void EmitKey(raw_ostream &OS, key_type_ref Key,
unsigned) {
1301 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1302 writer.write<
uint32_t>(Key.parentContextID);
1307 return static_cast<size_t>(Key.hashValue());
1310 unsigned getUnversionedInfoSize(
const UnversionedDataType &UDT) {
1311 return getCommonTypeInfoSize(UDT);
1314 void emitUnversionedInfo(raw_ostream &OS,
const UnversionedDataType &UDT) {
1315 emitCommonTypeInfo(OS, UDT);
1320class TagTableInfo :
public CommonTypeTableInfo<TagTableInfo, TagInfo> {
1322 unsigned getUnversionedInfoSize(
const TagInfo &TI) {
1324 return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
1325 2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
1326 2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
1327 2 + (TI.SwiftDestroyOp ? TI.SwiftDestroyOp->size() : 0) +
1328 2 + (TI.SwiftDefaultOwnership ? TI.SwiftDefaultOwnership->size() : 0) +
1329 3 + getCommonTypeInfoSize(TI);
1333 void emitUnversionedInfo(raw_ostream &OS,
const TagInfo &TI) {
1334 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1337 if (
auto extensibility = TI.EnumExtensibility) {
1338 Flags |=
static_cast<uint8_t
>(extensibility.value()) + 1;
1339 assert((Flags < (1 << 2)) &&
"must fit in two bits");
1343 if (
auto value = TI.isFlagEnum())
1344 Flags |= (value.value() << 1 | 1 << 0);
1346 writer.write<uint8_t>(Flags);
1348 if (
auto Copyable = TI.isSwiftCopyable())
1351 writer.write<uint8_t>(0);
1353 if (
auto Escapable = TI.isSwiftEscapable())
1356 writer.write<uint8_t>(0);
1358 if (
auto ImportAs = TI.SwiftImportAs) {
1359 writer.write<uint16_t>(ImportAs->size() + 1);
1360 OS.write(ImportAs->c_str(), ImportAs->size());
1362 writer.write<uint16_t>(0);
1364 if (
auto RetainOp = TI.SwiftRetainOp) {
1365 writer.write<uint16_t>(RetainOp->size() + 1);
1366 OS.write(RetainOp->c_str(), RetainOp->size());
1368 writer.write<uint16_t>(0);
1370 if (
auto ReleaseOp = TI.SwiftReleaseOp) {
1371 writer.write<uint16_t>(ReleaseOp->size() + 1);
1372 OS.write(ReleaseOp->c_str(), ReleaseOp->size());
1374 writer.write<uint16_t>(0);
1376 if (
auto DefaultOwnership = TI.SwiftDefaultOwnership) {
1377 writer.write<uint16_t>(DefaultOwnership->size() + 1);
1378 OS.write(DefaultOwnership->c_str(), DefaultOwnership->size());
1380 writer.write<uint16_t>(0);
1382 if (
auto DestroyOp = TI.SwiftDestroyOp) {
1383 writer.write<uint16_t>(DestroyOp->size() + 1);
1384 OS.write(DestroyOp->c_str(), DestroyOp->size());
1386 writer.write<uint16_t>(0);
1389 emitCommonTypeInfo(OS, TI);
1394void APINotesWriter::Implementation::writeTagBlock(
1395 llvm::BitstreamWriter &Stream) {
1402 llvm::SmallString<4096> HashTableBlob;
1405 llvm::OnDiskChainedHashTableGenerator<TagTableInfo>
Generator;
1406 for (
auto &T : Tags)
1409 llvm::raw_svector_ostream BlobStream(HashTableBlob);
1411 llvm::support::endian::write<uint32_t>(BlobStream, 0,
1412 llvm::endianness::little);
1417 TagData.emit(Scratch, Offset, HashTableBlob);
1423class TypedefTableInfo
1424 :
public CommonTypeTableInfo<TypedefTableInfo, TypedefInfo> {
1426 unsigned getUnversionedInfoSize(
const TypedefInfo &TI) {
1427 return 1 + getCommonTypeInfoSize(TI);
1430 void emitUnversionedInfo(raw_ostream &OS,
const TypedefInfo &TI) {
1431 llvm::support::endian::Writer writer(OS, llvm::endianness::little);
1434 if (
auto swiftWrapper = TI.SwiftWrapper)
1435 Flags |=
static_cast<uint8_t
>(*swiftWrapper) + 1;
1437 writer.write<uint8_t>(Flags);
1439 emitCommonTypeInfo(OS, TI);
1444void APINotesWriter::Implementation::writeTypedefBlock(
1445 llvm::BitstreamWriter &Stream) {
1448 if (Typedefs.empty())
1452 llvm::SmallString<4096> HashTableBlob;
1455 llvm::OnDiskChainedHashTableGenerator<TypedefTableInfo>
Generator;
1456 for (
auto &T : Typedefs)
1459 llvm::raw_svector_ostream BlobStream(HashTableBlob);
1461 llvm::support::endian::write<uint32_t>(BlobStream, 0,
1462 llvm::endianness::little);
1467 TypedefData.emit(Scratch, Offset, HashTableBlob);
1485 llvm::VersionTuple SwiftVersion) {
1488 uint32_t RawParentCtxID = ParentCtxID ? ParentCtxID->Value : -1;
1489 ContextTableKey Key(RawParentCtxID,
static_cast<uint8_t
>(Kind), NameID);
1494 Implementation::VersionedSmallVector<ContextInfo> EmptyVersionedInfo;
1496 .insert(std::make_pair(
1497 Key, std::make_pair(NextID, EmptyVersionedInfo)))
1502 Implementation->ContextKinds[NextID] =
static_cast<uint8_t
>(Kind);
1506 auto &VersionedVec = Known->second.second;
1508 for (
auto &Versioned : VersionedVec) {
1509 if (Versioned.first == SwiftVersion) {
1510 Versioned.second |= Info;
1517 VersionedVec.push_back({SwiftVersion, Info});
1523 bool IsInstanceProperty,
1525 VersionTuple SwiftVersion) {
1528 ->ObjCProperties[std::make_tuple(CtxID.
Value, NameID, IsInstanceProperty)]
1529 .push_back({SwiftVersion, Info});
1533 bool IsInstanceMethod,
1535 VersionTuple SwiftVersion) {
1537 auto Key = std::tuple<unsigned, unsigned, char>{CtxID.
Value, SelID,
1539 Implementation->ObjCMethods[Key].push_back({SwiftVersion, Info});
1552 for (
auto &Versioned : VersionedVec) {
1553 if (Versioned.first == SwiftVersion) {
1554 Versioned.second.setHasDesignatedInits(
true);
1561 VersionedVec.push_back({SwiftVersion,
ContextInfo()});
1562 VersionedVec.back().second.setHasDesignatedInits(
true);
1569 VersionTuple SwiftVersion) {
1577 VersionTuple SwiftVersion) {
1584 llvm::StringRef Name,
1586 VersionTuple SwiftVersion) {
1589 Implementation->GlobalVariables[Key].push_back({SwiftVersion, Info});
1593 llvm::StringRef Name,
1595 VersionTuple SwiftVersion) {
1598 Implementation->GlobalFunctions[Key].push_back({SwiftVersion, Info});
1603 VersionTuple SwiftVersion) {
1605 Implementation->EnumConstants[EnumConstantID].push_back({SwiftVersion, Info});
1609 const TagInfo &Info, VersionTuple SwiftVersion) {
1617 VersionTuple SwiftVersion) {
#define BLOCK_RECORD(NameSpace, Block)
static StringRef bytes(const std::vector< T, Allocator > &v)
Defines the clang::FileManager interface and associated types.
static void emitRecordID(unsigned ID, const char *Name, llvm::BitstreamWriter &Stream, SmallVectorImpl< uint64_t > &Record)
static void emitBlockID(unsigned ID, const char *Name, llvm::BitstreamWriter &Stream, SmallVectorImpl< uint64_t > &Record)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
static StringRef getIdentifier(const Token &Tok)
#define BLOCK(DERIVED, BASE)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Cached information about one file (either on disk or in the virtual file system).
Smart pointer class that efficiently represents Objective-C method names.
friend class APINotesWriter
void writeToStream(llvm::raw_ostream &OS)
Implementation(llvm::StringRef ModuleName, const FileEntry *SF)
void addObjCMethod(ContextID CtxID, ObjCSelectorRef Selector, bool IsInstanceMethod, const ObjCMethodInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific Objective-C method.
void addEnumConstant(llvm::StringRef Name, const EnumConstantInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about an enumerator.
ContextID addContext(std::optional< ContextID > ParentCtxID, llvm::StringRef Name, ContextKind Kind, const ContextInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific Objective-C class or protocol or a C++ namespace.
void addGlobalFunction(std::optional< Context > Ctx, llvm::StringRef Name, const GlobalFunctionInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a global function.
void addObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstanceProperty, const ObjCPropertyInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific Objective-C property.
void addField(ContextID CtxID, llvm::StringRef Name, const FieldInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific C record field.
void addGlobalVariable(std::optional< Context > Ctx, llvm::StringRef Name, const GlobalVariableInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a global variable.
void addTypedef(std::optional< Context > Ctx, llvm::StringRef Name, const TypedefInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a typedef.
void writeToStream(llvm::raw_ostream &OS)
void addCXXMethod(ContextID CtxID, llvm::StringRef Name, const CXXMethodInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a specific C++ method.
void addTag(std::optional< Context > Ctx, llvm::StringRef Name, const TagInfo &Info, llvm::VersionTuple SwiftVersion)
Add information about a tag (struct/union/enum/C++ class).
APINotesWriter(llvm::StringRef ModuleName, const FileEntry *SF)
Create a new API notes writer with the given module name and (optional) source file.
Describes API notes data for a C++ method.
Opaque context ID used to refer to an Objective-C class or protocol or a C++ namespace.
Describes API notes data for an Objective-C class or protocol or a C++ namespace.
Describes API notes data for an enumerator.
Describes API notes data for a C/C++ record field.
Describes API notes data for a global function.
Describes API notes data for a global variable.
Describes API notes data for an Objective-C method.
unsigned DesignatedInit
Whether this is a designated initializer of its class.
Describes API notes data for an Objective-C property.
Describes API notes data for a tag.
Describes API notes data for a typedef.
llvm::BCRecordLayout< CONTEXT_INFO_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > ContextInfoLayout
llvm::BCRecordLayout< CONTEXT_ID_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > ContextIDLayout
llvm::BCRecordLayout< MODULE_NAME, llvm::BCBlob > ModuleNameLayout
llvm::BCRecordLayout< SOURCE_FILE, llvm::BCVBR< 16 >, llvm::BCVBR< 16 > > SourceFileLayout
llvm::BCRecordLayout< METADATA, llvm::BCFixed< 16 >, llvm::BCFixed< 16 > > MetadataLayout
llvm::BCRecordLayout< CXX_METHOD_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > CXXMethodDataLayout
llvm::BCRecordLayout< ENUM_CONSTANT_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > EnumConstantDataLayout
llvm::BCRecordLayout< FIELD_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > FieldDataLayout
llvm::BCRecordLayout< GLOBAL_FUNCTION_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > GlobalFunctionDataLayout
llvm::BCRecordLayout< GLOBAL_VARIABLE_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > GlobalVariableDataLayout
llvm::BCRecordLayout< IDENTIFIER_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > IdentifierDataLayout
llvm::BCRecordLayout< OBJC_METHOD_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > ObjCMethodDataLayout
llvm::BCRecordLayout< OBJC_PROPERTY_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > ObjCPropertyDataLayout
llvm::BCRecordLayout< OBJC_SELECTOR_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > ObjCSelectorDataLayout
llvm::BCRecordLayout< TAG_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > TagDataLayout
llvm::BCRecordLayout< TYPEDEF_DATA, llvm::BCVBR< 16 >, llvm::BCBlob > TypedefDataLayout
llvm::PointerEmbeddedInt< unsigned, 31 > IdentifierID
llvm::PointerEmbeddedInt< unsigned, 31 > SelectorID
const uint8_t kSwiftConforms
const uint8_t kSwiftDoesNotConform
const uint16_t VERSION_MAJOR
API notes file major version number.
const unsigned char API_NOTES_SIGNATURE[]
Magic number for API notes files.
const uint16_t VERSION_MINOR
API notes file minor version number.
@ OBJC_CONTEXT_BLOCK_ID
The Objective-C context data block, which contains information about Objective-C classes and protocol...
@ TYPEDEF_BLOCK_ID
The typedef data block, which maps typedef names to information about the typedefs.
@ OBJC_PROPERTY_BLOCK_ID
The Objective-C property data block, which maps Objective-C (class name, property name) pairs to info...
@ ENUM_CONSTANT_BLOCK_ID
The enum constant data block, which maps enumerator names to information about the enumerators.
@ TAG_BLOCK_ID
The tag data block, which maps tag names to information about the tags.
@ OBJC_METHOD_BLOCK_ID
The Objective-C property data block, which maps Objective-C (class name, selector,...
@ FIELD_BLOCK_ID
The fields data block, which maps names fields of C records to information about the field.
@ OBJC_SELECTOR_BLOCK_ID
The Objective-C selector data block, which maps Objective-C selector names (# of pieces,...
@ CXX_METHOD_BLOCK_ID
The C++ method data block, which maps C++ (context id, method name) pairs to information about the me...
@ GLOBAL_FUNCTION_BLOCK_ID
The (global) functions data block, which maps global function names to information about the global f...
@ CONTROL_BLOCK_ID
The control block, which contains all of the information that needs to be validated prior to committi...
@ IDENTIFIER_BLOCK_ID
The identifier data block, which maps identifier strings to IDs.
@ GLOBAL_VARIABLE_BLOCK_ID
The global variables data block, which maps global variable names to information about the global var...
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
uint32_t SelectorID
An ID number that refers to an ObjC selector in an AST file.
unsigned ComputeHash(Selector Sel)
uint64_t IdentifierID
An ID number that refers to an identifier in an AST file.
The JSON file list parser is used to communicate input to InstallAPI.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
A stored Objective-C or C++ context, represented by the ID of its parent context, the kind of this co...
A temporary reference to an Objective-C selector, suitable for referencing selector data on the stack...
llvm::ArrayRef< llvm::StringRef > Identifiers
A stored Objective-C or C++ declaration, represented by the ID of its parent context,...
A stored Objective-C selector.