forked from OSchip/llvm-project
[clang][ExtractAPI] Record availability information on all platforms
Currently ExtractAPI only emits availability information for the current platform. This makes it easy for clients to get all availability information for a given symbol in one invocation as opposed to having to invoke clang once per-platform and then merge the symbol-graphs. Differential Revision: https://reviews.llvm.org/D130918
This commit is contained in:
parent
89aaae57ea
commit
57c9780d60
|
@ -58,7 +58,7 @@ struct APIRecord {
|
|||
StringRef USR;
|
||||
StringRef Name;
|
||||
PresumedLoc Location;
|
||||
AvailabilityInfo Availability;
|
||||
AvailabilitySet Availabilities;
|
||||
LinkageInfo Linkage;
|
||||
|
||||
/// Documentation comment lines attached to this symbol declaration.
|
||||
|
@ -102,12 +102,13 @@ public:
|
|||
APIRecord() = delete;
|
||||
|
||||
APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Location, const AvailabilityInfo &Availability,
|
||||
PresumedLoc Location, AvailabilitySet Availabilities,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading)
|
||||
: USR(USR), Name(Name), Location(Location), Availability(Availability),
|
||||
Linkage(Linkage), Comment(Comment), Declaration(Declaration),
|
||||
SubHeading(SubHeading), Kind(Kind) {}
|
||||
: USR(USR), Name(Name), Location(Location),
|
||||
Availabilities(std::move(Availabilities)), Linkage(Linkage),
|
||||
Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
|
||||
Kind(Kind) {}
|
||||
|
||||
// Pure virtual destructor to make APIRecord abstract
|
||||
virtual ~APIRecord() = 0;
|
||||
|
@ -118,13 +119,13 @@ struct GlobalFunctionRecord : APIRecord {
|
|||
FunctionSignature Signature;
|
||||
|
||||
GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature)
|
||||
: APIRecord(RK_GlobalFunction, USR, Name, Loc, Availability, Linkage,
|
||||
Comment, Declaration, SubHeading),
|
||||
: APIRecord(RK_GlobalFunction, USR, Name, Loc, std::move(Availabilities),
|
||||
Linkage, Comment, Declaration, SubHeading),
|
||||
Signature(Signature) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
|
@ -138,12 +139,12 @@ private:
|
|||
/// This holds information associated with global functions.
|
||||
struct GlobalVariableRecord : APIRecord {
|
||||
GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading)
|
||||
: APIRecord(RK_GlobalVariable, USR, Name, Loc, Availability, Linkage,
|
||||
Comment, Declaration, SubHeading) {}
|
||||
: APIRecord(RK_GlobalVariable, USR, Name, Loc, std::move(Availabilities),
|
||||
Linkage, Comment, Declaration, SubHeading) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_GlobalVariable;
|
||||
|
@ -156,11 +157,10 @@ private:
|
|||
/// This holds information associated with enum constants.
|
||||
struct EnumConstantRecord : APIRecord {
|
||||
EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading)
|
||||
: APIRecord(RK_EnumConstant, USR, Name, Loc, Availability,
|
||||
: APIRecord(RK_EnumConstant, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
|
@ -176,10 +176,10 @@ struct EnumRecord : APIRecord {
|
|||
SmallVector<std::unique_ptr<EnumConstantRecord>> Constants;
|
||||
|
||||
EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading)
|
||||
: APIRecord(RK_Enum, USR, Name, Loc, Availability, LinkageInfo::none(),
|
||||
Comment, Declaration, SubHeading) {}
|
||||
: APIRecord(RK_Enum, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_Enum;
|
||||
|
@ -192,10 +192,10 @@ private:
|
|||
/// This holds information associated with struct fields.
|
||||
struct StructFieldRecord : APIRecord {
|
||||
StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading)
|
||||
: APIRecord(RK_StructField, USR, Name, Loc, Availability,
|
||||
: APIRecord(RK_StructField, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
|
@ -211,11 +211,11 @@ struct StructRecord : APIRecord {
|
|||
SmallVector<std::unique_ptr<StructFieldRecord>> Fields;
|
||||
|
||||
StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading)
|
||||
: APIRecord(RK_Struct, USR, Name, Loc, Availability, LinkageInfo::none(),
|
||||
Comment, Declaration, SubHeading) {}
|
||||
: APIRecord(RK_Struct, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_Struct;
|
||||
|
@ -241,13 +241,12 @@ struct ObjCPropertyRecord : APIRecord {
|
|||
bool IsOptional;
|
||||
|
||||
ObjCPropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, AttributeKind Attributes,
|
||||
StringRef GetterName, StringRef SetterName,
|
||||
bool IsOptional)
|
||||
: APIRecord(RK_ObjCProperty, USR, Name, Loc, Availability,
|
||||
: APIRecord(RK_ObjCProperty, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading),
|
||||
Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
|
||||
IsOptional(IsOptional) {}
|
||||
|
@ -270,12 +269,12 @@ struct ObjCInstanceVariableRecord : APIRecord {
|
|||
AccessControl Access;
|
||||
|
||||
ObjCInstanceVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
AccessControl Access)
|
||||
: APIRecord(RK_ObjCIvar, USR, Name, Loc, Availability,
|
||||
: APIRecord(RK_ObjCIvar, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading),
|
||||
Access(Access) {}
|
||||
|
||||
|
@ -293,11 +292,11 @@ struct ObjCMethodRecord : APIRecord {
|
|||
bool IsInstanceMethod;
|
||||
|
||||
ObjCMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsInstanceMethod)
|
||||
: APIRecord(RK_ObjCMethod, USR, Name, Loc, Availability,
|
||||
: APIRecord(RK_ObjCMethod, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo::none(), Comment, Declaration, SubHeading),
|
||||
Signature(Signature), IsInstanceMethod(IsInstanceMethod) {}
|
||||
|
||||
|
@ -341,12 +340,12 @@ struct ObjCContainerRecord : APIRecord {
|
|||
ObjCContainerRecord() = delete;
|
||||
|
||||
ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
|
||||
PresumedLoc Loc, const AvailabilityInfo &Availability,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading)
|
||||
: APIRecord(Kind, USR, Name, Loc, Availability, Linkage, Comment,
|
||||
Declaration, SubHeading) {}
|
||||
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), Linkage,
|
||||
Comment, Declaration, SubHeading) {}
|
||||
|
||||
virtual ~ObjCContainerRecord() = 0;
|
||||
};
|
||||
|
@ -356,13 +355,12 @@ struct ObjCCategoryRecord : ObjCContainerRecord {
|
|||
SymbolReference Interface;
|
||||
|
||||
ObjCCategoryRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference Interface)
|
||||
: ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc, Availability,
|
||||
LinkageInfo::none(), Comment, Declaration,
|
||||
SubHeading),
|
||||
: ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc,
|
||||
std::move(Availabilities), LinkageInfo::none(),
|
||||
Comment, Declaration, SubHeading),
|
||||
Interface(Interface) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
|
@ -380,13 +378,14 @@ struct ObjCInterfaceRecord : ObjCContainerRecord {
|
|||
SmallVector<ObjCCategoryRecord *> Categories;
|
||||
|
||||
ObjCInterfaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
SymbolReference SuperClass)
|
||||
: ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc, Availability,
|
||||
Linkage, Comment, Declaration, SubHeading),
|
||||
: ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc,
|
||||
std::move(Availabilities), Linkage, Comment,
|
||||
Declaration, SubHeading),
|
||||
SuperClass(SuperClass) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
|
@ -400,13 +399,12 @@ private:
|
|||
/// This holds information associated with Objective-C protocols.
|
||||
struct ObjCProtocolRecord : ObjCContainerRecord {
|
||||
ObjCProtocolRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading)
|
||||
: ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc, Availability,
|
||||
LinkageInfo::none(), Comment, Declaration,
|
||||
SubHeading) {}
|
||||
: ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc,
|
||||
std::move(Availabilities), LinkageInfo::none(),
|
||||
Comment, Declaration, SubHeading) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
return Record->getKind() == RK_ObjCProtocol;
|
||||
|
@ -421,7 +419,7 @@ struct MacroDefinitionRecord : APIRecord {
|
|||
MacroDefinitionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading)
|
||||
: APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilityInfo(),
|
||||
: APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilitySet(),
|
||||
LinkageInfo(), {}, Declaration, SubHeading) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
|
@ -441,11 +439,11 @@ struct TypedefRecord : APIRecord {
|
|||
SymbolReference UnderlyingType;
|
||||
|
||||
TypedefRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, const DocComment &Comment,
|
||||
AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference UnderlyingType)
|
||||
: APIRecord(RK_Typedef, USR, Name, Loc, Availability, LinkageInfo(),
|
||||
Comment, Declaration, SubHeading),
|
||||
: APIRecord(RK_Typedef, USR, Name, Loc, std::move(Availabilities),
|
||||
LinkageInfo(), Comment, Declaration, SubHeading),
|
||||
UnderlyingType(UnderlyingType) {}
|
||||
|
||||
static bool classof(const APIRecord *Record) {
|
||||
|
@ -478,7 +476,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
GlobalVariableRecord *
|
||||
addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading);
|
||||
|
||||
|
@ -490,7 +488,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
GlobalFunctionRecord *
|
||||
addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature);
|
||||
|
@ -503,7 +501,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
EnumConstantRecord *addEnumConstant(EnumRecord *Enum, StringRef Name,
|
||||
StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading);
|
||||
|
@ -515,8 +513,7 @@ public:
|
|||
/// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
EnumRecord *addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading);
|
||||
|
||||
|
@ -528,7 +525,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
StructFieldRecord *addStructField(StructRecord *Struct, StringRef Name,
|
||||
StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading);
|
||||
|
@ -540,7 +537,7 @@ public:
|
|||
/// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
StructRecord *addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading);
|
||||
|
@ -553,8 +550,8 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCCategoryRecord *
|
||||
addObjCCategory(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
AvailabilitySet Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference Interface);
|
||||
|
||||
/// Create and add an Objective-C interface record into the API set.
|
||||
|
@ -565,7 +562,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCInterfaceRecord *
|
||||
addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
||||
AvailabilitySet Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference SuperClass);
|
||||
|
||||
|
@ -577,7 +574,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCMethodRecord *
|
||||
addObjCMethod(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, const AvailabilityInfo &Availability,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsInstanceMethod);
|
||||
|
@ -590,7 +587,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCPropertyRecord *
|
||||
addObjCProperty(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, const AvailabilityInfo &Availability,
|
||||
PresumedLoc Loc, AvailabilitySet Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
ObjCPropertyRecord::AttributeKind Attributes,
|
||||
|
@ -604,9 +601,8 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCInstanceVariableRecord *addObjCInstanceVariable(
|
||||
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, const AvailabilityInfo &Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
ObjCInstanceVariableRecord::AccessControl Access);
|
||||
|
||||
/// Create and add an Objective-C protocol record into the API set.
|
||||
|
@ -617,7 +613,7 @@ public:
|
|||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
ObjCProtocolRecord *addObjCProtocol(StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading);
|
||||
|
@ -641,7 +637,7 @@ public:
|
|||
/// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
|
||||
/// to generate the USR for \c D and keep it alive in APISet.
|
||||
TypedefRecord *addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
|
||||
#define LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/VersionTuple.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -24,20 +26,38 @@ using llvm::VersionTuple;
|
|||
namespace clang {
|
||||
namespace extractapi {
|
||||
|
||||
/// Stores availability attributes of a symbol.
|
||||
/// Stores availability attributes of a symbol in a given domain.
|
||||
struct AvailabilityInfo {
|
||||
/// The domain for which this availability info item applies
|
||||
std::string Domain;
|
||||
VersionTuple Introduced;
|
||||
VersionTuple Deprecated;
|
||||
VersionTuple Obsoleted;
|
||||
bool Unavailable{false};
|
||||
bool UnconditionallyDeprecated{false};
|
||||
bool UnconditionallyUnavailable{false};
|
||||
|
||||
/// Determine if this AvailabilityInfo represents the default availability.
|
||||
bool isDefault() const { return *this == AvailabilityInfo(); }
|
||||
AvailabilityInfo() = default;
|
||||
|
||||
/// Check if the symbol is unavailable.
|
||||
bool isUnavailable() const { return Unavailable; }
|
||||
AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
|
||||
VersionTuple O)
|
||||
: Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O) {}
|
||||
};
|
||||
|
||||
class AvailabilitySet {
|
||||
private:
|
||||
using AvailabilityList = llvm::SmallVector<AvailabilityInfo, 4>;
|
||||
AvailabilityList Availabilities;
|
||||
|
||||
bool UnconditionallyDeprecated = false;
|
||||
bool UnconditionallyUnavailable = false;
|
||||
|
||||
public:
|
||||
AvailabilitySet(const Decl *Decl);
|
||||
AvailabilitySet() = default;
|
||||
|
||||
AvailabilityList::const_iterator begin() const {
|
||||
return Availabilities.begin();
|
||||
}
|
||||
|
||||
AvailabilityList::const_iterator end() const { return Availabilities.end(); }
|
||||
|
||||
/// Check if the symbol is unconditionally deprecated.
|
||||
///
|
||||
|
@ -51,27 +71,10 @@ struct AvailabilityInfo {
|
|||
return UnconditionallyUnavailable;
|
||||
}
|
||||
|
||||
AvailabilityInfo() = default;
|
||||
|
||||
AvailabilityInfo(VersionTuple I, VersionTuple D, VersionTuple O, bool U,
|
||||
bool UD, bool UU)
|
||||
: Introduced(I), Deprecated(D), Obsoleted(O), Unavailable(U),
|
||||
UnconditionallyDeprecated(UD), UnconditionallyUnavailable(UU) {}
|
||||
|
||||
friend bool operator==(const AvailabilityInfo &Lhs,
|
||||
const AvailabilityInfo &Rhs);
|
||||
/// Determine if this AvailabilitySet represents default availability.
|
||||
bool isDefault() const { return Availabilities.empty(); }
|
||||
};
|
||||
|
||||
inline bool operator==(const AvailabilityInfo &Lhs,
|
||||
const AvailabilityInfo &Rhs) {
|
||||
return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted,
|
||||
Lhs.Unavailable, Lhs.UnconditionallyDeprecated,
|
||||
Lhs.UnconditionallyUnavailable) ==
|
||||
std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted,
|
||||
Rhs.Unavailable, Rhs.UnconditionallyDeprecated,
|
||||
Rhs.UnconditionallyUnavailable);
|
||||
}
|
||||
|
||||
} // namespace extractapi
|
||||
} // namespace clang
|
||||
|
||||
|
|
|
@ -43,68 +43,77 @@ RecordTy *addTopLevelRecord(APISet::RecordMap<RecordTy> &RecordMap,
|
|||
|
||||
GlobalVariableRecord *
|
||||
APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Fragments,
|
||||
DeclarationFragments SubHeading) {
|
||||
return addTopLevelRecord(GlobalVariables, USR, Name, Loc, Availability,
|
||||
Linkage, Comment, Fragments, SubHeading);
|
||||
return addTopLevelRecord(GlobalVariables, USR, Name, Loc,
|
||||
std::move(Availabilities), Linkage, Comment,
|
||||
Fragments, SubHeading);
|
||||
}
|
||||
|
||||
GlobalFunctionRecord *APISet::addGlobalFunction(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Fragments,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature) {
|
||||
return addTopLevelRecord(GlobalFunctions, USR, Name, Loc, Availability,
|
||||
Linkage, Comment, Fragments, SubHeading, Signature);
|
||||
return addTopLevelRecord(GlobalFunctions, USR, Name, Loc,
|
||||
std::move(Availabilities), 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) {
|
||||
EnumConstantRecord *APISet::addEnumConstant(EnumRecord *Enum, StringRef Name,
|
||||
StringRef USR, PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading) {
|
||||
auto Record = std::make_unique<EnumConstantRecord>(
|
||||
USR, Name, Loc, Availability, Comment, Declaration, SubHeading);
|
||||
USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
|
||||
SubHeading);
|
||||
return Enum->Constants.emplace_back(std::move(Record)).get();
|
||||
}
|
||||
|
||||
EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading) {
|
||||
return addTopLevelRecord(Enums, USR, Name, Loc, Availability, Comment,
|
||||
Declaration, SubHeading);
|
||||
return addTopLevelRecord(Enums, USR, Name, Loc, std::move(Availabilities),
|
||||
Comment, Declaration, SubHeading);
|
||||
}
|
||||
|
||||
StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name,
|
||||
StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading) {
|
||||
auto Record = std::make_unique<StructFieldRecord>(
|
||||
USR, Name, Loc, Availability, Comment, Declaration, SubHeading);
|
||||
USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
|
||||
SubHeading);
|
||||
return Struct->Fields.emplace_back(std::move(Record)).get();
|
||||
}
|
||||
|
||||
StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading) {
|
||||
return addTopLevelRecord(Structs, USR, Name, Loc, Availability, Comment,
|
||||
Declaration, SubHeading);
|
||||
return addTopLevelRecord(Structs, USR, Name, Loc, std::move(Availabilities),
|
||||
Comment, Declaration, SubHeading);
|
||||
}
|
||||
|
||||
ObjCCategoryRecord *APISet::addObjCCategory(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
SymbolReference Interface) {
|
||||
ObjCCategoryRecord *APISet::addObjCCategory(StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
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);
|
||||
auto *Record = addTopLevelRecord(ObjCCategories, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment,
|
||||
Declaration, SubHeading, Interface);
|
||||
|
||||
// If this category is extending a known interface, associate it with the
|
||||
// ObjCInterfaceRecord.
|
||||
|
@ -117,56 +126,57 @@ ObjCCategoryRecord *APISet::addObjCCategory(
|
|||
|
||||
ObjCInterfaceRecord *APISet::addObjCInterface(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability, LinkageInfo Linkage,
|
||||
AvailabilitySet Availabilities, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference SuperClass) {
|
||||
return addTopLevelRecord(ObjCInterfaces, USR, Name, Loc, Availability,
|
||||
Linkage, Comment, Declaration, SubHeading,
|
||||
SuperClass);
|
||||
return addTopLevelRecord(ObjCInterfaces, USR, Name, Loc,
|
||||
std::move(Availabilities), 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) {
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities, 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);
|
||||
USR, Name, Loc, std::move(Availabilities), 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,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities, 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);
|
||||
USR, Name, Loc, std::move(Availabilities), 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,
|
||||
PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
ObjCInstanceVariableRecord::AccessControl Access) {
|
||||
auto Record = std::make_unique<ObjCInstanceVariableRecord>(
|
||||
USR, Name, Loc, Availability, Comment, Declaration, SubHeading, Access);
|
||||
USR, Name, Loc, std::move(Availabilities), 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);
|
||||
ObjCProtocolRecord *APISet::addObjCProtocol(StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading) {
|
||||
return addTopLevelRecord(ObjCProtocols, USR, Name, Loc,
|
||||
std::move(Availabilities), Comment, Declaration,
|
||||
SubHeading);
|
||||
}
|
||||
|
||||
MacroDefinitionRecord *
|
||||
|
@ -178,13 +188,13 @@ APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc,
|
|||
|
||||
TypedefRecord *APISet::addTypedef(StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc,
|
||||
const AvailabilityInfo &Availability,
|
||||
AvailabilitySet Availabilities,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
SymbolReference UnderlyingType) {
|
||||
return addTopLevelRecord(Typedefs, USR, Name, Loc, Availability, Comment,
|
||||
Declaration, SubHeading, UnderlyingType);
|
||||
return addTopLevelRecord(Typedefs, USR, Name, Loc, std::move(Availabilities),
|
||||
Comment, Declaration, SubHeading, UnderlyingType);
|
||||
}
|
||||
|
||||
StringRef APISet::recordUSR(const Decl *D) {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#include "clang/ExtractAPI/AvailabilityInfo.h"
|
||||
#include "clang/AST/Attr.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace extractapi;
|
||||
|
||||
AvailabilitySet::AvailabilitySet(const Decl *Decl) {
|
||||
// Collect availability attributes from all redeclrations.
|
||||
for (const auto *RD : Decl->redecls()) {
|
||||
if (const auto *A = RD->getAttr<UnavailableAttr>()) {
|
||||
if (!A->isImplicit()) {
|
||||
this->Availabilities.clear();
|
||||
UnconditionallyUnavailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto *A = RD->getAttr<DeprecatedAttr>()) {
|
||||
if (!A->isImplicit()) {
|
||||
this->Availabilities.clear();
|
||||
UnconditionallyDeprecated = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto *Attr : RD->specific_attrs<AvailabilityAttr>()) {
|
||||
StringRef Domain = Attr->getPlatform()->getName();
|
||||
auto *Availability =
|
||||
llvm::find_if(Availabilities, [Domain](const AvailabilityInfo &Info) {
|
||||
return Domain.equals(Info.Domain);
|
||||
});
|
||||
if (Availability != Availabilities.end()) {
|
||||
// Get the highest introduced version for all redeclarations.
|
||||
if (Availability->Introduced < Attr->getIntroduced())
|
||||
Availability->Introduced = Attr->getIntroduced();
|
||||
|
||||
// Get the lowest deprecated version for all redeclarations.
|
||||
if (Availability->Deprecated > Attr->getDeprecated())
|
||||
Availability->Deprecated = Attr->getDeprecated();
|
||||
|
||||
// Get the lowest obsoleted version for all redeclarations.
|
||||
if (Availability->Obsoleted > Attr->getObsoleted())
|
||||
Availability->Obsoleted = Attr->getObsoleted();
|
||||
} else {
|
||||
Availabilities.emplace_back(Domain, Attr->getIntroduced(),
|
||||
Attr->getDeprecated(),
|
||||
Attr->getObsoleted());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
|
||||
add_clang_library(clangExtractAPI
|
||||
API.cpp
|
||||
AvailabilityInfo.cpp
|
||||
ExtractAPIConsumer.cpp
|
||||
DeclarationFragments.cpp
|
||||
Serialization/SerializerBase.cpp
|
||||
|
|
|
@ -264,7 +264,6 @@ public:
|
|||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
LinkageInfo Linkage = Decl->getLinkageAndVisibility();
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
|
@ -278,7 +277,7 @@ public:
|
|||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
// Add the global variable record to the API set.
|
||||
API.addGlobalVar(Name, USR, Loc, Availability, Linkage, Comment,
|
||||
API.addGlobalVar(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
|
||||
Declaration, SubHeading);
|
||||
return true;
|
||||
}
|
||||
|
@ -325,7 +324,6 @@ public:
|
|||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
LinkageInfo Linkage = Decl->getLinkageAndVisibility();
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
|
@ -341,8 +339,8 @@ public:
|
|||
DeclarationFragmentsBuilder::getFunctionSignature(Decl);
|
||||
|
||||
// Add the function record to the API set.
|
||||
API.addGlobalFunction(Name, USR, Loc, Availability, Linkage, Comment,
|
||||
Declaration, SubHeading, Signature);
|
||||
API.addGlobalFunction(Name, USR, Loc, AvailabilitySet(Decl), Linkage,
|
||||
Comment, Declaration, SubHeading, Signature);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -366,7 +364,6 @@ public:
|
|||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -379,8 +376,8 @@ public:
|
|||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
EnumRecord *EnumRecord =
|
||||
API.addEnum(API.copyString(Name), USR, Loc, Availability, Comment,
|
||||
Declaration, SubHeading);
|
||||
API.addEnum(API.copyString(Name), USR, Loc, AvailabilitySet(Decl),
|
||||
Comment, Declaration, SubHeading);
|
||||
|
||||
// Now collect information about the enumerators in this enum.
|
||||
recordEnumConstants(EnumRecord, Decl->enumerators());
|
||||
|
@ -407,7 +404,6 @@ public:
|
|||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -419,8 +415,9 @@ public:
|
|||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
StructRecord *StructRecord = API.addStruct(
|
||||
Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
|
||||
StructRecord *StructRecord =
|
||||
API.addStruct(Name, USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
Declaration, SubHeading);
|
||||
|
||||
// Now collect information about the fields in this struct.
|
||||
recordStructFields(StructRecord, Decl->fields());
|
||||
|
@ -441,7 +438,6 @@ public:
|
|||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
LinkageInfo Linkage = Decl->getLinkageAndVisibility();
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
|
@ -462,8 +458,8 @@ public:
|
|||
}
|
||||
|
||||
ObjCInterfaceRecord *ObjCInterfaceRecord =
|
||||
API.addObjCInterface(Name, USR, Loc, Availability, Linkage, Comment,
|
||||
Declaration, SubHeading, SuperClass);
|
||||
API.addObjCInterface(Name, USR, Loc, AvailabilitySet(Decl), Linkage,
|
||||
Comment, Declaration, SubHeading, SuperClass);
|
||||
|
||||
// Record all methods (selectors). This doesn't include automatically
|
||||
// synthesized property methods.
|
||||
|
@ -488,7 +484,6 @@ public:
|
|||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -500,8 +495,9 @@ public:
|
|||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
ObjCProtocolRecord *ObjCProtocolRecord = API.addObjCProtocol(
|
||||
Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
|
||||
ObjCProtocolRecord *ObjCProtocolRecord =
|
||||
API.addObjCProtocol(Name, USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
Declaration, SubHeading);
|
||||
|
||||
recordObjCMethods(ObjCProtocolRecord, Decl->methods());
|
||||
recordObjCProperties(ObjCProtocolRecord, Decl->properties());
|
||||
|
@ -524,7 +520,6 @@ public:
|
|||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
StringRef Name = Decl->getName();
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
StringRef USR = API.recordUSR(Decl);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
|
@ -536,7 +531,7 @@ public:
|
|||
TypedefUnderlyingTypeResolver(Context).getSymbolReferenceForType(Type,
|
||||
API);
|
||||
|
||||
API.addTypedef(Name, USR, Loc, Availability, Comment,
|
||||
API.addTypedef(Name, USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
DeclarationFragmentsBuilder::getFragmentsForTypedef(Decl),
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl), SymRef);
|
||||
|
||||
|
@ -549,7 +544,6 @@ public:
|
|||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Decl);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -565,8 +559,8 @@ public:
|
|||
API.recordUSR(InterfaceDecl));
|
||||
|
||||
ObjCCategoryRecord *ObjCCategoryRecord =
|
||||
API.addObjCCategory(Name, USR, Loc, Availability, Comment, Declaration,
|
||||
SubHeading, Interface);
|
||||
API.addObjCCategory(Name, USR, Loc, AvailabilitySet(Decl), Comment,
|
||||
Declaration, SubHeading, Interface);
|
||||
|
||||
recordObjCMethods(ObjCCategoryRecord, Decl->methods());
|
||||
recordObjCProperties(ObjCCategoryRecord, Decl->properties());
|
||||
|
@ -577,37 +571,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
/// Get availability information of the declaration \p D.
|
||||
AvailabilityInfo getAvailability(const Decl *D) const {
|
||||
StringRef PlatformName = Context.getTargetInfo().getPlatformName();
|
||||
|
||||
AvailabilityInfo Availability;
|
||||
// Collect availability attributes from all redeclarations.
|
||||
for (const auto *RD : D->redecls()) {
|
||||
for (const auto *A : RD->specific_attrs<AvailabilityAttr>()) {
|
||||
if (A->getPlatform()->getName() != PlatformName)
|
||||
continue;
|
||||
Availability = AvailabilityInfo(A->getIntroduced(), A->getDeprecated(),
|
||||
A->getObsoleted(), A->getUnavailable(),
|
||||
/* UnconditionallyDeprecated */ false,
|
||||
/* UnconditionallyUnavailable */ false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (const auto *A = RD->getAttr<UnavailableAttr>())
|
||||
if (!A->isImplicit()) {
|
||||
Availability.Unavailable = true;
|
||||
Availability.UnconditionallyUnavailable = true;
|
||||
}
|
||||
|
||||
if (const auto *A = RD->getAttr<DeprecatedAttr>())
|
||||
if (!A->isImplicit())
|
||||
Availability.UnconditionallyDeprecated = true;
|
||||
}
|
||||
|
||||
return Availability;
|
||||
}
|
||||
|
||||
/// Collect API information for the enum constants and associate with the
|
||||
/// parent enum.
|
||||
void recordEnumConstants(EnumRecord *EnumRecord,
|
||||
|
@ -618,7 +581,6 @@ private:
|
|||
StringRef USR = API.recordUSR(Constant);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Constant->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Constant);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Constant))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -630,8 +592,8 @@ private:
|
|||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Constant);
|
||||
|
||||
API.addEnumConstant(EnumRecord, Name, USR, Loc, Availability, Comment,
|
||||
Declaration, SubHeading);
|
||||
API.addEnumConstant(EnumRecord, Name, USR, Loc, AvailabilitySet(Constant),
|
||||
Comment, Declaration, SubHeading);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -645,7 +607,6 @@ private:
|
|||
StringRef USR = API.recordUSR(Field);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Field->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Field);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Field))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -657,8 +618,8 @@ private:
|
|||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Field);
|
||||
|
||||
API.addStructField(StructRecord, Name, USR, Loc, Availability, Comment,
|
||||
Declaration, SubHeading);
|
||||
API.addStructField(StructRecord, Name, USR, Loc, AvailabilitySet(Field),
|
||||
Comment, Declaration, SubHeading);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,7 +636,6 @@ private:
|
|||
StringRef USR = API.recordUSR(Method);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Method->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Method);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Method))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -689,8 +649,8 @@ private:
|
|||
FunctionSignature Signature =
|
||||
DeclarationFragmentsBuilder::getFunctionSignature(Method);
|
||||
|
||||
API.addObjCMethod(Container, Name, USR, Loc, Availability, Comment,
|
||||
Declaration, SubHeading, Signature,
|
||||
API.addObjCMethod(Container, Name, USR, Loc, AvailabilitySet(Method),
|
||||
Comment, Declaration, SubHeading, Signature,
|
||||
Method->isInstanceMethod());
|
||||
}
|
||||
}
|
||||
|
@ -702,7 +662,6 @@ private:
|
|||
StringRef USR = API.recordUSR(Property);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Property->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Property);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Property))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -728,8 +687,8 @@ private:
|
|||
Attributes |= ObjCPropertyRecord::Class;
|
||||
|
||||
API.addObjCProperty(
|
||||
Container, Name, USR, Loc, Availability, Comment, Declaration,
|
||||
SubHeading,
|
||||
Container, Name, USR, Loc, AvailabilitySet(Property), Comment,
|
||||
Declaration, SubHeading,
|
||||
static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
|
||||
GetterName, SetterName, Property->isOptional());
|
||||
}
|
||||
|
@ -745,7 +704,6 @@ private:
|
|||
StringRef USR = API.recordUSR(Ivar);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
|
||||
AvailabilityInfo Availability = getAvailability(Ivar);
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = Context.getRawCommentForDeclNoCache(Ivar))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
|
@ -760,8 +718,9 @@ private:
|
|||
ObjCInstanceVariableRecord::AccessControl Access =
|
||||
Ivar->getCanonicalAccessControl();
|
||||
|
||||
API.addObjCInstanceVariable(Container, Name, USR, Loc, Availability,
|
||||
Comment, Declaration, SubHeading, Access);
|
||||
API.addObjCInstanceVariable(Container, Name, USR, Loc,
|
||||
AvailabilitySet(Ivar), Comment, Declaration,
|
||||
SubHeading, Access);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -135,30 +135,42 @@ Object serializeSourceRange(const PresumedLoc &BeginLoc,
|
|||
/// Serialize the availability attributes of a symbol.
|
||||
///
|
||||
/// Availability information contains the introduced, deprecated, and obsoleted
|
||||
/// versions of the symbol as semantic versions, if not default.
|
||||
/// Availability information also contains flags to indicate if the symbol is
|
||||
/// unconditionally unavailable or deprecated,
|
||||
/// i.e. \c __attribute__((unavailable)) and \c __attribute__((deprecated)).
|
||||
/// versions of the symbol for a given domain (roughly corresponds to a
|
||||
/// platform) as semantic versions, if not default. Availability information
|
||||
/// also contains flags to indicate if the symbol is unconditionally unavailable
|
||||
/// or deprecated, i.e. \c __attribute__((unavailable)) and \c
|
||||
/// __attribute__((deprecated)).
|
||||
///
|
||||
/// \returns \c None if the symbol has default availability attributes, or
|
||||
/// an \c Object containing the formatted availability information.
|
||||
Optional<Object> serializeAvailability(const AvailabilityInfo &Avail) {
|
||||
if (Avail.isDefault())
|
||||
/// an \c Array containing the formatted availability information.
|
||||
Optional<Array> serializeAvailability(const AvailabilitySet &Availabilities) {
|
||||
if (Availabilities.isDefault())
|
||||
return None;
|
||||
|
||||
Object Availability;
|
||||
serializeObject(Availability, "introducedVersion",
|
||||
serializeSemanticVersion(Avail.Introduced));
|
||||
serializeObject(Availability, "deprecatedVersion",
|
||||
serializeSemanticVersion(Avail.Deprecated));
|
||||
serializeObject(Availability, "obsoletedVersion",
|
||||
serializeSemanticVersion(Avail.Obsoleted));
|
||||
if (Avail.isUnavailable())
|
||||
Availability["isUnconditionallyUnavailable"] = true;
|
||||
if (Avail.isUnconditionallyDeprecated())
|
||||
Availability["isUnconditionallyDeprecated"] = true;
|
||||
Array AvailabilityArray;
|
||||
|
||||
return Availability;
|
||||
if (Availabilities.isUnconditionallyDeprecated()) {
|
||||
Object UnconditionallyDeprecated;
|
||||
UnconditionallyDeprecated["domain"] = "*";
|
||||
UnconditionallyDeprecated["isUnconditionallyDeprecated"] = true;
|
||||
AvailabilityArray.emplace_back(std::move(UnconditionallyDeprecated));
|
||||
}
|
||||
|
||||
// Note unconditionally unavailable records are skipped.
|
||||
|
||||
for (const auto &AvailInfo : Availabilities) {
|
||||
Object Availability;
|
||||
Availability["domain"] = AvailInfo.Domain;
|
||||
serializeObject(Availability, "introducedVersion",
|
||||
serializeSemanticVersion(AvailInfo.Introduced));
|
||||
serializeObject(Availability, "deprecatedVersion",
|
||||
serializeSemanticVersion(AvailInfo.Deprecated));
|
||||
serializeObject(Availability, "obsoletedVersion",
|
||||
serializeSemanticVersion(AvailInfo.Obsoleted));
|
||||
AvailabilityArray.emplace_back(std::move(Availability));
|
||||
}
|
||||
|
||||
return AvailabilityArray;
|
||||
}
|
||||
|
||||
/// Get the language name string for interface language references.
|
||||
|
@ -469,7 +481,7 @@ Object SymbolGraphSerializer::serializeModule() const {
|
|||
|
||||
bool SymbolGraphSerializer::shouldSkip(const APIRecord &Record) const {
|
||||
// Skip unconditionally unavailable symbols
|
||||
if (Record.Availability.isUnconditionallyUnavailable())
|
||||
if (Record.Availabilities.isUnconditionallyUnavailable())
|
||||
return true;
|
||||
|
||||
// Filter out symbols prefixed with an underscored as they are understood to
|
||||
|
@ -494,8 +506,8 @@ SymbolGraphSerializer::serializeAPIRecord(const RecordTy &Record) const {
|
|||
serializeObject(
|
||||
Obj, "location",
|
||||
serializeSourceLocation(Record.Location, /*IncludeFileURI=*/true));
|
||||
serializeObject(Obj, "availability",
|
||||
serializeAvailability(Record.Availability));
|
||||
serializeArray(Obj, "availability",
|
||||
serializeAvailability(Record.Availabilities));
|
||||
serializeObject(Obj, "docComment", serializeDocComment(Record.Comment));
|
||||
serializeArray(Obj, "declarationFragments",
|
||||
serializeDeclarationFragments(Record.Declaration));
|
||||
|
|
|
@ -0,0 +1,459 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
|
||||
// RUN: %t/reference.output.json.in >> %t/reference.output.json
|
||||
// RUN: %clang_cc1 -extract-api --product-name=Availability -triple arm64-apple-macosx -x c-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
|
||||
// RUN: %t/output.json >> %t/output-normalized.json
|
||||
// RUN: diff %t/reference.output.json %t/output-normalized.json
|
||||
|
||||
// CHECK-NOT: error:
|
||||
// CHECK-NOT: warning:
|
||||
|
||||
//--- input.h
|
||||
void a(void);
|
||||
|
||||
void b(void) __attribute__((availability(macos, introduced=12.0)));
|
||||
|
||||
void c(void) __attribute__((availability(macos, introduced=11.0, deprecated=12.0, obsoleted=20.0)));
|
||||
|
||||
void d(void) __attribute__((availability(macos, introduced=11.0, deprecated=12.0, obsoleted=20.0))) __attribute__((availability(ios, introduced=13.0)));
|
||||
|
||||
void e(void) __attribute__((deprecated)) __attribute__((availability(macos, introduced=11.0)));
|
||||
|
||||
void f(void) __attribute__((unavailable)) __attribute__((availability(macos, introduced=11.0)));
|
||||
|
||||
void d(void) __attribute__((availability(tvos, introduced=15.0)));
|
||||
///expected-no-diagnostics
|
||||
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "Availability",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "a"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "()"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@F@a"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Function",
|
||||
"identifier": "c.func"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 1
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "a"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "a"
|
||||
}
|
||||
],
|
||||
"title": "a"
|
||||
},
|
||||
"pathComponents": [
|
||||
"a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"availability": [
|
||||
{
|
||||
"domain": "macos",
|
||||
"introducedVersion": {
|
||||
"major": 12,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "b"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "()"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@F@b"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Function",
|
||||
"identifier": "c.func"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 3
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "b"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "b"
|
||||
}
|
||||
],
|
||||
"title": "b"
|
||||
},
|
||||
"pathComponents": [
|
||||
"b"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"availability": [
|
||||
{
|
||||
"deprecatedVersion": {
|
||||
"major": 12,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"domain": "macos",
|
||||
"introducedVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"obsoletedVersion": {
|
||||
"major": 20,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "c"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "()"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@F@c"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Function",
|
||||
"identifier": "c.func"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 5
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "c"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "c"
|
||||
}
|
||||
],
|
||||
"title": "c"
|
||||
},
|
||||
"pathComponents": [
|
||||
"c"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"availability": [
|
||||
{
|
||||
"deprecatedVersion": {
|
||||
"major": 12,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"domain": "macos",
|
||||
"introducedVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"obsoletedVersion": {
|
||||
"major": 20,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "ios",
|
||||
"introducedVersion": {
|
||||
"major": 13,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"domain": "tvos",
|
||||
"introducedVersion": {
|
||||
"major": 15,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "d"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "()"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@F@d"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Function",
|
||||
"identifier": "c.func"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 7
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "d"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "d"
|
||||
}
|
||||
],
|
||||
"title": "d"
|
||||
},
|
||||
"pathComponents": [
|
||||
"d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"availability": [
|
||||
{
|
||||
"domain": "*",
|
||||
"isUnconditionallyDeprecated": true
|
||||
},
|
||||
{
|
||||
"domain": "macos",
|
||||
"introducedVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "e"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "()"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@F@e"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Function",
|
||||
"identifier": "c.func"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 9
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "e"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "e"
|
||||
}
|
||||
],
|
||||
"title": "e"
|
||||
},
|
||||
"pathComponents": [
|
||||
"e"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue