[clang] 236b6a0 - [clang][extract-api] Emit "functionSignature" in SGF for ObjC methods.
Daniel Grumberg via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 11 11:07:44 PDT 2022
Author: Daniel Grumberg
Date: 2022-04-11T19:05:24+01:00
New Revision: 236b6a0eb41a163510e65664e2160f599287326b
URL: https://github.com/llvm/llvm-project/commit/236b6a0eb41a163510e65664e2160f599287326b
DIFF: https://github.com/llvm/llvm-project/commit/236b6a0eb41a163510e65664e2160f599287326b.diff
LOG: [clang][extract-api] Emit "functionSignature" in SGF for ObjC methods.
- Split GlobalRecord into two distinct types to be able to introduce
has_function_signature type trait.
- Add has_function_signature type trait.
- Serialize function signatures as part of serializeAPIRecord for
records that are known to have a function signature.
Differential Revision: https://reviews.llvm.org/D123304
Added:
Modified:
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
clang/test/ExtractAPI/objc_category.m
clang/test/ExtractAPI/objc_interface.m
Removed:
################################################################################
diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h
index 57b6a2ee5a43c..6a9429704d45e 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -77,7 +77,8 @@ struct APIRecord {
/// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
enum RecordKind {
- RK_Global,
+ RK_GlobalFunction,
+ RK_GlobalVariable,
RK_EnumConstant,
RK_Enum,
RK_StructField,
@@ -112,31 +113,40 @@ struct APIRecord {
virtual ~APIRecord() = 0;
};
-/// The kind of a global record.
-enum class GVKind : uint8_t {
- Unknown = 0,
- Variable = 1,
- Function = 2,
-};
+/// This holds information associated with global functions.
+struct GlobalFunctionRecord : APIRecord {
+ FunctionSignature Signature;
-/// This holds information associated with global variables or functions.
-struct GlobalRecord : APIRecord {
- GVKind GlobalKind;
+ GlobalFunctionRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature)
+ : APIRecord(RK_GlobalFunction, Name, USR, Loc, Availability, Linkage,
+ Comment, Declaration, SubHeading),
+ Signature(Signature) {}
- /// The function signature of the record if it is a function.
- FunctionSignature Signature;
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalFunction;
+ }
- GlobalRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
- const AvailabilityInfo &Availability, LinkageInfo Linkage,
- const DocComment &Comment, DeclarationFragments Declaration,
- DeclarationFragments SubHeading, GVKind Kind,
- FunctionSignature Signature)
- : APIRecord(RK_Global, Name, USR, Loc, Availability, Linkage, Comment,
- Declaration, SubHeading),
- GlobalKind(Kind), Signature(Signature) {}
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with global functions.
+struct GlobalVariableRecord : APIRecord {
+ GlobalVariableRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading)
+ : APIRecord(RK_GlobalVariable, Name, USR, Loc, Availability, Linkage,
+ Comment, Declaration, SubHeading) {}
static bool classof(const APIRecord *Record) {
- return Record->getKind() == RK_Global;
+ return Record->getKind() == RK_GlobalVariable;
}
private:
@@ -446,33 +456,31 @@ struct TypedefRecord : APIRecord {
virtual void anchor();
};
+/// Check if a record type has a function signature mixin.
+///
+/// This is denoted by the record type having a ``Signature`` field of type
+/// FunctionSignature.
+template <typename RecordTy>
+struct has_function_signature : public std::false_type {};
+template <>
+struct has_function_signature<GlobalFunctionRecord> : public std::true_type {};
+template <>
+struct has_function_signature<ObjCMethodRecord> : public std::true_type {};
+
/// APISet holds the set of API records collected from given inputs.
class APISet {
public:
- /// Create and add a GlobalRecord of kind \p Kind into the API set.
- ///
- /// Note: the caller is responsible for keeping the StringRef \p Name and
- /// \p USR alive. APISet::copyString provides a way to copy strings into
- /// 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.
- GlobalRecord *addGlobal(GVKind Kind, StringRef Name, StringRef USR,
- PresumedLoc Loc, const AvailabilityInfo &Availability,
- LinkageInfo Linkage, const DocComment &Comment,
- DeclarationFragments Declaration,
- DeclarationFragments SubHeading,
- FunctionSignature Signature);
-
/// Create and add a global variable record into the API set.
///
/// Note: the caller is responsible for keeping the StringRef \p Name and
/// \p USR alive. APISet::copyString provides a way to copy strings into
/// 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.
- GlobalRecord *addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
- const AvailabilityInfo &Availability,
- LinkageInfo Linkage, const DocComment &Comment,
- DeclarationFragments Declaration,
- DeclarationFragments SubHeading);
+ GlobalVariableRecord *
+ addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading);
/// Create and add a function record into the API set.
///
@@ -480,12 +488,12 @@ class APISet {
/// \p USR alive. APISet::copyString provides a way to copy strings into
/// 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.
- GlobalRecord *addFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
- const AvailabilityInfo &Availability,
- LinkageInfo Linkage, const DocComment &Comment,
- DeclarationFragments Declaration,
- DeclarationFragments SubHeading,
- FunctionSignature Signature);
+ GlobalFunctionRecord *
+ addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature);
/// Create and add an enum constant record into the API set.
///
@@ -652,7 +660,12 @@ class APISet {
/// Get the language used by the APIs.
Language getLanguage() const { return Lang; }
- const RecordMap<GlobalRecord> &getGlobals() const { return Globals; }
+ const RecordMap<GlobalFunctionRecord> &getGlobalFunctions() const {
+ return GlobalFunctions;
+ }
+ const RecordMap<GlobalVariableRecord> &getGlobalVariables() const {
+ return GlobalVariables;
+ }
const RecordMap<EnumRecord> &getEnums() const { return Enums; }
const RecordMap<StructRecord> &getStructs() const { return Structs; }
const RecordMap<ObjCCategoryRecord> &getObjCCategories() const {
@@ -699,7 +712,8 @@ class APISet {
const llvm::Triple Target;
const Language Lang;
- RecordMap<GlobalRecord> Globals;
+ RecordMap<GlobalFunctionRecord> GlobalFunctions;
+ RecordMap<GlobalVariableRecord> GlobalVariables;
RecordMap<EnumRecord> Enums;
RecordMap<StructRecord> Structs;
RecordMap<ObjCCategoryRecord> ObjCCategories;
diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
index 93942ff05a0ae..438a9dc327058 100644
--- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
+++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
@@ -122,7 +122,8 @@ class SymbolGraphSerializer : public APISerializer {
///
/// \returns \c None if this \p Record should be skipped, or a JSON object
/// containing common symbol information of \p Record.
- Optional<Object> serializeAPIRecord(const APIRecord &Record) const;
+ template <typename RecordTy>
+ Optional<Object> serializeAPIRecord(const RecordTy &Record) const;
/// Helper method to serialize second-level member records of \p Record and
/// the member-of relationships.
@@ -137,8 +138,11 @@ class SymbolGraphSerializer : public APISerializer {
void serializeRelationship(RelationshipKind Kind, SymbolReference Source,
SymbolReference Target);
- /// Serialize a global record.
- void serializeGlobalRecord(const GlobalRecord &Record);
+ /// Serialize a global function record.
+ void serializeGlobalFunctionRecord(const GlobalFunctionRecord &Record);
+
+ /// Serialize a global variable record.
+ void serializeGlobalVariableRecord(const GlobalVariableRecord &Record);
/// Serialize an enum record.
void serializeEnumRecord(const EnumRecord &Record);
diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp
index 1c33bbf4328cf..10d723d452cac 100644
--- a/clang/lib/ExtractAPI/API.cpp
+++ b/clang/lib/ExtractAPI/API.cpp
@@ -41,34 +41,22 @@ RecordTy *addTopLevelRecord(APISet::RecordMap<RecordTy> &RecordMap,
} // namespace
-GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR,
- PresumedLoc Loc,
- const AvailabilityInfo &Availability,
- LinkageInfo Linkage, const DocComment &Comment,
- DeclarationFragments Fragments,
- DeclarationFragments SubHeading,
- FunctionSignature Signature) {
- return addTopLevelRecord(Globals, Name, USR, Loc, Availability, Linkage,
- Comment, Fragments, SubHeading, Kind, Signature);
-}
-
-GlobalRecord *
+GlobalVariableRecord *
APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
const AvailabilityInfo &Availability, LinkageInfo Linkage,
const DocComment &Comment, DeclarationFragments Fragments,
DeclarationFragments SubHeading) {
- return addGlobal(GVKind::Variable, Name, USR, Loc, Availability, Linkage,
- Comment, Fragments, SubHeading, {});
+ return addTopLevelRecord(GlobalVariables, Name, USR, Loc, Availability,
+ Linkage, Comment, Fragments, SubHeading);
}
-GlobalRecord *
-APISet::addFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
- const AvailabilityInfo &Availability, LinkageInfo Linkage,
- const DocComment &Comment, DeclarationFragments Fragments,
- DeclarationFragments SubHeading,
- FunctionSignature Signature) {
- return addGlobal(GVKind::Function, Name, USR, Loc, Availability, Linkage,
- Comment, Fragments, SubHeading, Signature);
+GlobalFunctionRecord *APISet::addGlobalFunction(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Fragments,
+ DeclarationFragments SubHeading, FunctionSignature Signature) {
+ return addTopLevelRecord(GlobalFunctions, Name, USR, Loc, Availability,
+ Linkage, Comment, Fragments, SubHeading, Signature);
}
EnumConstantRecord *APISet::addEnumConstant(
@@ -229,7 +217,8 @@ APIRecord::~APIRecord() {}
ObjCContainerRecord::~ObjCContainerRecord() {}
-void GlobalRecord::anchor() {}
+void GlobalFunctionRecord::anchor() {}
+void GlobalVariableRecord::anchor() {}
void EnumConstantRecord::anchor() {}
void EnumRecord::anchor() {}
void StructFieldRecord::anchor() {}
diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index 0757881862984..e3700a0d390a2 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -198,8 +198,8 @@ class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> {
DeclarationFragmentsBuilder::getFunctionSignature(Decl);
// Add the function record to the API set.
- API.addFunction(Name, USR, Loc, Availability, Linkage, Comment, Declaration,
- SubHeading, Signature);
+ API.addGlobalFunction(Name, USR, Loc, Availability, Linkage, Comment,
+ Declaration, SubHeading, Signature);
return true;
}
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 2a3818e0da520..045d5d68e733b 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -18,6 +18,7 @@
#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VersionTuple.h"
+#include <type_traits>
using namespace clang;
using namespace clang::extractapi;
@@ -285,39 +286,6 @@ Optional<Array> serializeDeclarationFragments(const DeclarationFragments &DF) {
return Fragments;
}
-/// Serialize the function signature field of a function, as specified by the
-/// Symbol Graph format.
-///
-/// The Symbol Graph function signature property contains two arrays.
-/// - The \c returns array is the declaration fragments of the return type;
-/// - The \c parameters array contains names and declaration fragments of the
-/// parameters.
-///
-/// \returns \c None if \p FS is empty, or an \c Object containing the
-/// formatted function signature.
-Optional<Object> serializeFunctionSignature(const FunctionSignature &FS) {
- if (FS.empty())
- return None;
-
- Object Signature;
- serializeArray(Signature, "returns",
- serializeDeclarationFragments(FS.getReturnType()));
-
- Array Parameters;
- for (const auto &P : FS.getParameters()) {
- Object Parameter;
- Parameter["name"] = P.Name;
- serializeArray(Parameter, "declarationFragments",
- serializeDeclarationFragments(P.Fragments));
- Parameters.emplace_back(std::move(Parameter));
- }
-
- if (!Parameters.empty())
- Signature["parameters"] = std::move(Parameters);
-
- return Signature;
-}
-
/// Serialize the \c names field of a symbol as specified by the Symbol Graph
/// format.
///
@@ -354,23 +322,14 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
Object Kind;
switch (Record.getKind()) {
- case APIRecord::RK_Global: {
- auto *GR = dyn_cast<GlobalRecord>(&Record);
- switch (GR->GlobalKind) {
- case GVKind::Function:
- Kind["identifier"] = AddLangPrefix("func");
- Kind["displayName"] = "Function";
- break;
- case GVKind::Variable:
- Kind["identifier"] = AddLangPrefix("var");
- Kind["displayName"] = "Global Variable";
- break;
- case GVKind::Unknown:
- // Unknown global kind
- break;
- }
+ case APIRecord::RK_GlobalFunction:
+ Kind["identifier"] = AddLangPrefix("func");
+ Kind["displayName"] = "Function";
+ break;
+ case APIRecord::RK_GlobalVariable:
+ Kind["identifier"] = AddLangPrefix("var");
+ Kind["displayName"] = "Global Variable";
break;
- }
case APIRecord::RK_EnumConstant:
Kind["identifier"] = AddLangPrefix("enum.case");
Kind["displayName"] = "Enumeration Case";
@@ -430,6 +389,55 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
return Kind;
}
+template <typename RecordTy>
+Optional<Object> serializeFunctionSignatureMixinImpl(const RecordTy &Record,
+ std::true_type) {
+ const auto &FS = Record.Signature;
+ if (FS.empty())
+ return None;
+
+ Object Signature;
+ serializeArray(Signature, "returns",
+ serializeDeclarationFragments(FS.getReturnType()));
+
+ Array Parameters;
+ for (const auto &P : FS.getParameters()) {
+ Object Parameter;
+ Parameter["name"] = P.Name;
+ serializeArray(Parameter, "declarationFragments",
+ serializeDeclarationFragments(P.Fragments));
+ Parameters.emplace_back(std::move(Parameter));
+ }
+
+ if (!Parameters.empty())
+ Signature["parameters"] = std::move(Parameters);
+
+ return Signature;
+}
+
+template <typename RecordTy>
+Optional<Object> serializeFunctionSignatureMixinImpl(const RecordTy &Record,
+ std::false_type) {
+ return None;
+}
+
+/// Serialize the function signature field, as specified by the
+/// Symbol Graph format.
+///
+/// The Symbol Graph function signature property contains two arrays.
+/// - The \c returns array is the declaration fragments of the return type;
+/// - The \c parameters array contains names and declaration fragments of the
+/// parameters.
+///
+/// \returns \c None if \p FS is empty, or an \c Object containing the
+/// formatted function signature.
+template <typename RecordTy>
+void serializeFunctionSignatureMixin(Object &Paren, const RecordTy &Record) {
+ serializeObject(Paren, "functionSignature",
+ serializeFunctionSignatureMixinImpl(
+ Record, has_function_signature<RecordTy>()));
+}
+
} // namespace
void SymbolGraphSerializer::anchor() {}
@@ -462,8 +470,9 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord &Record) const {
return false;
}
+template <typename RecordTy>
Optional<Object>
-SymbolGraphSerializer::serializeAPIRecord(const APIRecord &Record) const {
+SymbolGraphSerializer::serializeAPIRecord(const RecordTy &Record) const {
if (shouldSkip(Record))
return None;
@@ -485,6 +494,8 @@ SymbolGraphSerializer::serializeAPIRecord(const APIRecord &Record) const {
Obj["accessLevel"] = "public";
serializeArray(Obj, "pathComponents", Array(PathComponents));
+ serializeFunctionSignatureMixin(Obj, Record);
+
return Obj;
}
@@ -526,16 +537,24 @@ void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind,
Relationships.emplace_back(std::move(Relationship));
}
-void SymbolGraphSerializer::serializeGlobalRecord(const GlobalRecord &Record) {
+void SymbolGraphSerializer::serializeGlobalFunctionRecord(
+ const GlobalFunctionRecord &Record) {
auto GlobalPathComponentGuard = makePathComponentGuard(Record.Name);
auto Obj = serializeAPIRecord(Record);
if (!Obj)
return;
- if (Record.GlobalKind == GVKind::Function)
- serializeObject(*Obj, "functionSignature",
- serializeFunctionSignature(Record.Signature));
+ Symbols.emplace_back(std::move(*Obj));
+}
+
+void SymbolGraphSerializer::serializeGlobalVariableRecord(
+ const GlobalVariableRecord &Record) {
+ auto GlobalPathComponentGuard = makePathComponentGuard(Record.Name);
+
+ auto Obj = serializeAPIRecord(Record);
+ if (!Obj)
+ return;
Symbols.emplace_back(std::move(*Obj));
}
@@ -640,9 +659,12 @@ Object SymbolGraphSerializer::serialize() {
serializeObject(Root, "metadata", serializeMetadata());
serializeObject(Root, "module", serializeModule());
- // Serialize global records in the API set.
- for (const auto &Global : API.getGlobals())
- serializeGlobalRecord(*Global.second);
+ // Serialize global variables in the API set.
+ for (const auto &GlobalVar : API.getGlobalVariables())
+ serializeGlobalVariableRecord(*GlobalVar.second);
+
+ for (const auto &GlobalFunction : API.getGlobalFunctions())
+ serializeGlobalFunctionRecord(*GlobalFunction.second);
// Serialize enum records in the API set.
for (const auto &Enum : API.getEnums())
diff --git a/clang/test/ExtractAPI/objc_category.m b/clang/test/ExtractAPI/objc_category.m
index af5a44ff5b424..2a69740203c3a 100644
--- a/clang/test/ExtractAPI/objc_category.m
+++ b/clang/test/ExtractAPI/objc_category.m
@@ -148,6 +148,15 @@ + (void)ClassMethod;
"spelling": ";"
}
],
+ "functionSignature": {
+ "returns": [
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:v",
+ "spelling": "void"
+ }
+ ]
+ },
"identifier": {
"interfaceLanguage": "objective-c",
"precise": "c:objc(cs)Interface(im)InstanceMethod"
@@ -212,6 +221,15 @@ + (void)ClassMethod;
"spelling": ";"
}
],
+ "functionSignature": {
+ "returns": [
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:v",
+ "spelling": "void"
+ }
+ ]
+ },
"identifier": {
"interfaceLanguage": "objective-c",
"precise": "c:objc(cs)Interface(cm)ClassMethod"
diff --git a/clang/test/ExtractAPI/objc_interface.m b/clang/test/ExtractAPI/objc_interface.m
index fc42cfc7c6728..1ac2f81a80603 100644
--- a/clang/test/ExtractAPI/objc_interface.m
+++ b/clang/test/ExtractAPI/objc_interface.m
@@ -182,6 +182,38 @@ - (char)getIvar;
"spelling": ";"
}
],
+ "functionSignature": {
+ "parameters": [
+ {
+ "declarationFragments": [
+ {
+ "kind": "text",
+ "spelling": "("
+ },
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:i",
+ "spelling": "unsigned int"
+ },
+ {
+ "kind": "text",
+ "spelling": ") "
+ },
+ {
+ "kind": "internalParam",
+ "spelling": "Property"
+ }
+ ],
+ "name": "Property"
+ }
+ ],
+ "returns": [
+ {
+ "kind": "keyword",
+ "spelling": "id"
+ }
+ ]
+ },
"identifier": {
"interfaceLanguage": "objective-c",
"precise": "c:objc(cs)Super(cm)getWithProperty:"
@@ -288,6 +320,61 @@ - (char)getIvar;
"spelling": ";"
}
],
+ "functionSignature": {
+ "parameters": [
+ {
+ "declarationFragments": [
+ {
+ "kind": "text",
+ "spelling": "("
+ },
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:i",
+ "spelling": "unsigned int"
+ },
+ {
+ "kind": "text",
+ "spelling": ") "
+ },
+ {
+ "kind": "internalParam",
+ "spelling": "Property"
+ }
+ ],
+ "name": "Property"
+ },
+ {
+ "declarationFragments": [
+ {
+ "kind": "text",
+ "spelling": "("
+ },
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:i",
+ "spelling": "unsigned int"
+ },
+ {
+ "kind": "text",
+ "spelling": ") "
+ },
+ {
+ "kind": "internalParam",
+ "spelling": "Thing"
+ }
+ ],
+ "name": "Thing"
+ }
+ ],
+ "returns": [
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:v",
+ "spelling": "void"
+ }
+ ]
+ },
"identifier": {
"interfaceLanguage": "objective-c",
"precise": "c:objc(cs)Super(im)setProperty:andOtherThing:"
@@ -551,6 +638,15 @@ - (char)getIvar;
"spelling": ";"
}
],
+ "functionSignature": {
+ "returns": [
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:C",
+ "spelling": "char"
+ }
+ ]
+ },
"identifier": {
"interfaceLanguage": "objective-c",
"precise": "c:objc(cs)Derived(im)getIvar"
More information about the cfe-commits
mailing list