clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
238 lines
7.0 KiB
C++
238 lines
7.0 KiB
C++
//===- llvm/TextAPI/Record.h - TAPI Record ----------------------*- 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
|
|
/// \brief Implements the TAPI Record Types.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TEXTAPI_RECORD_H
|
|
#define LLVM_TEXTAPI_RECORD_H
|
|
|
|
#include "llvm/ADT/MapVector.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/TextAPI/Symbol.h"
|
|
#include <string>
|
|
|
|
namespace llvm {
|
|
namespace MachO {
|
|
|
|
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
|
|
|
|
class RecordsSlice;
|
|
|
|
// Defines lightweight source location for records.
|
|
struct RecordLoc {
|
|
RecordLoc() = default;
|
|
RecordLoc(std::string File, unsigned Line)
|
|
: File(std::move(File)), Line(Line) {}
|
|
|
|
/// Whether there is source location tied to the RecordLoc object.
|
|
bool isValid() const { return !File.empty(); }
|
|
|
|
bool operator==(const RecordLoc &O) const {
|
|
return std::tie(File, Line) == std::tie(O.File, O.Line);
|
|
}
|
|
|
|
const std::string File;
|
|
const unsigned Line = 0;
|
|
};
|
|
|
|
// Defines a list of linkage types.
|
|
enum class RecordLinkage : uint8_t {
|
|
// Unknown linkage.
|
|
Unknown = 0,
|
|
|
|
// Local, hidden or private extern linkage.
|
|
Internal = 1,
|
|
|
|
// Undefined linkage, it represents usage of external interface.
|
|
Undefined = 2,
|
|
|
|
// Re-exported linkage, record is defined in external interface.
|
|
Rexported = 3,
|
|
|
|
// Exported linkage.
|
|
Exported = 4,
|
|
};
|
|
|
|
/// Define Record. They represent API's in binaries that could be linkable
|
|
/// symbols.
|
|
class Record {
|
|
public:
|
|
Record() = default;
|
|
Record(StringRef Name, RecordLinkage Linkage, SymbolFlags Flags)
|
|
: Name(Name), Linkage(Linkage), Flags(mergeFlags(Flags, Linkage)),
|
|
Verified(false) {}
|
|
|
|
bool isWeakDefined() const {
|
|
return (Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined;
|
|
}
|
|
|
|
bool isWeakReferenced() const {
|
|
return (Flags & SymbolFlags::WeakReferenced) == SymbolFlags::WeakReferenced;
|
|
}
|
|
|
|
bool isThreadLocalValue() const {
|
|
return (Flags & SymbolFlags::ThreadLocalValue) ==
|
|
SymbolFlags::ThreadLocalValue;
|
|
}
|
|
|
|
bool isData() const {
|
|
return (Flags & SymbolFlags::Data) == SymbolFlags::Data;
|
|
}
|
|
|
|
bool isText() const {
|
|
return (Flags & SymbolFlags::Text) == SymbolFlags::Text;
|
|
}
|
|
|
|
bool isInternal() const { return Linkage == RecordLinkage::Internal; }
|
|
bool isUndefined() const { return Linkage == RecordLinkage::Undefined; }
|
|
bool isExported() const { return Linkage >= RecordLinkage::Rexported; }
|
|
bool isRexported() const { return Linkage == RecordLinkage::Rexported; }
|
|
|
|
bool isVerified() const { return Verified; }
|
|
void setVerify(bool V = true) { Verified = V; }
|
|
|
|
StringRef getName() const { return Name; }
|
|
SymbolFlags getFlags() const { return Flags; }
|
|
|
|
private:
|
|
SymbolFlags mergeFlags(SymbolFlags Flags, RecordLinkage Linkage);
|
|
|
|
protected:
|
|
StringRef Name;
|
|
RecordLinkage Linkage;
|
|
SymbolFlags Flags;
|
|
bool Verified;
|
|
|
|
friend class RecordsSlice;
|
|
};
|
|
|
|
// Defines broadly non-objc records, categorized as variables or functions.
|
|
class GlobalRecord : public Record {
|
|
public:
|
|
enum class Kind : uint8_t {
|
|
Unknown = 0,
|
|
Variable = 1,
|
|
Function = 2,
|
|
};
|
|
|
|
GlobalRecord(StringRef Name, RecordLinkage Linkage, SymbolFlags Flags,
|
|
Kind GV, bool Inlined)
|
|
: Record({Name, Linkage, Flags}), GV(GV), Inlined(Inlined) {}
|
|
|
|
bool isFunction() const { return GV == Kind::Function; }
|
|
bool isVariable() const { return GV == Kind::Variable; }
|
|
void setKind(const Kind &V) {
|
|
if (GV == Kind::Unknown)
|
|
GV = V;
|
|
}
|
|
bool isInlined() const { return Inlined; }
|
|
|
|
private:
|
|
Kind GV;
|
|
bool Inlined = false;
|
|
};
|
|
|
|
// Define Objective-C instance variable records.
|
|
class ObjCIVarRecord : public Record {
|
|
public:
|
|
ObjCIVarRecord(StringRef Name, RecordLinkage Linkage)
|
|
: Record({Name, Linkage, SymbolFlags::Data}) {}
|
|
|
|
static std::string createScopedName(StringRef SuperClass, StringRef IVar) {
|
|
return (SuperClass + "." + IVar).str();
|
|
}
|
|
};
|
|
|
|
template <typename V, typename K = StringRef,
|
|
typename std::enable_if<std::is_base_of<Record, V>::value>::type * =
|
|
nullptr>
|
|
using RecordMap = llvm::MapVector<K, std::unique_ptr<V>>;
|
|
|
|
// Defines Objective-C record types that have assigned methods, properties,
|
|
// instance variable (ivars) and protocols.
|
|
class ObjCContainerRecord : public Record {
|
|
public:
|
|
ObjCContainerRecord(StringRef Name, RecordLinkage Linkage)
|
|
: Record({Name, Linkage, SymbolFlags::Data}) {}
|
|
|
|
ObjCIVarRecord *addObjCIVar(StringRef IVar, RecordLinkage Linkage);
|
|
ObjCIVarRecord *findObjCIVar(StringRef IVar) const;
|
|
std::vector<ObjCIVarRecord *> getObjCIVars() const;
|
|
RecordLinkage getLinkage() const { return Linkage; }
|
|
|
|
private:
|
|
RecordMap<ObjCIVarRecord> IVars;
|
|
};
|
|
|
|
// Define Objective-C category types. They don't generate linkable symbols, but
|
|
// they have assigned ivars that do.
|
|
class ObjCCategoryRecord : public ObjCContainerRecord {
|
|
public:
|
|
ObjCCategoryRecord(StringRef ClassToExtend, StringRef Name)
|
|
: ObjCContainerRecord(Name, RecordLinkage::Unknown),
|
|
ClassToExtend(ClassToExtend) {}
|
|
|
|
StringRef getSuperClassName() const { return ClassToExtend; }
|
|
|
|
private:
|
|
StringRef ClassToExtend;
|
|
};
|
|
|
|
// Define Objective-C Interfaces or class types.
|
|
class ObjCInterfaceRecord : public ObjCContainerRecord {
|
|
public:
|
|
ObjCInterfaceRecord(StringRef Name, RecordLinkage Linkage,
|
|
ObjCIFSymbolKind SymType)
|
|
: ObjCContainerRecord(Name, Linkage) {
|
|
updateLinkageForSymbols(SymType, Linkage);
|
|
}
|
|
|
|
bool hasExceptionAttribute() const {
|
|
return Linkages.EHType != RecordLinkage::Unknown;
|
|
}
|
|
bool isCompleteInterface() const {
|
|
return Linkages.Class >= RecordLinkage::Rexported &&
|
|
Linkages.MetaClass >= RecordLinkage::Rexported;
|
|
}
|
|
bool isExportedSymbol(ObjCIFSymbolKind CurrType) const {
|
|
return getLinkageForSymbol(CurrType) >= RecordLinkage::Rexported;
|
|
}
|
|
|
|
RecordLinkage getLinkageForSymbol(ObjCIFSymbolKind CurrType) const;
|
|
void updateLinkageForSymbols(ObjCIFSymbolKind SymType, RecordLinkage Link);
|
|
|
|
bool addObjCCategory(ObjCCategoryRecord *Record);
|
|
std::vector<ObjCCategoryRecord *> getObjCCategories() const;
|
|
|
|
private:
|
|
/// Linkage level for each symbol represented in ObjCInterfaceRecord.
|
|
struct Linkages {
|
|
RecordLinkage Class = RecordLinkage::Unknown;
|
|
RecordLinkage MetaClass = RecordLinkage::Unknown;
|
|
RecordLinkage EHType = RecordLinkage::Unknown;
|
|
bool operator==(const Linkages &other) const {
|
|
return std::tie(Class, MetaClass, EHType) ==
|
|
std::tie(other.Class, other.MetaClass, other.EHType);
|
|
}
|
|
bool operator!=(const Linkages &other) const { return !(*this == other); }
|
|
};
|
|
Linkages Linkages;
|
|
|
|
// Non-owning containers of categories that extend the class.
|
|
llvm::MapVector<StringRef, ObjCCategoryRecord *> Categories;
|
|
};
|
|
|
|
} // end namespace MachO.
|
|
} // end namespace llvm.
|
|
|
|
#endif // LLVM_TEXTAPI_RECORD_H
|