mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 23:36:05 +00:00
Revert "[clang][ExtractAPI] Add ability to create multiple symbol graphs (#86676)"
This failed the test suite due to missing DiagGroup for a new warning. This reverts commit b31414bf4f9898f7817a9fcf8a91f62ec26f3eaf.
This commit is contained in:
parent
ea9a66ea8b
commit
209a1e8dfd
@ -548,12 +548,6 @@ def err_drv_extract_api_wrong_kind : Error<
|
||||
"header file '%0' input '%1' does not match the type of prior input "
|
||||
"in api extraction; use '-x %2' to override">;
|
||||
|
||||
def err_drv_missing_symbol_graph_dir: Error<
|
||||
"Must provide a symbol graph output directory using --symbol-graph-dir=<directory>">;
|
||||
|
||||
def err_drv_unexpected_symbol_graph_output : Error<
|
||||
"Unexpected output symbol graph '%1'; please provide --symbol-graph-dir=<directory> instead">;
|
||||
|
||||
def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
|
||||
InGroup<DiagGroup<"slash-u-filename">>;
|
||||
def note_use_dashdash : Note<
|
||||
|
@ -366,6 +366,4 @@ def warn_profile_data_misexpect : Warning<
|
||||
def err_extract_api_ignores_file_not_found :
|
||||
Error<"file '%0' specified by '--extract-api-ignores=' not found">, DefaultFatal;
|
||||
|
||||
def warn_missing_symbol_graph_dir : Warning<"Missing symbol graph output directory, defaulting to working directory">;
|
||||
|
||||
}
|
||||
|
@ -1507,29 +1507,14 @@ def extract_api : Flag<["-"], "extract-api">,
|
||||
def product_name_EQ: Joined<["--"], "product-name=">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
MarshallingInfoString<FrontendOpts<"ProductName">>;
|
||||
def emit_symbol_graph: Flag<["-"], "emit-symbol-graph">,
|
||||
def emit_symbol_graph_EQ: JoinedOrSeparate<["--"], "emit-symbol-graph=">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Generate Extract API information as a side effect of compilation.">,
|
||||
MarshallingInfoFlag<FrontendOpts<"EmitSymbolGraph">>;
|
||||
def emit_extension_symbol_graphs: Flag<["--"], "emit-extension-symbol-graphs">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Generate additional symbol graphs for extended modules.">,
|
||||
MarshallingInfoFlag<FrontendOpts<"EmitExtensionSymbolGraphs">>;
|
||||
HelpText<"Generate Extract API information as a side effect of compilation.">,
|
||||
MarshallingInfoString<FrontendOpts<"SymbolGraphOutputDir">>;
|
||||
def extract_api_ignores_EQ: CommaJoined<["--"], "extract-api-ignores=">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Comma separated list of files containing a new line separated list of API symbols to ignore when extracting API information.">,
|
||||
MarshallingInfoStringVector<FrontendOpts<"ExtractAPIIgnoresFileList">>;
|
||||
def symbol_graph_dir_EQ: Joined<["--"], "symbol-graph-dir=">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Directory in which to emit symbol graphs.">,
|
||||
MarshallingInfoString<FrontendOpts<"SymbolGraphOutputDir">>;
|
||||
def emit_pretty_sgf: Flag<["--"], "pretty-sgf">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Emit pretty printed symbol graphs">,
|
||||
MarshallingInfoFlag<FrontendOpts<"EmitPrettySymbolGraphs">>;
|
||||
def emit_sgf_symbol_labels_for_testing: Flag<["--"], "emit-sgf-symbol-labels-for-testing">,
|
||||
Visibility<[CC1Option]>,
|
||||
MarshallingInfoFlag<FrontendOpts<"EmitSymbolGraphSymbolLabelsForTesting">>;
|
||||
def e : Separate<["-"], "e">, Flags<[LinkerInput]>, Group<Link_Group>;
|
||||
def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,103 +0,0 @@
|
||||
//===- ExtractAPI/APIRecords.inc --------------------------------*- 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
|
||||
/// This file defines the classes defined from ExtractAPI's APIRecord
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ABSTRACT_RECORD
|
||||
#define ABSTRACT_RECORD(CLASS, BASE) RECORD(CLASS, BASE)
|
||||
#endif
|
||||
#ifndef CONCRETE_RECORD
|
||||
#define CONCRETE_RECORD(CLASS, BASE, KIND) RECORD(CLASS, BASE)
|
||||
#endif
|
||||
#ifndef RECORD
|
||||
#define RECORD(CLASS, BASE)
|
||||
#endif
|
||||
|
||||
CONCRETE_RECORD(NamespaceRecord, APIRecord, RK_Namespace)
|
||||
CONCRETE_RECORD(GlobalFunctionRecord, APIRecord, RK_GlobalFunction)
|
||||
CONCRETE_RECORD(GlobalFunctionTemplateRecord, GlobalFunctionRecord,
|
||||
RK_GlobalFunctionTemplate)
|
||||
CONCRETE_RECORD(GlobalFunctionTemplateSpecializationRecord,
|
||||
GlobalFunctionRecord, RK_GlobalFunctionTemplateSpecialization)
|
||||
CONCRETE_RECORD(GlobalVariableRecord, APIRecord, RK_GlobalVariable)
|
||||
CONCRETE_RECORD(GlobalVariableTemplateRecord, GlobalVariableRecord,
|
||||
RK_GlobalVariableTemplate)
|
||||
CONCRETE_RECORD(GlobalVariableTemplateSpecializationRecord,
|
||||
GlobalVariableRecord, RK_GlobalVariableTemplateSpecialization)
|
||||
CONCRETE_RECORD(GlobalVariableTemplatePartialSpecializationRecord,
|
||||
GlobalVariableRecord,
|
||||
RK_GlobalVariableTemplatePartialSpecialization)
|
||||
CONCRETE_RECORD(EnumConstantRecord, APIRecord, RK_EnumConstant)
|
||||
CONCRETE_RECORD(EnumRecord, APIRecord, RK_Enum)
|
||||
ABSTRACT_RECORD(RecordFieldRecord, APIRecord)
|
||||
ABSTRACT_RECORD(RecordRecord, APIRecord)
|
||||
CONCRETE_RECORD(StructFieldRecord, RecordFieldRecord, RK_StructField)
|
||||
CONCRETE_RECORD(StructRecord, APIRecord, RK_Struct)
|
||||
CONCRETE_RECORD(UnionFieldRecord, RecordFieldRecord, RK_UnionField)
|
||||
CONCRETE_RECORD(UnionRecord, APIRecord, RK_Union)
|
||||
CONCRETE_RECORD(CXXFieldRecord, APIRecord, RK_CXXField)
|
||||
CONCRETE_RECORD(CXXFieldTemplateRecord, CXXFieldRecord, RK_CXXFieldTemplate)
|
||||
ABSTRACT_RECORD(CXXMethodRecord, APIRecord)
|
||||
CONCRETE_RECORD(CXXConstructorRecord, CXXMethodRecord, RK_CXXConstructorMethod)
|
||||
CONCRETE_RECORD(CXXDestructorRecord, CXXMethodRecord, RK_CXXDestructorMethod)
|
||||
CONCRETE_RECORD(CXXStaticMethodRecord, CXXMethodRecord, RK_CXXStaticMethod)
|
||||
CONCRETE_RECORD(CXXInstanceMethodRecord, CXXMethodRecord, RK_CXXInstanceMethod)
|
||||
CONCRETE_RECORD(CXXMethodTemplateRecord, CXXMethodRecord, RK_CXXMethodTemplate)
|
||||
CONCRETE_RECORD(CXXMethodTemplateSpecializationRecord, CXXMethodRecord,
|
||||
RK_CXXMethodTemplateSpecialization)
|
||||
ABSTRACT_RECORD(ObjCPropertyRecord, APIRecord)
|
||||
CONCRETE_RECORD(ObjCInstancePropertyRecord, ObjCPropertyRecord,
|
||||
RK_ObjCInstanceProperty)
|
||||
CONCRETE_RECORD(ObjCClassPropertyRecord, ObjCPropertyRecord,
|
||||
RK_ObjCClassProperty)
|
||||
CONCRETE_RECORD(ObjCInstanceVariableRecord, APIRecord, RK_ObjCIvar)
|
||||
ABSTRACT_RECORD(ObjCMethodRecord, APIRecord)
|
||||
CONCRETE_RECORD(ObjCInstanceMethodRecord, ObjCMethodRecord,
|
||||
RK_ObjCInstanceMethod)
|
||||
CONCRETE_RECORD(ObjCClassMethodRecord, ObjCMethodRecord, RK_ObjCClassMethod)
|
||||
CONCRETE_RECORD(StaticFieldRecord, CXXFieldRecord, RK_StaticField)
|
||||
ABSTRACT_RECORD(ObjCContainerRecord, APIRecord)
|
||||
CONCRETE_RECORD(CXXClassRecord, APIRecord, RK_CXXClass)
|
||||
CONCRETE_RECORD(ClassTemplateRecord, CXXClassRecord, RK_ClassTemplate)
|
||||
CONCRETE_RECORD(ClassTemplateSpecializationRecord, CXXClassRecord,
|
||||
RK_ClassTemplateSpecialization)
|
||||
CONCRETE_RECORD(ClassTemplatePartialSpecializationRecord, CXXClassRecord,
|
||||
RK_ClassTemplatePartialSpecialization)
|
||||
CONCRETE_RECORD(ConceptRecord, APIRecord, RK_Concept)
|
||||
CONCRETE_RECORD(ObjCCategoryRecord, ObjCContainerRecord, RK_ObjCCategory)
|
||||
CONCRETE_RECORD(ObjCInterfaceRecord, ObjCContainerRecord, RK_ObjCInterface)
|
||||
CONCRETE_RECORD(ObjCProtocolRecord, ObjCContainerRecord, RK_ObjCProtocol)
|
||||
CONCRETE_RECORD(MacroDefinitionRecord, APIRecord, RK_MacroDefinition)
|
||||
CONCRETE_RECORD(TypedefRecord, APIRecord, RK_Typedef)
|
||||
|
||||
#undef CONCRETE_RECORD
|
||||
#undef ABSTRACT_RECORD
|
||||
#undef RECORD
|
||||
|
||||
#ifndef RECORD_CONTEXT
|
||||
#define RECORD_CONTEXT(CLASS, KIND)
|
||||
#endif
|
||||
|
||||
RECORD_CONTEXT(NamespaceRecord, RK_Namespace)
|
||||
RECORD_CONTEXT(EnumRecord, RK_Enum)
|
||||
RECORD_CONTEXT(StructRecord, RK_Struct)
|
||||
RECORD_CONTEXT(UnionRecord, RK_Union)
|
||||
RECORD_CONTEXT(ObjCCategoryRecord, RK_ObjCCategory)
|
||||
RECORD_CONTEXT(ObjCInterfaceRecord, RK_ObjCInterface)
|
||||
RECORD_CONTEXT(ObjCProtocolRecord, RK_ObjCProtocol)
|
||||
RECORD_CONTEXT(CXXClassRecord, RK_CXXClass)
|
||||
RECORD_CONTEXT(ClassTemplateRecord, RK_ClassTemplate)
|
||||
RECORD_CONTEXT(ClassTemplateSpecializationRecord,
|
||||
RK_ClassTemplateSpecialization)
|
||||
RECORD_CONTEXT(ClassTemplatePartialSpecializationRecord,
|
||||
RK_ClassTemplatePartialSpecialization)
|
||||
|
||||
#undef RECORD_CONTEXT
|
@ -182,18 +182,6 @@ public:
|
||||
/// appending to chain up consecutive appends.
|
||||
DeclarationFragments &appendSpace();
|
||||
|
||||
/// Append a text Fragment of a semicolon character.
|
||||
///
|
||||
/// \returns a reference to the DeclarationFragments object itself after
|
||||
/// appending to chain up consecutive appends.
|
||||
DeclarationFragments &appendSemicolon();
|
||||
|
||||
/// Removes a trailing semicolon character if present.
|
||||
///
|
||||
/// \returns a reference to the DeclarationFragments object itself after
|
||||
/// removing to chain up consecutive operations.
|
||||
DeclarationFragments &removeTrailingSemicolon();
|
||||
|
||||
/// Get the string description of a FragmentKind \p Kind.
|
||||
static StringRef getFragmentKindString(FragmentKind Kind);
|
||||
|
||||
@ -206,14 +194,12 @@ public:
|
||||
static DeclarationFragments getStructureTypeFragment(const RecordDecl *Decl);
|
||||
|
||||
private:
|
||||
DeclarationFragments &appendUnduplicatedTextCharacter(char Character);
|
||||
std::vector<Fragment> Fragments;
|
||||
};
|
||||
|
||||
class AccessControl {
|
||||
public:
|
||||
AccessControl(std::string Access) : Access(Access) {}
|
||||
AccessControl() : Access("public") {}
|
||||
|
||||
const std::string &getAccess() const { return Access; }
|
||||
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
#include "clang/ExtractAPI/API.h"
|
||||
#include "clang/ExtractAPI/APIIgnoresList.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -31,8 +29,8 @@ protected:
|
||||
/// A representation of the APIs this action extracts.
|
||||
std::unique_ptr<extractapi::APISet> API;
|
||||
|
||||
/// A stream to the main output file of this action.
|
||||
std::unique_ptr<llvm::raw_pwrite_stream> OS;
|
||||
/// A stream to the output file of this action.
|
||||
std::unique_ptr<raw_pwrite_stream> OS;
|
||||
|
||||
/// The product this action is extracting API information for.
|
||||
std::string ProductName;
|
||||
@ -48,7 +46,7 @@ protected:
|
||||
///
|
||||
/// Use the serializer to generate output symbol graph files from
|
||||
/// the information gathered during the execution of Action.
|
||||
void ImplEndSourceFileAction(CompilerInstance &CI);
|
||||
void ImplEndSourceFileAction();
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -49,6 +49,9 @@ private:
|
||||
void EndSourceFileAction() override;
|
||||
|
||||
static StringRef getInputBufferName() { return "<extract-api-includes>"; }
|
||||
|
||||
static std::unique_ptr<llvm::raw_pwrite_stream>
|
||||
CreateOutputFile(CompilerInstance &CI, StringRef InFile);
|
||||
};
|
||||
|
||||
/// Wrap ExtractAPIAction on top of a pre-existing action
|
||||
@ -82,6 +85,9 @@ private:
|
||||
/// actions. This is the place where all the gathered symbol graph
|
||||
/// information is emited.
|
||||
void EndSourceFileAction() override;
|
||||
|
||||
static std::unique_ptr<llvm::raw_pwrite_stream>
|
||||
CreateOutputFile(CompilerInstance &CI, StringRef InFile);
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
@ -1,172 +0,0 @@
|
||||
//===- ExtractAPI/Serialization/APISetVisitor.h ----------------*- 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
|
||||
/// This file defines the ExtractAPI APISetVisitor interface.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
|
||||
#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
|
||||
|
||||
#include "clang/ExtractAPI/API.h"
|
||||
|
||||
namespace clang {
|
||||
namespace extractapi {
|
||||
|
||||
// A helper macro to implement short-circuiting when recursing. It
|
||||
// invokes CALL_EXPR, which must be a method call, on the derived
|
||||
// object (s.t. a user of RecursiveASTVisitor can override the method
|
||||
// in CALL_EXPR).
|
||||
#define TRY_TO(CALL_EXPR) \
|
||||
do { \
|
||||
if (!getDerived()->CALL_EXPR) \
|
||||
return false; \
|
||||
} while (false)
|
||||
|
||||
/// The base interface of visitors for API information, the interface and usage
|
||||
/// is almost identical to RecurisveASTVistor. This class performs three
|
||||
/// distinct tasks:
|
||||
/// 1. traverse the APISet (i.e. go to every record);
|
||||
/// 2. at a given record, walk up the class hierarchy starting from the record's
|
||||
/// dynamic type until APIRecord is reached.
|
||||
/// 3. given a (record, class) combination where 'class' is some base class of
|
||||
/// the dynamic type of 'record', call a user-overridable function to actually
|
||||
/// visit the record.
|
||||
///
|
||||
/// These tasks are done by three groups of methods, respectively:
|
||||
/// 1. traverseRecord(APIRecord *x) does task #1, it is the entry point for
|
||||
/// traversing the records starting from x. This method simply forwards to
|
||||
/// traverseFoo(Foo *x) where Foo is the dynamic type of *x, which calls
|
||||
/// walkUpFromFoo(x) and then recursively visits the child records of x.
|
||||
/// 2. walkUpFromFoo(Foo *x) does task #2. It doesn't visit children records of
|
||||
/// x, instead it first calls walkUpFromBar(x) where Bar is the direct parent
|
||||
/// class of Foo (unless Foo has no parent) and then calls visitFoo(x).
|
||||
/// 3. visitFoo(Foo *x) does task #3.
|
||||
///
|
||||
/// These three method groups are tiered (traverse* > walkUpFrom* >
|
||||
/// visit*). A method (e.g. traverse*) may call methods from the same
|
||||
/// tier (e.g. other traverse*) or one tier lower (e.g. walkUpFrom*).
|
||||
/// It may not call methods from a higher tier.
|
||||
///
|
||||
/// Note that since walkUpFromFoo() calls walkUpFromBar() (where Bar
|
||||
/// is Foo's super class) before calling visitFoo(), the result is
|
||||
/// that the visit*() methods for a given record are called in the
|
||||
/// top-down order (e.g. for a record of type ObjCInstancePropertyRecord, the
|
||||
/// order will be visitRecord(), visitObjCPropertyRecord(), and then
|
||||
/// visitObjCInstancePropertyRecord()).
|
||||
///
|
||||
/// This scheme guarantees that all visit*() calls for the same record
|
||||
/// are grouped together. In other words, visit*() methods for different
|
||||
/// records are never interleaved.
|
||||
///
|
||||
/// Clients of this visitor should subclass the visitor (providing
|
||||
/// themselves as the template argument, using the curiously recurring
|
||||
/// template pattern) and override any of the traverse*, walkUpFrom*,
|
||||
/// and visit* methods for records where the visitor should customize
|
||||
/// behavior. Most users only need to override visit*. Advanced
|
||||
/// users may override traverse* and walkUpFrom* to implement custom
|
||||
/// traversal strategies. Returning false from one of these overridden
|
||||
/// functions will abort the entire traversal.
|
||||
template <typename Derived> class APISetVisitor {
|
||||
public:
|
||||
bool traverseAPISet() {
|
||||
for (const APIRecord *TLR : API.getTopLevelRecords()) {
|
||||
TRY_TO(traverseAPIRecord(TLR));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool traverseAPIRecord(const APIRecord *Record);
|
||||
bool walkUpFromAPIRecord(const APIRecord *Record) {
|
||||
TRY_TO(visitAPIRecord(Record));
|
||||
return true;
|
||||
}
|
||||
bool visitAPIRecord(const APIRecord *Record) { return true; }
|
||||
|
||||
#define GENERATE_TRAVERSE_METHOD(CLASS, BASE) \
|
||||
bool traverse##CLASS(const CLASS *Record) { \
|
||||
TRY_TO(walkUpFrom##CLASS(Record)); \
|
||||
TRY_TO(traverseRecordContext(dyn_cast<RecordContext>(Record))); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#define GENERATE_WALKUP_AND_VISIT_METHODS(CLASS, BASE) \
|
||||
bool walkUpFrom##CLASS(const CLASS *Record) { \
|
||||
TRY_TO(walkUpFrom##BASE(Record)); \
|
||||
TRY_TO(visit##CLASS(Record)); \
|
||||
return true; \
|
||||
} \
|
||||
bool visit##CLASS(const CLASS *Record) { return true; }
|
||||
|
||||
#define CONCRETE_RECORD(CLASS, BASE, KIND) \
|
||||
GENERATE_TRAVERSE_METHOD(CLASS, BASE) \
|
||||
GENERATE_WALKUP_AND_VISIT_METHODS(CLASS, BASE)
|
||||
|
||||
#define ABSTRACT_RECORD(CLASS, BASE) \
|
||||
GENERATE_WALKUP_AND_VISIT_METHODS(CLASS, BASE)
|
||||
|
||||
#include "../APIRecords.inc"
|
||||
|
||||
#undef GENERATE_WALKUP_AND_VISIT_METHODS
|
||||
#undef GENERATE_TRAVERSE_METHOD
|
||||
|
||||
bool traverseRecordContext(const RecordContext *);
|
||||
|
||||
protected:
|
||||
const APISet &API;
|
||||
|
||||
public:
|
||||
APISetVisitor() = delete;
|
||||
APISetVisitor(const APISetVisitor &) = delete;
|
||||
APISetVisitor(APISetVisitor &&) = delete;
|
||||
APISetVisitor &operator=(const APISetVisitor &) = delete;
|
||||
APISetVisitor &operator=(APISetVisitor &&) = delete;
|
||||
|
||||
protected:
|
||||
APISetVisitor(const APISet &API) : API(API) {}
|
||||
~APISetVisitor() = default;
|
||||
|
||||
Derived *getDerived() { return static_cast<Derived *>(this); };
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
bool APISetVisitor<Derived>::traverseRecordContext(
|
||||
const RecordContext *Context) {
|
||||
if (!Context)
|
||||
return true;
|
||||
|
||||
for (auto *Child : Context->records())
|
||||
TRY_TO(traverseAPIRecord(Child));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool APISetVisitor<Derived>::traverseAPIRecord(const APIRecord *Record) {
|
||||
switch (Record->getKind()) {
|
||||
#define CONCRETE_RECORD(CLASS, BASE, KIND) \
|
||||
case APIRecord::KIND: { \
|
||||
TRY_TO(traverse##CLASS(static_cast<const CLASS *>(Record))); \
|
||||
break; \
|
||||
}
|
||||
#include "../APIRecords.inc"
|
||||
case APIRecord::RK_Unknown: {
|
||||
TRY_TO(walkUpFromAPIRecord(static_cast<const APIRecord *>(Record)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("API Record with uninstantiable kind");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace extractapi
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
|
314
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
Normal file
314
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
Normal file
@ -0,0 +1,314 @@
|
||||
//===- ExtractAPI/Serialization/SerializerBase.h ----------------*- 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
|
||||
/// This file defines the ExtractAPI APISetVisitor interface.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
|
||||
#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
|
||||
|
||||
#include "clang/ExtractAPI/API.h"
|
||||
|
||||
namespace clang {
|
||||
namespace extractapi {
|
||||
|
||||
/// The base interface of visitors for API information.
|
||||
template <typename Derived> class APISetVisitor {
|
||||
public:
|
||||
void traverseAPISet() {
|
||||
getDerived()->traverseNamespaces();
|
||||
|
||||
getDerived()->traverseGlobalVariableRecords();
|
||||
|
||||
getDerived()->traverseGlobalFunctionRecords();
|
||||
|
||||
getDerived()->traverseEnumRecords();
|
||||
|
||||
getDerived()->traverseStaticFieldRecords();
|
||||
|
||||
getDerived()->traverseCXXClassRecords();
|
||||
|
||||
getDerived()->traverseClassTemplateRecords();
|
||||
|
||||
getDerived()->traverseClassTemplateSpecializationRecords();
|
||||
|
||||
getDerived()->traverseClassTemplatePartialSpecializationRecords();
|
||||
|
||||
getDerived()->traverseCXXInstanceMethods();
|
||||
|
||||
getDerived()->traverseCXXStaticMethods();
|
||||
|
||||
getDerived()->traverseCXXMethodTemplates();
|
||||
|
||||
getDerived()->traverseCXXMethodTemplateSpecializations();
|
||||
|
||||
getDerived()->traverseCXXFields();
|
||||
|
||||
getDerived()->traverseCXXFieldTemplates();
|
||||
|
||||
getDerived()->traverseConcepts();
|
||||
|
||||
getDerived()->traverseGlobalVariableTemplateRecords();
|
||||
|
||||
getDerived()->traverseGlobalVariableTemplateSpecializationRecords();
|
||||
|
||||
getDerived()->traverseGlobalVariableTemplatePartialSpecializationRecords();
|
||||
|
||||
getDerived()->traverseGlobalFunctionTemplateRecords();
|
||||
|
||||
getDerived()->traverseGlobalFunctionTemplateSpecializationRecords();
|
||||
|
||||
getDerived()->traverseRecordRecords();
|
||||
|
||||
getDerived()->traverseObjCInterfaces();
|
||||
|
||||
getDerived()->traverseObjCProtocols();
|
||||
|
||||
getDerived()->traverseObjCCategories();
|
||||
|
||||
getDerived()->traverseMacroDefinitionRecords();
|
||||
|
||||
getDerived()->traverseTypedefRecords();
|
||||
}
|
||||
|
||||
void traverseNamespaces() {
|
||||
for (const auto &Namespace : API.getNamespaces())
|
||||
getDerived()->visitNamespaceRecord(*Namespace.second);
|
||||
}
|
||||
|
||||
void traverseGlobalFunctionRecords() {
|
||||
for (const auto &GlobalFunction : API.getGlobalFunctions())
|
||||
getDerived()->visitGlobalFunctionRecord(*GlobalFunction.second);
|
||||
}
|
||||
|
||||
void traverseGlobalVariableRecords() {
|
||||
for (const auto &GlobalVariable : API.getGlobalVariables())
|
||||
getDerived()->visitGlobalVariableRecord(*GlobalVariable.second);
|
||||
}
|
||||
|
||||
void traverseEnumRecords() {
|
||||
for (const auto &Enum : API.getEnums())
|
||||
getDerived()->visitEnumRecord(*Enum.second);
|
||||
}
|
||||
|
||||
void traverseRecordRecords() {
|
||||
for (const auto &Record : API.getRecords())
|
||||
getDerived()->visitRecordRecord(*Record.second);
|
||||
}
|
||||
|
||||
void traverseStaticFieldRecords() {
|
||||
for (const auto &StaticField : API.getStaticFields())
|
||||
getDerived()->visitStaticFieldRecord(*StaticField.second);
|
||||
}
|
||||
|
||||
void traverseCXXClassRecords() {
|
||||
for (const auto &Class : API.getCXXClasses())
|
||||
getDerived()->visitCXXClassRecord(*Class.second);
|
||||
}
|
||||
|
||||
void traverseCXXMethodTemplates() {
|
||||
for (const auto &MethodTemplate : API.getCXXMethodTemplates())
|
||||
getDerived()->visitMethodTemplateRecord(*MethodTemplate.second);
|
||||
}
|
||||
|
||||
void traverseCXXMethodTemplateSpecializations() {
|
||||
for (const auto &MethodTemplateSpecialization :
|
||||
API.getCXXMethodTemplateSpecializations())
|
||||
getDerived()->visitMethodTemplateSpecializationRecord(
|
||||
*MethodTemplateSpecialization.second);
|
||||
}
|
||||
|
||||
void traverseClassTemplateRecords() {
|
||||
for (const auto &ClassTemplate : API.getClassTemplates())
|
||||
getDerived()->visitClassTemplateRecord(*ClassTemplate.second);
|
||||
}
|
||||
|
||||
void traverseClassTemplateSpecializationRecords() {
|
||||
for (const auto &ClassTemplateSpecialization :
|
||||
API.getClassTemplateSpecializations())
|
||||
getDerived()->visitClassTemplateSpecializationRecord(
|
||||
*ClassTemplateSpecialization.second);
|
||||
}
|
||||
|
||||
void traverseClassTemplatePartialSpecializationRecords() {
|
||||
for (const auto &ClassTemplatePartialSpecialization :
|
||||
API.getClassTemplatePartialSpecializations())
|
||||
getDerived()->visitClassTemplatePartialSpecializationRecord(
|
||||
*ClassTemplatePartialSpecialization.second);
|
||||
}
|
||||
|
||||
void traverseCXXInstanceMethods() {
|
||||
for (const auto &InstanceMethod : API.getCXXInstanceMethods())
|
||||
getDerived()->visitCXXInstanceMethodRecord(*InstanceMethod.second);
|
||||
}
|
||||
|
||||
void traverseCXXStaticMethods() {
|
||||
for (const auto &InstanceMethod : API.getCXXStaticMethods())
|
||||
getDerived()->visitCXXStaticMethodRecord(*InstanceMethod.second);
|
||||
}
|
||||
|
||||
void traverseCXXFields() {
|
||||
for (const auto &CXXField : API.getCXXFields())
|
||||
getDerived()->visitCXXFieldRecord(*CXXField.second);
|
||||
}
|
||||
|
||||
void traverseCXXFieldTemplates() {
|
||||
for (const auto &CXXFieldTemplate : API.getCXXFieldTemplates())
|
||||
getDerived()->visitCXXFieldTemplateRecord(*CXXFieldTemplate.second);
|
||||
}
|
||||
|
||||
void traverseGlobalVariableTemplateRecords() {
|
||||
for (const auto &GlobalVariableTemplate : API.getGlobalVariableTemplates())
|
||||
getDerived()->visitGlobalVariableTemplateRecord(
|
||||
*GlobalVariableTemplate.second);
|
||||
}
|
||||
|
||||
void traverseGlobalVariableTemplateSpecializationRecords() {
|
||||
for (const auto &GlobalVariableTemplateSpecialization :
|
||||
API.getGlobalVariableTemplateSpecializations())
|
||||
getDerived()->visitGlobalVariableTemplateSpecializationRecord(
|
||||
*GlobalVariableTemplateSpecialization.second);
|
||||
}
|
||||
|
||||
void traverseGlobalVariableTemplatePartialSpecializationRecords() {
|
||||
for (const auto &GlobalVariableTemplatePartialSpecialization :
|
||||
API.getGlobalVariableTemplatePartialSpecializations())
|
||||
getDerived()->visitGlobalVariableTemplatePartialSpecializationRecord(
|
||||
*GlobalVariableTemplatePartialSpecialization.second);
|
||||
}
|
||||
|
||||
void traverseGlobalFunctionTemplateRecords() {
|
||||
for (const auto &GlobalFunctionTemplate : API.getGlobalFunctionTemplates())
|
||||
getDerived()->visitGlobalFunctionTemplateRecord(
|
||||
*GlobalFunctionTemplate.second);
|
||||
}
|
||||
|
||||
void traverseGlobalFunctionTemplateSpecializationRecords() {
|
||||
for (const auto &GlobalFunctionTemplateSpecialization :
|
||||
API.getGlobalFunctionTemplateSpecializations())
|
||||
getDerived()->visitGlobalFunctionTemplateSpecializationRecord(
|
||||
*GlobalFunctionTemplateSpecialization.second);
|
||||
}
|
||||
|
||||
void traverseConcepts() {
|
||||
for (const auto &Concept : API.getConcepts())
|
||||
getDerived()->visitConceptRecord(*Concept.second);
|
||||
}
|
||||
|
||||
void traverseObjCInterfaces() {
|
||||
for (const auto &Interface : API.getObjCInterfaces())
|
||||
getDerived()->visitObjCContainerRecord(*Interface.second);
|
||||
}
|
||||
|
||||
void traverseObjCProtocols() {
|
||||
for (const auto &Protocol : API.getObjCProtocols())
|
||||
getDerived()->visitObjCContainerRecord(*Protocol.second);
|
||||
}
|
||||
|
||||
void traverseObjCCategories() {
|
||||
for (const auto &Category : API.getObjCCategories())
|
||||
getDerived()->visitObjCCategoryRecord(*Category.second);
|
||||
}
|
||||
|
||||
void traverseMacroDefinitionRecords() {
|
||||
for (const auto &Macro : API.getMacros())
|
||||
getDerived()->visitMacroDefinitionRecord(*Macro.second);
|
||||
}
|
||||
|
||||
void traverseTypedefRecords() {
|
||||
for (const auto &Typedef : API.getTypedefs())
|
||||
getDerived()->visitTypedefRecord(*Typedef.second);
|
||||
}
|
||||
|
||||
void visitNamespaceRecord(const NamespaceRecord &Record){};
|
||||
|
||||
/// Visit a global function record.
|
||||
void visitGlobalFunctionRecord(const GlobalFunctionRecord &Record){};
|
||||
|
||||
/// Visit a global variable record.
|
||||
void visitGlobalVariableRecord(const GlobalVariableRecord &Record){};
|
||||
|
||||
/// Visit an enum record.
|
||||
void visitEnumRecord(const EnumRecord &Record){};
|
||||
|
||||
/// Visit a record record.
|
||||
void visitRecordRecord(const RecordRecord &Record){};
|
||||
|
||||
void visitStaticFieldRecord(const StaticFieldRecord &Record){};
|
||||
|
||||
void visitCXXClassRecord(const CXXClassRecord &Record){};
|
||||
|
||||
void visitClassTemplateRecord(const ClassTemplateRecord &Record){};
|
||||
|
||||
void visitClassTemplateSpecializationRecord(
|
||||
const ClassTemplateSpecializationRecord &Record){};
|
||||
|
||||
void visitClassTemplatePartialSpecializationRecord(
|
||||
const ClassTemplatePartialSpecializationRecord &Record){};
|
||||
|
||||
void visitCXXInstanceRecord(const CXXInstanceMethodRecord &Record){};
|
||||
|
||||
void visitCXXStaticRecord(const CXXStaticMethodRecord &Record){};
|
||||
|
||||
void visitMethodTemplateRecord(const CXXMethodTemplateRecord &Record){};
|
||||
|
||||
void visitMethodTemplateSpecializationRecord(
|
||||
const CXXMethodTemplateSpecializationRecord &Record){};
|
||||
|
||||
void visitCXXFieldTemplateRecord(const CXXFieldTemplateRecord &Record){};
|
||||
|
||||
void visitGlobalVariableTemplateRecord(
|
||||
const GlobalVariableTemplateRecord &Record) {}
|
||||
|
||||
void visitGlobalVariableTemplateSpecializationRecord(
|
||||
const GlobalVariableTemplateSpecializationRecord &Record){};
|
||||
|
||||
void visitGlobalVariableTemplatePartialSpecializationRecord(
|
||||
const GlobalVariableTemplatePartialSpecializationRecord &Record){};
|
||||
|
||||
void visitGlobalFunctionTemplateRecord(
|
||||
const GlobalFunctionTemplateRecord &Record){};
|
||||
|
||||
void visitGlobalFunctionTemplateSpecializationRecord(
|
||||
const GlobalFunctionTemplateSpecializationRecord &Record){};
|
||||
|
||||
/// Visit an Objective-C container record.
|
||||
void visitObjCContainerRecord(const ObjCContainerRecord &Record){};
|
||||
|
||||
/// Visit an Objective-C category record.
|
||||
void visitObjCCategoryRecord(const ObjCCategoryRecord &Record){};
|
||||
|
||||
/// Visit a macro definition record.
|
||||
void visitMacroDefinitionRecord(const MacroDefinitionRecord &Record){};
|
||||
|
||||
/// Visit a typedef record.
|
||||
void visitTypedefRecord(const TypedefRecord &Record){};
|
||||
|
||||
protected:
|
||||
const APISet &API;
|
||||
|
||||
public:
|
||||
APISetVisitor() = delete;
|
||||
APISetVisitor(const APISetVisitor &) = delete;
|
||||
APISetVisitor(APISetVisitor &&) = delete;
|
||||
APISetVisitor &operator=(const APISetVisitor &) = delete;
|
||||
APISetVisitor &operator=(APISetVisitor &&) = delete;
|
||||
|
||||
protected:
|
||||
APISetVisitor(const APISet &API) : API(API) {}
|
||||
~APISetVisitor() = default;
|
||||
|
||||
Derived *getDerived() { return static_cast<Derived *>(this); };
|
||||
};
|
||||
|
||||
} // namespace extractapi
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
|
@ -17,17 +17,11 @@
|
||||
#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
|
||||
#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
|
||||
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "clang/ExtractAPI/API.h"
|
||||
#include "clang/ExtractAPI/APIIgnoresList.h"
|
||||
#include "clang/ExtractAPI/Serialization/APISetVisitor.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "clang/ExtractAPI/Serialization/SerializerBase.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/JSON.h"
|
||||
#include "llvm/Support/VersionTuple.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -41,30 +35,7 @@ using namespace llvm::json;
|
||||
/// Common options to customize the visitor output.
|
||||
struct SymbolGraphSerializerOption {
|
||||
/// Do not include unnecessary whitespaces to save space.
|
||||
bool Compact = true;
|
||||
bool EmitSymbolLabelsForTesting = false;
|
||||
};
|
||||
|
||||
/// A representation of the contents of a given module symbol graph
|
||||
struct ExtendedModule {
|
||||
ExtendedModule() = default;
|
||||
ExtendedModule(ExtendedModule &&EM) = default;
|
||||
ExtendedModule &operator=(ExtendedModule &&EM) = default;
|
||||
// Copies are expensive so disable them.
|
||||
ExtendedModule(const ExtendedModule &EM) = delete;
|
||||
ExtendedModule &operator=(const ExtendedModule &EM) = delete;
|
||||
|
||||
/// Add a symbol to the module, do not store the resulting pointer or use it
|
||||
/// across insertions.
|
||||
Object *addSymbol(Object &&Symbol);
|
||||
|
||||
void addRelationship(Object &&Relationship);
|
||||
|
||||
/// A JSON array of formatted symbols from an \c APISet.
|
||||
Array Symbols;
|
||||
|
||||
/// A JSON array of formatted symbol relationships from an \c APISet.
|
||||
Array Relationships;
|
||||
bool Compact;
|
||||
};
|
||||
|
||||
/// The visitor that organizes API information in the Symbol Graph format.
|
||||
@ -73,54 +44,28 @@ struct ExtendedModule {
|
||||
/// models an API set as a directed graph, where nodes are symbol declarations,
|
||||
/// and edges are relationships between the connected symbols.
|
||||
class SymbolGraphSerializer : public APISetVisitor<SymbolGraphSerializer> {
|
||||
private:
|
||||
using Base = APISetVisitor<SymbolGraphSerializer>;
|
||||
/// The main symbol graph that contains symbols that are either top-level or a
|
||||
/// are related to symbols defined in this product/module.
|
||||
ExtendedModule MainModule;
|
||||
/// A JSON array of formatted symbols in \c APISet.
|
||||
Array Symbols;
|
||||
|
||||
/// Additional symbol graphs that contain symbols that are related to symbols
|
||||
/// defined in another product/module. The key of this map is the module name
|
||||
/// of the extended module.
|
||||
llvm::StringMap<ExtendedModule> ExtendedModules;
|
||||
/// A JSON array of formatted symbol relationships in \c APISet.
|
||||
Array Relationships;
|
||||
|
||||
/// The Symbol Graph format version used by this serializer.
|
||||
static const VersionTuple FormatVersion;
|
||||
|
||||
/// Indicates whether to take into account the extended module. This is only
|
||||
/// Indicates whether child symbols should be visited. This is mainly
|
||||
/// useful for \c serializeSingleSymbolSGF.
|
||||
bool ForceEmitToMainModule;
|
||||
|
||||
// Stores the references required to construct path components for the
|
||||
// currently visited APIRecord.
|
||||
llvm::SmallVector<SymbolReference, 8> Hierarchy;
|
||||
|
||||
/// The list of symbols to ignore.
|
||||
///
|
||||
/// Note: This should be consulted before emitting a symbol.
|
||||
const APIIgnoresList &IgnoresList;
|
||||
|
||||
const bool EmitSymbolLabelsForTesting = false;
|
||||
|
||||
/// The object instantiated by the last call to serializeAPIRecord.
|
||||
Object *CurrentSymbol = nullptr;
|
||||
|
||||
/// The module to which \p CurrentSymbol belongs too.
|
||||
ExtendedModule *ModuleForCurrentSymbol = nullptr;
|
||||
bool ShouldRecurse;
|
||||
|
||||
public:
|
||||
static void
|
||||
serializeMainSymbolGraph(raw_ostream &OS, const APISet &API,
|
||||
const APIIgnoresList &IgnoresList,
|
||||
SymbolGraphSerializerOption Options = {});
|
||||
/// Serialize the APIs in \c APISet in the Symbol Graph format.
|
||||
///
|
||||
/// \returns a JSON object that contains the root of the formatted
|
||||
/// Symbol Graph.
|
||||
Object serialize();
|
||||
|
||||
static void serializeWithExtensionGraphs(
|
||||
raw_ostream &MainOutput, const APISet &API,
|
||||
const APIIgnoresList &IgnoresList,
|
||||
llvm::function_ref<
|
||||
std::unique_ptr<llvm::raw_pwrite_stream>(llvm::Twine BaseFileName)>
|
||||
CreateOutputStream,
|
||||
SymbolGraphSerializerOption Options = {});
|
||||
/// Wrap serialize(void) and write out the serialized JSON object to \p os.
|
||||
void serialize(raw_ostream &os);
|
||||
|
||||
/// Serialize a single symbol SGF. This is primarily used for libclang.
|
||||
///
|
||||
@ -130,7 +75,6 @@ public:
|
||||
static std::optional<Object> serializeSingleSymbolSGF(StringRef USR,
|
||||
const APISet &API);
|
||||
|
||||
private:
|
||||
/// The kind of a relationship between two symbols.
|
||||
enum RelationshipKind {
|
||||
/// The source symbol is a member of the target symbol.
|
||||
@ -150,32 +94,16 @@ private:
|
||||
ExtensionTo,
|
||||
};
|
||||
|
||||
/// Serialize a single record.
|
||||
void serializeSingleRecord(const APIRecord *Record);
|
||||
|
||||
/// Get the string representation of the relationship kind.
|
||||
static StringRef getRelationshipString(RelationshipKind Kind);
|
||||
|
||||
void serializeRelationship(RelationshipKind Kind,
|
||||
const SymbolReference &Source,
|
||||
const SymbolReference &Target,
|
||||
ExtendedModule &Into);
|
||||
|
||||
enum ConstraintKind { Conformance, ConditionalConformance };
|
||||
|
||||
static StringRef getConstraintString(ConstraintKind Kind);
|
||||
|
||||
/// Serialize the APIs in \c ExtendedModule.
|
||||
///
|
||||
/// \returns a JSON object that contains the root of the formatted
|
||||
/// Symbol Graph.
|
||||
Object serializeGraph(StringRef ModuleName, ExtendedModule &&EM);
|
||||
|
||||
/// Serialize the APIs in \c ExtendedModule in the Symbol Graph format and
|
||||
/// write them to the provide stream.
|
||||
void serializeGraphToStream(raw_ostream &OS,
|
||||
SymbolGraphSerializerOption Options,
|
||||
StringRef ModuleName, ExtendedModule &&EM);
|
||||
private:
|
||||
/// Just serialize the currently recorded objects in Symbol Graph format.
|
||||
Object serializeCurrentGraph();
|
||||
|
||||
/// Synthesize the metadata section of the Symbol Graph format.
|
||||
///
|
||||
@ -189,92 +117,124 @@ private:
|
||||
/// by the given API set.
|
||||
/// Note that "module" here is not to be confused with the Clang/C++ module
|
||||
/// concept.
|
||||
Object serializeModuleObject(StringRef ModuleName) const;
|
||||
|
||||
Array serializePathComponents(const APIRecord *Record) const;
|
||||
Object serializeModule() const;
|
||||
|
||||
/// Determine if the given \p Record should be skipped during serialization.
|
||||
bool shouldSkip(const APIRecord *Record) const;
|
||||
|
||||
ExtendedModule &getModuleForCurrentSymbol();
|
||||
bool shouldSkip(const APIRecord &Record) const;
|
||||
|
||||
/// Format the common API information for \p Record.
|
||||
///
|
||||
/// This handles the shared information of all kinds of API records,
|
||||
/// for example identifier, source location and path components. The resulting
|
||||
/// object is then augmented with kind-specific symbol information in
|
||||
/// subsequent visit* methods by accessing the \p State member variable. This
|
||||
/// method also checks if the given \p Record should be skipped during
|
||||
/// serialization. This should be called only once per concrete APIRecord
|
||||
/// instance and the first visit* method to be called is responsible for
|
||||
/// calling this. This is normally visitAPIRecord unless a walkUpFromFoo
|
||||
/// method is implemented along the inheritance hierarchy in which case the
|
||||
/// visitFoo method needs to call this.
|
||||
/// for example identifier and source location. The resulting object is then
|
||||
/// augmented with kind-specific symbol information by the caller.
|
||||
/// This method also checks if the given \p Record should be skipped during
|
||||
/// serialization.
|
||||
///
|
||||
/// \returns \c nullptr if this \p Record should be skipped, or a pointer to
|
||||
/// JSON object containing common symbol information of \p Record. Do not
|
||||
/// store the returned pointer only use it to augment the object with record
|
||||
/// specific information as it directly points to the object in the
|
||||
/// \p ExtendedModule, the pointer won't be valid as soon as another object is
|
||||
/// inserted into the module.
|
||||
void serializeAPIRecord(const APIRecord *Record);
|
||||
/// \returns \c std::nullopt if this \p Record should be skipped, or a JSON
|
||||
/// object containing common symbol information of \p Record.
|
||||
template <typename RecordTy>
|
||||
std::optional<Object> serializeAPIRecord(const RecordTy &Record) const;
|
||||
|
||||
/// Helper method to serialize second-level member records of \p Record and
|
||||
/// the member-of relationships.
|
||||
template <typename MemberTy>
|
||||
void serializeMembers(const APIRecord &Record,
|
||||
const SmallVector<std::unique_ptr<MemberTy>> &Members);
|
||||
|
||||
/// Serialize the \p Kind relationship between \p Source and \p Target.
|
||||
///
|
||||
/// Record the relationship between the two symbols in
|
||||
/// SymbolGraphSerializer::Relationships.
|
||||
void serializeRelationship(RelationshipKind Kind, SymbolReference Source,
|
||||
SymbolReference Target);
|
||||
|
||||
protected:
|
||||
/// The list of symbols to ignore.
|
||||
///
|
||||
/// Note: This should be consulted before emitting a symbol.
|
||||
const APIIgnoresList &IgnoresList;
|
||||
|
||||
SymbolGraphSerializerOption Options;
|
||||
|
||||
llvm::StringSet<> visitedCategories;
|
||||
|
||||
public:
|
||||
// Handle if records should be skipped at this level of the traversal to
|
||||
// ensure that children of skipped records aren't serialized.
|
||||
bool traverseAPIRecord(const APIRecord *Record);
|
||||
|
||||
bool visitAPIRecord(const APIRecord *Record);
|
||||
void visitNamespaceRecord(const NamespaceRecord &Record);
|
||||
|
||||
/// Visit a global function record.
|
||||
bool visitGlobalFunctionRecord(const GlobalFunctionRecord *Record);
|
||||
void visitGlobalFunctionRecord(const GlobalFunctionRecord &Record);
|
||||
|
||||
bool visitCXXClassRecord(const CXXClassRecord *Record);
|
||||
/// Visit a global variable record.
|
||||
void visitGlobalVariableRecord(const GlobalVariableRecord &Record);
|
||||
|
||||
bool visitClassTemplateRecord(const ClassTemplateRecord *Record);
|
||||
/// Visit an enum record.
|
||||
void visitEnumRecord(const EnumRecord &Record);
|
||||
|
||||
bool visitClassTemplatePartialSpecializationRecord(
|
||||
const ClassTemplatePartialSpecializationRecord *Record);
|
||||
/// Visit a record record.
|
||||
void visitRecordRecord(const RecordRecord &Record);
|
||||
|
||||
bool visitCXXMethodRecord(const CXXMethodRecord *Record);
|
||||
void visitStaticFieldRecord(const StaticFieldRecord &Record);
|
||||
|
||||
bool visitCXXMethodTemplateRecord(const CXXMethodTemplateRecord *Record);
|
||||
void visitCXXClassRecord(const CXXClassRecord &Record);
|
||||
|
||||
bool visitCXXFieldTemplateRecord(const CXXFieldTemplateRecord *Record);
|
||||
void visitClassTemplateRecord(const ClassTemplateRecord &Record);
|
||||
|
||||
bool visitConceptRecord(const ConceptRecord *Record);
|
||||
void visitClassTemplateSpecializationRecord(
|
||||
const ClassTemplateSpecializationRecord &Record);
|
||||
|
||||
bool
|
||||
visitGlobalVariableTemplateRecord(const GlobalVariableTemplateRecord *Record);
|
||||
void visitClassTemplatePartialSpecializationRecord(
|
||||
const ClassTemplatePartialSpecializationRecord &Record);
|
||||
|
||||
bool visitGlobalVariableTemplatePartialSpecializationRecord(
|
||||
const GlobalVariableTemplatePartialSpecializationRecord *Record);
|
||||
void visitCXXInstanceMethodRecord(const CXXInstanceMethodRecord &Record);
|
||||
|
||||
bool
|
||||
visitGlobalFunctionTemplateRecord(const GlobalFunctionTemplateRecord *Record);
|
||||
void visitCXXStaticMethodRecord(const CXXStaticMethodRecord &Record);
|
||||
|
||||
bool visitObjCContainerRecord(const ObjCContainerRecord *Record);
|
||||
void visitMethodTemplateRecord(const CXXMethodTemplateRecord &Record);
|
||||
|
||||
bool visitObjCInterfaceRecord(const ObjCInterfaceRecord *Record);
|
||||
void visitMethodTemplateSpecializationRecord(
|
||||
const CXXMethodTemplateSpecializationRecord &Record);
|
||||
|
||||
bool traverseObjCCategoryRecord(const ObjCCategoryRecord *Record);
|
||||
bool walkUpFromObjCCategoryRecord(const ObjCCategoryRecord *Record);
|
||||
bool visitObjCCategoryRecord(const ObjCCategoryRecord *Record);
|
||||
void visitCXXFieldRecord(const CXXFieldRecord &Record);
|
||||
|
||||
bool visitObjCMethodRecord(const ObjCMethodRecord *Record);
|
||||
void visitCXXFieldTemplateRecord(const CXXFieldTemplateRecord &Record);
|
||||
|
||||
bool
|
||||
visitObjCInstanceVariableRecord(const ObjCInstanceVariableRecord *Record);
|
||||
void visitConceptRecord(const ConceptRecord &Record);
|
||||
|
||||
bool walkUpFromTypedefRecord(const TypedefRecord *Record);
|
||||
bool visitTypedefRecord(const TypedefRecord *Record);
|
||||
void
|
||||
visitGlobalVariableTemplateRecord(const GlobalVariableTemplateRecord &Record);
|
||||
|
||||
void visitGlobalVariableTemplateSpecializationRecord(
|
||||
const GlobalVariableTemplateSpecializationRecord &Record);
|
||||
|
||||
void visitGlobalVariableTemplatePartialSpecializationRecord(
|
||||
const GlobalVariableTemplatePartialSpecializationRecord &Record);
|
||||
|
||||
void
|
||||
visitGlobalFunctionTemplateRecord(const GlobalFunctionTemplateRecord &Record);
|
||||
|
||||
void visitGlobalFunctionTemplateSpecializationRecord(
|
||||
const GlobalFunctionTemplateSpecializationRecord &Record);
|
||||
|
||||
/// Visit an Objective-C container record.
|
||||
void visitObjCContainerRecord(const ObjCContainerRecord &Record);
|
||||
|
||||
/// Visit an Objective-C category record.
|
||||
void visitObjCCategoryRecord(const ObjCCategoryRecord &Record);
|
||||
|
||||
/// Visit a macro definition record.
|
||||
void visitMacroDefinitionRecord(const MacroDefinitionRecord &Record);
|
||||
|
||||
/// Visit a typedef record.
|
||||
void visitTypedefRecord(const TypedefRecord &Record);
|
||||
|
||||
/// Serialize a single record.
|
||||
void serializeSingleRecord(const APIRecord *Record);
|
||||
|
||||
SymbolGraphSerializer(const APISet &API, const APIIgnoresList &IgnoresList,
|
||||
bool EmitSymbolLabelsForTesting = false,
|
||||
bool ForceEmitToMainModule = false)
|
||||
: Base(API), ForceEmitToMainModule(ForceEmitToMainModule),
|
||||
IgnoresList(IgnoresList),
|
||||
EmitSymbolLabelsForTesting(EmitSymbolLabelsForTesting) {}
|
||||
SymbolGraphSerializerOption Options = {},
|
||||
bool ShouldRecurse = true)
|
||||
: APISetVisitor(API), ShouldRecurse(ShouldRecurse),
|
||||
IgnoresList(IgnoresList), Options(Options) {}
|
||||
};
|
||||
|
||||
} // namespace extractapi
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "clang/Sema/CodeCompleteOptions.h"
|
||||
#include "clang/Serialization/ModuleFileExtension.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
@ -388,22 +387,6 @@ public:
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned ModulesShareFileManager : 1;
|
||||
|
||||
/// Whether to emit symbol graph files as a side effect of compilation.
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned EmitSymbolGraph : 1;
|
||||
|
||||
/// Whether to emit additional symbol graphs for extended modules.
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned EmitExtensionSymbolGraphs : 1;
|
||||
|
||||
/// Whether to emit symbol labels for testing in generated symbol graphs
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned EmitSymbolGraphSymbolLabelsForTesting : 1;
|
||||
|
||||
/// Whether to emit symbol labels for testing in generated symbol graphs
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned EmitPrettySymbolGraphs : 1;
|
||||
|
||||
CodeCompleteOptions CodeCompleteOpts;
|
||||
|
||||
/// Specifies the output format of the AST.
|
||||
@ -513,8 +496,10 @@ public:
|
||||
// ignore when extracting documentation.
|
||||
std::vector<std::string> ExtractAPIIgnoresFileList;
|
||||
|
||||
// Currently this is only used as part of the `-emit-symbol-graph`
|
||||
// action.
|
||||
// Location of output directory where symbol graph information would
|
||||
// be dumped. This overrides regular -o output file specification
|
||||
// be dumped
|
||||
std::string SymbolGraphOutputDir;
|
||||
|
||||
/// Args to pass to the plugins
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "ToolChains/WebAssembly.h"
|
||||
#include "ToolChains/XCore.h"
|
||||
#include "ToolChains/ZOS.h"
|
||||
#include "clang/Basic/DiagnosticDriver.h"
|
||||
#include "clang/Basic/TargetID.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Config/config.h"
|
||||
@ -5890,12 +5889,6 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
|
||||
&JA);
|
||||
}
|
||||
|
||||
if (JA.getType() == types::TY_API_INFO &&
|
||||
C.getArgs().hasArg(options::OPT_emit_extension_symbol_graphs) &&
|
||||
C.getArgs().hasArg(options::OPT_o))
|
||||
Diag(clang::diag::err_drv_unexpected_symbol_graph_output)
|
||||
<< C.getArgs().getLastArgValue(options::OPT_o);
|
||||
|
||||
// DXC defaults to standard out when generating assembly. We check this after
|
||||
// any DXC flags that might specify a file.
|
||||
if (AtTopLevel && JA.getType() == types::TY_PP_Asm && IsDXCMode())
|
||||
|
@ -5037,26 +5037,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
assert(JA.getType() == types::TY_API_INFO &&
|
||||
"Extract API actions must generate a API information.");
|
||||
CmdArgs.push_back("-extract-api");
|
||||
|
||||
if (Arg *PrettySGFArg = Args.getLastArg(options::OPT_emit_pretty_sgf))
|
||||
PrettySGFArg->render(Args, CmdArgs);
|
||||
|
||||
Arg *SymbolGraphDirArg = Args.getLastArg(options::OPT_symbol_graph_dir_EQ);
|
||||
|
||||
if (Arg *ProductNameArg = Args.getLastArg(options::OPT_product_name_EQ))
|
||||
ProductNameArg->render(Args, CmdArgs);
|
||||
if (Arg *ExtractAPIIgnoresFileArg =
|
||||
Args.getLastArg(options::OPT_extract_api_ignores_EQ))
|
||||
ExtractAPIIgnoresFileArg->render(Args, CmdArgs);
|
||||
if (Arg *EmitExtensionSymbolGraphs =
|
||||
Args.getLastArg(options::OPT_emit_extension_symbol_graphs)) {
|
||||
if (!SymbolGraphDirArg)
|
||||
D.Diag(diag::err_drv_missing_symbol_graph_dir);
|
||||
|
||||
EmitExtensionSymbolGraphs->render(Args, CmdArgs);
|
||||
}
|
||||
if (SymbolGraphDirArg)
|
||||
SymbolGraphDirArg->render(Args, CmdArgs);
|
||||
} else {
|
||||
assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&
|
||||
"Invalid action for clang tool.");
|
||||
|
@ -13,67 +13,514 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/ExtractAPI/API.h"
|
||||
#include "clang/AST/CommentCommandTraits.h"
|
||||
#include "clang/AST/CommentLexer.h"
|
||||
#include "clang/AST/RawCommentList.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "clang/Index/USRGeneration.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace clang::extractapi;
|
||||
using namespace llvm;
|
||||
|
||||
SymbolReference::SymbolReference(const APIRecord *R)
|
||||
: Name(R->Name), USR(R->USR), Record(R) {}
|
||||
namespace {
|
||||
|
||||
APIRecord *APIRecord::castFromRecordContext(const RecordContext *Ctx) {
|
||||
switch (Ctx->getKind()) {
|
||||
#define RECORD_CONTEXT(CLASS, KIND) \
|
||||
case KIND: \
|
||||
return static_cast<CLASS *>(const_cast<RecordContext *>(Ctx));
|
||||
#include "clang/ExtractAPI/APIRecords.inc"
|
||||
default:
|
||||
return nullptr;
|
||||
// llvm_unreachable("RecordContext derived class isn't propertly
|
||||
// implemented");
|
||||
}
|
||||
template <typename RecordTy, typename... CtorArgsTy>
|
||||
RecordTy *addTopLevelRecord(DenseMap<StringRef, APIRecord *> &USRLookupTable,
|
||||
APISet::RecordMap<RecordTy> &RecordMap,
|
||||
StringRef USR, CtorArgsTy &&...CtorArgs) {
|
||||
auto Result = RecordMap.insert({USR, nullptr});
|
||||
|
||||
// Create the record if it does not already exist
|
||||
if (Result.second)
|
||||
Result.first->second =
|
||||
std::make_unique<RecordTy>(USR, std::forward<CtorArgsTy>(CtorArgs)...);
|
||||
|
||||
auto *Record = Result.first->second.get();
|
||||
USRLookupTable.insert({USR, Record});
|
||||
return Record;
|
||||
}
|
||||
|
||||
RecordContext *APIRecord::castToRecordContext(const APIRecord *Record) {
|
||||
if (!Record)
|
||||
return nullptr;
|
||||
switch (Record->getKind()) {
|
||||
#define RECORD_CONTEXT(CLASS, KIND) \
|
||||
case KIND: \
|
||||
return static_cast<CLASS *>(const_cast<APIRecord *>(Record));
|
||||
#include "clang/ExtractAPI/APIRecords.inc"
|
||||
default:
|
||||
return nullptr;
|
||||
// llvm_unreachable("RecordContext derived class isn't propertly
|
||||
// implemented");
|
||||
}
|
||||
} // namespace
|
||||
|
||||
NamespaceRecord *
|
||||
APISet::addNamespace(APIRecord *Parent, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
LinkageInfo Linkage, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader) {
|
||||
auto *Record = addTopLevelRecord(
|
||||
USRBasedLookupTable, Namespaces, USR, Name, Loc, std::move(Availability),
|
||||
Linkage, Comment, Declaration, SubHeading, IsFromSystemHeader);
|
||||
|
||||
if (Parent)
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
return Record;
|
||||
}
|
||||
|
||||
void RecordContext::addToRecordChain(APIRecord *Record) const {
|
||||
if (!First) {
|
||||
First = Record;
|
||||
Last = Record;
|
||||
return;
|
||||
}
|
||||
GlobalVariableRecord *
|
||||
APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Fragments,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, GlobalVariables, USR, Name, Loc,
|
||||
std::move(Availability), Linkage, Comment, Fragments,
|
||||
SubHeading, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
Last->NextInContext = Record;
|
||||
Last = Record;
|
||||
GlobalVariableTemplateRecord *APISet::addGlobalVariableTemplate(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, GlobalVariableTemplates, USR,
|
||||
Name, Loc, std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, Template,
|
||||
IsFromSystemHeader);
|
||||
}
|
||||
|
||||
GlobalFunctionRecord *APISet::addGlobalFunction(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Fragments,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, GlobalFunctions, USR, Name, Loc,
|
||||
std::move(Availability), Linkage, Comment, Fragments,
|
||||
SubHeading, Signature, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
GlobalFunctionTemplateRecord *APISet::addGlobalFunctionTemplate(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
Template Template, bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, GlobalFunctionTemplates, USR,
|
||||
Name, Loc, std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, Signature, Template,
|
||||
IsFromSystemHeader);
|
||||
}
|
||||
|
||||
GlobalFunctionTemplateSpecializationRecord *
|
||||
APISet::addGlobalFunctionTemplateSpecialization(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, FunctionSignature Signature,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(
|
||||
USRBasedLookupTable, GlobalFunctionTemplateSpecializations, USR, Name,
|
||||
Loc, std::move(Availability), Linkage, Comment, Declaration, SubHeading,
|
||||
Signature, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
EnumConstantRecord *APISet::addEnumConstant(EnumRecord *Enum, StringRef Name,
|
||||
StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader) {
|
||||
auto Record = std::make_unique<EnumConstantRecord>(
|
||||
USR, Name, Loc, std::move(Availability), Comment, Declaration, SubHeading,
|
||||
IsFromSystemHeader);
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Enum->USR, Enum->Name, Enum->getKind(), Enum);
|
||||
USRBasedLookupTable.insert({USR, Record.get()});
|
||||
return Enum->Constants.emplace_back(std::move(Record)).get();
|
||||
}
|
||||
|
||||
EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, Enums, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
RecordFieldRecord *APISet::addRecordField(
|
||||
RecordRecord *Record, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
APIRecord::RecordKind Kind, bool IsFromSystemHeader) {
|
||||
auto RecordField = std::make_unique<RecordFieldRecord>(
|
||||
USR, Name, Loc, std::move(Availability), Comment, Declaration, SubHeading,
|
||||
Kind, IsFromSystemHeader);
|
||||
RecordField->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Record->USR, Record->Name, Record->getKind(), Record);
|
||||
USRBasedLookupTable.insert({USR, RecordField.get()});
|
||||
return Record->Fields.emplace_back(std::move(RecordField)).get();
|
||||
}
|
||||
|
||||
RecordRecord *APISet::addRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
APIRecord::RecordKind Kind,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, Records, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Kind, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
StaticFieldRecord *
|
||||
APISet::addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, SymbolReference Context,
|
||||
AccessControl Access, bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, StaticFields, USR, Name, Loc,
|
||||
std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, Context, Access,
|
||||
IsFromSystemHeader);
|
||||
}
|
||||
|
||||
CXXFieldRecord *
|
||||
APISet::addCXXField(APIRecord *CXXClass, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, AccessControl Access,
|
||||
bool IsFromSystemHeader) {
|
||||
auto *Record = addTopLevelRecord(
|
||||
USRBasedLookupTable, CXXFields, USR, Name, Loc, std::move(Availability),
|
||||
Comment, Declaration, SubHeading, Access, IsFromSystemHeader);
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
CXXClass->USR, CXXClass->Name, CXXClass->getKind(), CXXClass);
|
||||
return Record;
|
||||
}
|
||||
|
||||
CXXFieldTemplateRecord *APISet::addCXXFieldTemplate(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
AccessControl Access, Template Template, bool IsFromSystemHeader) {
|
||||
auto *Record =
|
||||
addTopLevelRecord(USRBasedLookupTable, CXXFieldTemplates, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Access, Template, IsFromSystemHeader);
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
|
||||
return Record;
|
||||
}
|
||||
|
||||
CXXClassRecord *
|
||||
APISet::addCXXClass(APIRecord *Parent, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
|
||||
AccessControl Access, bool IsFromSystemHeader) {
|
||||
auto *Record = addTopLevelRecord(
|
||||
USRBasedLookupTable, CXXClasses, USR, Name, Loc, std::move(Availability),
|
||||
Comment, Declaration, SubHeading, Kind, Access, IsFromSystemHeader);
|
||||
if (Parent)
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
return Record;
|
||||
}
|
||||
|
||||
ClassTemplateRecord *APISet::addClassTemplate(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
Template Template, AccessControl Access, bool IsFromSystemHeader) {
|
||||
auto *Record =
|
||||
addTopLevelRecord(USRBasedLookupTable, ClassTemplates, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Template, Access, IsFromSystemHeader);
|
||||
if (Parent)
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
return Record;
|
||||
}
|
||||
|
||||
ClassTemplateSpecializationRecord *APISet::addClassTemplateSpecialization(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
AccessControl Access, bool IsFromSystemHeader) {
|
||||
auto *Record =
|
||||
addTopLevelRecord(USRBasedLookupTable, ClassTemplateSpecializations, USR,
|
||||
Name, Loc, std::move(Availability), Comment,
|
||||
Declaration, SubHeading, Access, IsFromSystemHeader);
|
||||
if (Parent)
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
return Record;
|
||||
}
|
||||
|
||||
ClassTemplatePartialSpecializationRecord *
|
||||
APISet::addClassTemplatePartialSpecialization(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
Template Template, AccessControl Access, bool IsFromSystemHeader) {
|
||||
auto *Record = addTopLevelRecord(
|
||||
USRBasedLookupTable, ClassTemplatePartialSpecializations, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration, SubHeading, Template,
|
||||
Access, IsFromSystemHeader);
|
||||
if (Parent)
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
return Record;
|
||||
}
|
||||
|
||||
GlobalVariableTemplateSpecializationRecord *
|
||||
APISet::addGlobalVariableTemplateSpecialization(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable,
|
||||
GlobalVariableTemplateSpecializations, USR, Name,
|
||||
Loc, std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
GlobalVariableTemplatePartialSpecializationRecord *
|
||||
APISet::addGlobalVariableTemplatePartialSpecialization(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment, DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading, Template Template,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(
|
||||
USRBasedLookupTable, GlobalVariableTemplatePartialSpecializations, USR,
|
||||
Name, Loc, std::move(Availability), Linkage, Comment, Declaration,
|
||||
SubHeading, Template, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
ConceptRecord *APISet::addConcept(StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
Template Template, bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, Concepts, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Template, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
CXXMethodRecord *APISet::addCXXInstanceMethod(
|
||||
APIRecord *CXXClassRecord, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader) {
|
||||
CXXMethodRecord *Record =
|
||||
addTopLevelRecord(USRBasedLookupTable, CXXInstanceMethods, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader);
|
||||
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(),
|
||||
CXXClassRecord);
|
||||
return Record;
|
||||
}
|
||||
|
||||
CXXMethodRecord *APISet::addCXXStaticMethod(
|
||||
APIRecord *CXXClassRecord, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader) {
|
||||
CXXMethodRecord *Record =
|
||||
addTopLevelRecord(USRBasedLookupTable, CXXStaticMethods, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, Access, IsFromSystemHeader);
|
||||
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(),
|
||||
CXXClassRecord);
|
||||
return Record;
|
||||
}
|
||||
|
||||
CXXMethodTemplateRecord *APISet::addCXXMethodTemplate(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access, Template Template,
|
||||
bool IsFromSystemHeader) {
|
||||
auto *Record = addTopLevelRecord(USRBasedLookupTable, CXXMethodTemplates, USR,
|
||||
Name, Loc, std::move(Availability), Comment,
|
||||
Declaration, SubHeading, Signature, Access,
|
||||
Template, IsFromSystemHeader);
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
|
||||
return Record;
|
||||
}
|
||||
|
||||
CXXMethodTemplateSpecializationRecord *APISet::addCXXMethodTemplateSpec(
|
||||
APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, AccessControl Access,
|
||||
bool IsFromSystemHeader) {
|
||||
|
||||
auto *Record = addTopLevelRecord(
|
||||
USRBasedLookupTable, CXXMethodTemplateSpecializations, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration, SubHeading, Signature,
|
||||
Access, IsFromSystemHeader);
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Parent->USR, Parent->Name, Parent->getKind(), Parent);
|
||||
|
||||
return Record;
|
||||
}
|
||||
|
||||
ObjCCategoryRecord *APISet::addObjCCategory(
|
||||
StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
SymbolReference Interface, bool IsFromSystemHeader,
|
||||
bool IsFromExternalModule) {
|
||||
// Create the category record.
|
||||
auto *Record =
|
||||
addTopLevelRecord(USRBasedLookupTable, ObjCCategories, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Interface, IsFromSystemHeader);
|
||||
|
||||
Record->IsFromExternalModule = IsFromExternalModule;
|
||||
|
||||
auto It = ObjCInterfaces.find(Interface.USR);
|
||||
if (It != ObjCInterfaces.end())
|
||||
It->second->Categories.push_back(Record);
|
||||
|
||||
return Record;
|
||||
}
|
||||
|
||||
ObjCInterfaceRecord *
|
||||
APISet::addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, LinkageInfo Linkage,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
SymbolReference SuperClass, bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, ObjCInterfaces, USR, Name, Loc,
|
||||
std::move(Availability), Linkage, Comment,
|
||||
Declaration, SubHeading, SuperClass,
|
||||
IsFromSystemHeader);
|
||||
}
|
||||
|
||||
ObjCMethodRecord *APISet::addObjCMethod(
|
||||
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
FunctionSignature Signature, bool IsInstanceMethod,
|
||||
bool IsFromSystemHeader) {
|
||||
std::unique_ptr<ObjCMethodRecord> Record;
|
||||
if (IsInstanceMethod)
|
||||
Record = std::make_unique<ObjCInstanceMethodRecord>(
|
||||
USR, Name, Loc, std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, IsFromSystemHeader);
|
||||
else
|
||||
Record = std::make_unique<ObjCClassMethodRecord>(
|
||||
USR, Name, Loc, std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Signature, IsFromSystemHeader);
|
||||
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Container->USR, Container->Name, Container->getKind(), Container);
|
||||
USRBasedLookupTable.insert({USR, Record.get()});
|
||||
return Container->Methods.emplace_back(std::move(Record)).get();
|
||||
}
|
||||
|
||||
ObjCPropertyRecord *APISet::addObjCProperty(
|
||||
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName,
|
||||
StringRef SetterName, bool IsOptional, bool IsInstanceProperty,
|
||||
bool IsFromSystemHeader) {
|
||||
std::unique_ptr<ObjCPropertyRecord> Record;
|
||||
if (IsInstanceProperty)
|
||||
Record = std::make_unique<ObjCInstancePropertyRecord>(
|
||||
USR, Name, Loc, std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Attributes, GetterName, SetterName, IsOptional,
|
||||
IsFromSystemHeader);
|
||||
else
|
||||
Record = std::make_unique<ObjCClassPropertyRecord>(
|
||||
USR, Name, Loc, std::move(Availability), Comment, Declaration,
|
||||
SubHeading, Attributes, GetterName, SetterName, IsOptional,
|
||||
IsFromSystemHeader);
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Container->USR, Container->Name, Container->getKind(), Container);
|
||||
USRBasedLookupTable.insert({USR, Record.get()});
|
||||
return Container->Properties.emplace_back(std::move(Record)).get();
|
||||
}
|
||||
|
||||
ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable(
|
||||
ObjCContainerRecord *Container, StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration, DeclarationFragments SubHeading,
|
||||
ObjCInstanceVariableRecord::AccessControl Access, bool IsFromSystemHeader) {
|
||||
auto Record = std::make_unique<ObjCInstanceVariableRecord>(
|
||||
USR, Name, Loc, std::move(Availability), Comment, Declaration, SubHeading,
|
||||
Access, IsFromSystemHeader);
|
||||
Record->ParentInformation = APIRecord::HierarchyInformation(
|
||||
Container->USR, Container->Name, Container->getKind(), Container);
|
||||
USRBasedLookupTable.insert({USR, Record.get()});
|
||||
return Container->Ivars.emplace_back(std::move(Record)).get();
|
||||
}
|
||||
|
||||
ObjCProtocolRecord *APISet::addObjCProtocol(StringRef Name, StringRef USR,
|
||||
PresumedLoc Loc,
|
||||
AvailabilityInfo Availability,
|
||||
const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, ObjCProtocols, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
MacroDefinitionRecord *
|
||||
APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, Macros, USR, Name, Loc,
|
||||
Declaration, SubHeading, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
TypedefRecord *
|
||||
APISet::addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
|
||||
AvailabilityInfo Availability, const DocComment &Comment,
|
||||
DeclarationFragments Declaration,
|
||||
DeclarationFragments SubHeading,
|
||||
SymbolReference UnderlyingType, bool IsFromSystemHeader) {
|
||||
return addTopLevelRecord(USRBasedLookupTable, Typedefs, USR, Name, Loc,
|
||||
std::move(Availability), Comment, Declaration,
|
||||
SubHeading, UnderlyingType, IsFromSystemHeader);
|
||||
}
|
||||
|
||||
APIRecord *APISet::findRecordForUSR(StringRef USR) const {
|
||||
if (USR.empty())
|
||||
return nullptr;
|
||||
|
||||
auto FindIt = USRBasedLookupTable.find(USR);
|
||||
if (FindIt != USRBasedLookupTable.end())
|
||||
return FindIt->getSecond().get();
|
||||
return USRBasedLookupTable.lookup(USR);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
StringRef APISet::recordUSR(const Decl *D) {
|
||||
SmallString<128> USR;
|
||||
index::generateUSRForDecl(D, USR);
|
||||
return copyString(USR);
|
||||
}
|
||||
|
||||
StringRef APISet::recordUSRForMacro(StringRef Name, SourceLocation SL,
|
||||
const SourceManager &SM) {
|
||||
SmallString<128> USR;
|
||||
index::generateUSRForMacro(Name, SL, SM, USR);
|
||||
return copyString(USR);
|
||||
}
|
||||
|
||||
StringRef APISet::copyString(StringRef String) {
|
||||
@ -81,22 +528,15 @@ StringRef APISet::copyString(StringRef String) {
|
||||
return {};
|
||||
|
||||
// No need to allocate memory and copy if the string has already been stored.
|
||||
if (Allocator.identifyObject(String.data()))
|
||||
if (StringAllocator.identifyObject(String.data()))
|
||||
return String;
|
||||
|
||||
void *Ptr = Allocator.Allocate(String.size(), 1);
|
||||
void *Ptr = StringAllocator.Allocate(String.size(), 1);
|
||||
memcpy(Ptr, String.data(), String.size());
|
||||
return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
|
||||
}
|
||||
|
||||
SymbolReference APISet::createSymbolReference(StringRef Name, StringRef USR,
|
||||
StringRef Source) {
|
||||
return SymbolReference(copyString(Name), copyString(USR), copyString(Source));
|
||||
}
|
||||
|
||||
APIRecord::~APIRecord() {}
|
||||
RecordRecord::~RecordRecord() {}
|
||||
RecordFieldRecord::~RecordFieldRecord() {}
|
||||
ObjCContainerRecord::~ObjCContainerRecord() {}
|
||||
ObjCMethodRecord::~ObjCMethodRecord() {}
|
||||
ObjCPropertyRecord::~ObjCPropertyRecord() {}
|
||||
@ -106,10 +546,8 @@ void GlobalFunctionRecord::anchor() {}
|
||||
void GlobalVariableRecord::anchor() {}
|
||||
void EnumConstantRecord::anchor() {}
|
||||
void EnumRecord::anchor() {}
|
||||
void StructFieldRecord::anchor() {}
|
||||
void StructRecord::anchor() {}
|
||||
void UnionFieldRecord::anchor() {}
|
||||
void UnionRecord::anchor() {}
|
||||
void RecordFieldRecord::anchor() {}
|
||||
void RecordRecord::anchor() {}
|
||||
void CXXFieldRecord::anchor() {}
|
||||
void CXXClassRecord::anchor() {}
|
||||
void CXXConstructorRecord::anchor() {}
|
||||
|
@ -60,44 +60,23 @@ void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
|
||||
|
||||
} // namespace
|
||||
|
||||
DeclarationFragments &
|
||||
DeclarationFragments::appendUnduplicatedTextCharacter(char Character) {
|
||||
DeclarationFragments &DeclarationFragments::appendSpace() {
|
||||
if (!Fragments.empty()) {
|
||||
Fragment &Last = Fragments.back();
|
||||
if (Last.Kind == FragmentKind::Text) {
|
||||
// Merge the extra space into the last fragment if the last fragment is
|
||||
// also text.
|
||||
if (Last.Spelling.back() != Character) { // avoid duplicates at end
|
||||
Last.Spelling.push_back(Character);
|
||||
if (Last.Spelling.back() != ' ') { // avoid extra trailing spaces.
|
||||
Last.Spelling.push_back(' ');
|
||||
}
|
||||
} else {
|
||||
append("", FragmentKind::Text);
|
||||
Fragments.back().Spelling.push_back(Character);
|
||||
append(" ", FragmentKind::Text);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DeclarationFragments &DeclarationFragments::appendSpace() {
|
||||
return appendUnduplicatedTextCharacter(' ');
|
||||
}
|
||||
|
||||
DeclarationFragments &DeclarationFragments::appendSemicolon() {
|
||||
return appendUnduplicatedTextCharacter(';');
|
||||
}
|
||||
|
||||
DeclarationFragments &DeclarationFragments::removeTrailingSemicolon() {
|
||||
if (Fragments.empty())
|
||||
return *this;
|
||||
|
||||
Fragment &Last = Fragments.back();
|
||||
if (Last.Kind == FragmentKind::Text && Last.Spelling.back() == ';')
|
||||
Last.Spelling.pop_back();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringRef DeclarationFragments::getFragmentKindString(
|
||||
DeclarationFragments::FragmentKind Kind) {
|
||||
switch (Kind) {
|
||||
@ -490,7 +469,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForNamespace(
|
||||
if (!Decl->isAnonymousNamespace())
|
||||
Fragments.appendSpace().append(
|
||||
Decl->getName(), DeclarationFragments::FragmentKind::Identifier);
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -532,7 +511,7 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) {
|
||||
return Fragments
|
||||
.append(Var->getName(), DeclarationFragments::FragmentKind::Identifier)
|
||||
.append(std::move(After))
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -564,7 +543,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) {
|
||||
Fragments.append(std::move(ArgumentFragment))
|
||||
.appendSpace()
|
||||
.append(Var->getName(), DeclarationFragments::FragmentKind::Identifier)
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
return Fragments;
|
||||
}
|
||||
|
||||
@ -733,7 +712,7 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) {
|
||||
Fragments.append(DeclarationFragments::getExceptionSpecificationString(
|
||||
Func->getExceptionSpecType()));
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForEnumConstant(
|
||||
@ -762,7 +741,7 @@ DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) {
|
||||
getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After))
|
||||
.append(std::move(After));
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -778,7 +757,7 @@ DeclarationFragmentsBuilder::getFragmentsForField(const FieldDecl *Field) {
|
||||
.appendSpace()
|
||||
.append(Field->getName(), DeclarationFragments::FragmentKind::Identifier)
|
||||
.append(std::move(After))
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForRecordDecl(
|
||||
@ -796,7 +775,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForRecordDecl(
|
||||
Fragments.appendSpace().append(
|
||||
Record->getName(), DeclarationFragments::FragmentKind::Identifier);
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXClass(
|
||||
@ -811,7 +790,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXClass(
|
||||
Fragments.appendSpace().append(
|
||||
Record->getName(), DeclarationFragments::FragmentKind::Identifier);
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -841,7 +820,7 @@ DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(
|
||||
Fragments.append(DeclarationFragments::getExceptionSpecificationString(
|
||||
Method->getExceptionSpecType()));
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod(
|
||||
@ -881,7 +860,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod(
|
||||
Fragments.append(DeclarationFragments::getExceptionSpecificationString(
|
||||
Method->getExceptionSpecType()));
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -912,7 +891,7 @@ DeclarationFragmentsBuilder::getFragmentsForConversionFunction(
|
||||
Fragments.appendSpace().append("const",
|
||||
DeclarationFragments::FragmentKind::Keyword);
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -944,7 +923,7 @@ DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator(
|
||||
Fragments.append(DeclarationFragments::getExceptionSpecificationString(
|
||||
Method->getExceptionSpecType()));
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
// Get fragments for template parameters, e.g. T in tempalte<typename T> ...
|
||||
@ -1049,7 +1028,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForConcept(
|
||||
.appendSpace()
|
||||
.append(Concept->getName().str(),
|
||||
DeclarationFragments::FragmentKind::Identifier)
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -1090,7 +1069,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization(
|
||||
getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
|
||||
Decl->getASTContext(), std::nullopt))
|
||||
.append(">", DeclarationFragments::FragmentKind::Text)
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -1112,7 +1091,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization(
|
||||
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
|
||||
Decl->getTemplateParameters()->asArray()))
|
||||
.append(">", DeclarationFragments::FragmentKind::Text)
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -1131,7 +1110,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization(
|
||||
getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
|
||||
Decl->getASTContext(), std::nullopt))
|
||||
.append(">", DeclarationFragments::FragmentKind::Text)
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -1153,7 +1132,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization(
|
||||
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
|
||||
Decl->getTemplateParameters()->asArray()))
|
||||
.append(">", DeclarationFragments::FragmentKind::Text)
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments
|
||||
@ -1224,7 +1203,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory(
|
||||
|
||||
Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword)
|
||||
.appendSpace()
|
||||
.append(Interface->getName(),
|
||||
.append(Category->getClassInterface()->getName(),
|
||||
DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR,
|
||||
Interface)
|
||||
.append(" (", DeclarationFragments::FragmentKind::Text)
|
||||
@ -1298,7 +1277,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod(
|
||||
Fragments.append(getFragmentsForParam(Param));
|
||||
}
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty(
|
||||
@ -1399,7 +1378,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty(
|
||||
.append(Property->getName(),
|
||||
DeclarationFragments::FragmentKind::Identifier)
|
||||
.append(std::move(After))
|
||||
.appendSemicolon();
|
||||
.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(
|
||||
@ -1443,7 +1422,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef(
|
||||
.appendSpace()
|
||||
.append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier);
|
||||
|
||||
return Fragments.appendSemicolon();
|
||||
return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
|
||||
}
|
||||
|
||||
// Instantiate template for FunctionDecl.
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/FrontendOptions.h"
|
||||
#include "clang/Frontend/MultiplexConsumer.h"
|
||||
#include "clang/Index/USRGeneration.h"
|
||||
#include "clang/InstallAPI/HeaderFile.h"
|
||||
#include "clang/Lex/MacroInfo.h"
|
||||
#include "clang/Lex/PPCallbacks.h"
|
||||
@ -40,7 +39,6 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
@ -329,12 +327,11 @@ public:
|
||||
|
||||
StringRef Name = PM.MacroNameToken.getIdentifierInfo()->getName();
|
||||
PresumedLoc Loc = SM.getPresumedLoc(PM.MacroNameToken.getLocation());
|
||||
SmallString<128> USR;
|
||||
index::generateUSRForMacro(Name, PM.MacroNameToken.getLocation(), SM,
|
||||
USR);
|
||||
StringRef USR =
|
||||
API.recordUSRForMacro(Name, PM.MacroNameToken.getLocation(), SM);
|
||||
|
||||
API.createRecord<extractapi::MacroDefinitionRecord>(
|
||||
USR, Name, SymbolReference(), Loc,
|
||||
API.addMacroDefinition(
|
||||
Name, USR, Loc,
|
||||
DeclarationFragmentsBuilder::getFragmentsForMacro(Name, PM.MD),
|
||||
DeclarationFragmentsBuilder::getSubHeadingForMacro(Name),
|
||||
SM.isInSystemHeader(PM.MacroNameToken.getLocation()));
|
||||
@ -375,57 +372,40 @@ private:
|
||||
LocationFileChecker &LCF;
|
||||
};
|
||||
|
||||
std::unique_ptr<llvm::raw_pwrite_stream>
|
||||
createAdditionalSymbolGraphFile(CompilerInstance &CI, Twine BaseName) {
|
||||
auto OutputDirectory = CI.getFrontendOpts().SymbolGraphOutputDir;
|
||||
|
||||
SmallString<256> FileName;
|
||||
llvm::sys::path::append(FileName, OutputDirectory,
|
||||
BaseName + ".symbols.json");
|
||||
return CI.createOutputFile(
|
||||
FileName, /*Binary*/ false, /*RemoveFileOnSignal*/ false,
|
||||
/*UseTemporary*/ true, /*CreateMissingDirectories*/ true);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ExtractAPIActionBase::ImplEndSourceFileAction(CompilerInstance &CI) {
|
||||
SymbolGraphSerializerOption SerializationOptions;
|
||||
SerializationOptions.Compact = !CI.getFrontendOpts().EmitPrettySymbolGraphs;
|
||||
SerializationOptions.EmitSymbolLabelsForTesting =
|
||||
CI.getFrontendOpts().EmitSymbolGraphSymbolLabelsForTesting;
|
||||
void ExtractAPIActionBase::ImplEndSourceFileAction() {
|
||||
if (!OS)
|
||||
return;
|
||||
|
||||
if (CI.getFrontendOpts().EmitExtensionSymbolGraphs) {
|
||||
auto ConstructOutputFile = [&CI](Twine BaseName) {
|
||||
return createAdditionalSymbolGraphFile(CI, BaseName);
|
||||
};
|
||||
|
||||
SymbolGraphSerializer::serializeWithExtensionGraphs(
|
||||
*OS, *API, IgnoresList, ConstructOutputFile, SerializationOptions);
|
||||
} else {
|
||||
SymbolGraphSerializer::serializeMainSymbolGraph(*OS, *API, IgnoresList,
|
||||
SerializationOptions);
|
||||
}
|
||||
|
||||
// Flush the stream and close the main output stream.
|
||||
// Setup a SymbolGraphSerializer to write out collected API information in
|
||||
// the Symbol Graph format.
|
||||
// FIXME: Make the kind of APISerializer configurable.
|
||||
SymbolGraphSerializer SGSerializer(*API, IgnoresList);
|
||||
SGSerializer.serialize(*OS);
|
||||
OS.reset();
|
||||
}
|
||||
|
||||
std::unique_ptr<raw_pwrite_stream>
|
||||
ExtractAPIAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) {
|
||||
std::unique_ptr<raw_pwrite_stream> OS;
|
||||
OS = CI.createDefaultOutputFile(/*Binary=*/false, InFile,
|
||||
/*Extension=*/"json",
|
||||
/*RemoveFileOnSignal=*/false);
|
||||
if (!OS)
|
||||
return nullptr;
|
||||
return OS;
|
||||
}
|
||||
|
||||
std::unique_ptr<ASTConsumer>
|
||||
ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
|
||||
auto ProductName = CI.getFrontendOpts().ProductName;
|
||||
|
||||
if (CI.getFrontendOpts().SymbolGraphOutputDir.empty())
|
||||
OS = CI.createDefaultOutputFile(/*Binary*/ false, InFile,
|
||||
/*Extension*/ "symbols.json",
|
||||
/*RemoveFileOnSignal*/ false,
|
||||
/*CreateMissingDirectories*/ true);
|
||||
else
|
||||
OS = createAdditionalSymbolGraphFile(CI, ProductName);
|
||||
OS = CreateOutputFile(CI, InFile);
|
||||
|
||||
if (!OS)
|
||||
return nullptr;
|
||||
|
||||
auto ProductName = CI.getFrontendOpts().ProductName;
|
||||
|
||||
// Now that we have enough information about the language options and the
|
||||
// target triple, let's create the APISet before anyone uses it.
|
||||
API = std::make_unique<APISet>(
|
||||
@ -515,9 +495,7 @@ bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExtractAPIAction::EndSourceFileAction() {
|
||||
ImplEndSourceFileAction(getCompilerInstance());
|
||||
}
|
||||
void ExtractAPIAction::EndSourceFileAction() { ImplEndSourceFileAction(); }
|
||||
|
||||
std::unique_ptr<ASTConsumer>
|
||||
WrappingExtractAPIAction::CreateASTConsumer(CompilerInstance &CI,
|
||||
@ -528,9 +506,11 @@ WrappingExtractAPIAction::CreateASTConsumer(CompilerInstance &CI,
|
||||
|
||||
CreatedASTConsumer = true;
|
||||
|
||||
ProductName = CI.getFrontendOpts().ProductName;
|
||||
auto InputFilename = llvm::sys::path::filename(InFile);
|
||||
OS = createAdditionalSymbolGraphFile(CI, InputFilename);
|
||||
OS = CreateOutputFile(CI, InFile);
|
||||
if (!OS)
|
||||
return nullptr;
|
||||
|
||||
auto ProductName = CI.getFrontendOpts().ProductName;
|
||||
|
||||
// Now that we have enough information about the language options and the
|
||||
// target triple, let's create the APISet before anyone uses it.
|
||||
@ -572,6 +552,32 @@ void WrappingExtractAPIAction::EndSourceFileAction() {
|
||||
WrapperFrontendAction::EndSourceFileAction();
|
||||
|
||||
if (CreatedASTConsumer) {
|
||||
ImplEndSourceFileAction(getCompilerInstance());
|
||||
ImplEndSourceFileAction();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<raw_pwrite_stream>
|
||||
WrappingExtractAPIAction::CreateOutputFile(CompilerInstance &CI,
|
||||
StringRef InFile) {
|
||||
std::unique_ptr<raw_pwrite_stream> OS;
|
||||
std::string OutputDir = CI.getFrontendOpts().SymbolGraphOutputDir;
|
||||
|
||||
// The symbol graphs need to be generated as a side effect of regular
|
||||
// compilation so the output should be dumped in the directory provided with
|
||||
// the command line option.
|
||||
llvm::SmallString<128> OutFilePath(OutputDir);
|
||||
auto Seperator = llvm::sys::path::get_separator();
|
||||
auto Infilename = llvm::sys::path::filename(InFile);
|
||||
OutFilePath.append({Seperator, Infilename});
|
||||
llvm::sys::path::replace_extension(OutFilePath, "json");
|
||||
// StringRef outputFilePathref = *OutFilePath;
|
||||
|
||||
// don't use the default output file
|
||||
OS = CI.createOutputFile(/*OutputPath=*/OutFilePath, /*Binary=*/false,
|
||||
/*RemoveFileOnSignal=*/true,
|
||||
/*UseTemporary=*/true,
|
||||
/*CreateMissingDirectories=*/true);
|
||||
if (!OS)
|
||||
return nullptr;
|
||||
return OS;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "clang/Index/USRGeneration.h"
|
||||
|
||||
using namespace clang;
|
||||
@ -51,20 +50,17 @@ TypedefUnderlyingTypeResolver::getSymbolReferenceForType(QualType Type,
|
||||
SmallString<128> TypeUSR;
|
||||
const NamedDecl *TypeDecl = getUnderlyingTypeDecl(Type);
|
||||
const TypedefType *TypedefTy = Type->getAs<TypedefType>();
|
||||
StringRef OwningModuleName;
|
||||
|
||||
if (TypeDecl) {
|
||||
if (!TypedefTy)
|
||||
TypeName = TypeDecl->getName().str();
|
||||
|
||||
clang::index::generateUSRForDecl(TypeDecl, TypeUSR);
|
||||
if (auto *OwningModule = TypeDecl->getImportedOwningModule())
|
||||
OwningModuleName = OwningModule->Name;
|
||||
} else {
|
||||
clang::index::generateUSRForType(Type, Context, TypeUSR);
|
||||
}
|
||||
|
||||
return API.createSymbolReference(TypeName, TypeUSR, OwningModuleName);
|
||||
return {API.copyString(TypeName), API.copyString(TypeUSR)};
|
||||
}
|
||||
|
||||
std::string TypedefUnderlyingTypeResolver::getUSRForType(QualType Type) const {
|
||||
|
@ -181,13 +181,9 @@ CreateFrontendAction(CompilerInstance &CI) {
|
||||
#endif
|
||||
|
||||
// Wrap the base FE action in an extract api action to generate
|
||||
// symbol graph as a biproduct of compilation (enabled with
|
||||
// --emit-symbol-graph option)
|
||||
if (FEOpts.EmitSymbolGraph) {
|
||||
if (FEOpts.SymbolGraphOutputDir.empty()) {
|
||||
CI.getDiagnostics().Report(diag::warn_missing_symbol_graph_dir);
|
||||
CI.getFrontendOpts().SymbolGraphOutputDir = ".";
|
||||
}
|
||||
// symbol graph as a biproduct of compilation ( enabled with
|
||||
// --emit-symbol-graph option )
|
||||
if (!FEOpts.SymbolGraphOutputDir.empty()) {
|
||||
CI.getCodeGenOpts().ClearASTBeforeBackend = false;
|
||||
Act = std::make_unique<WrappingExtractAPIAction>(std::move(Act));
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
// XFAIL: *
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf --product-name=Availability -triple arm64-apple-macosx -x c-header %t/input.h -o %t/output.json -verify
|
||||
// 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" \
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
@ -15,7 +15,7 @@ template<typename X, typename Y> class Foo {};
|
||||
|
||||
template<typename Z> class Foo<Z, int> {};
|
||||
|
||||
// expected-no-diagnostics
|
||||
/// expected-no-diagnostics
|
||||
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -std=c++20 -extract-api --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -std=c++20 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
@ -137,7 +137,7 @@ class Foo {
|
||||
"precise": "c:@S@Foo@F@Foo#"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Constructor",
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "c++.method"
|
||||
},
|
||||
"location": {
|
||||
@ -193,7 +193,7 @@ class Foo {
|
||||
"precise": "c:@S@Foo@F@~Foo#"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Destructor",
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "c++.method"
|
||||
},
|
||||
"location": {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -5,19 +5,18 @@
|
||||
// RUN: %t/reference.main.json.in >> %t/reference.main.json
|
||||
// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
|
||||
// RUN: %t/reference.test.json.in >> %t/reference.test.json
|
||||
// RUN: %clang_cc1 %t/test.c %t/main.c -emit-symbol-graph --pretty-sgf \
|
||||
// RUN: --symbol-graph-dir=%t/SymbolGraphs --product-name=multifile_test -triple=x86_64-apple-macosx12.0.0
|
||||
// RUN: %clang_cc1 %t/test.c %t/main.c --emit-symbol-graph=%t/SymbolGraphs --product-name=multifile_test -triple=x86_64-apple-macosx12.0.0
|
||||
|
||||
// Test main.json
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
|
||||
// RUN: %t/SymbolGraphs/main.c.symbols.json > %t/output-normalized.json
|
||||
// RUN: %t/SymbolGraphs/main.json > %t/output-normalized.json
|
||||
// RUN: diff %t/reference.main.json %t/output-normalized.json
|
||||
|
||||
// Test test.json
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
|
||||
// RUN: %t/SymbolGraphs/test.c.symbols.json > %t/output-normalized.json
|
||||
// RUN: %t/SymbolGraphs/test.json > %t/output-normalized.json
|
||||
// RUN: diff %t/reference.test.json %t/output-normalized.json
|
||||
|
||||
// CHECK-NOT: error:
|
||||
|
@ -3,12 +3,11 @@
|
||||
// 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 %t/main.c -emit-symbol-graph --pretty-sgf \
|
||||
// RUN: --symbol-graph-dir=%t/SymbolGraphs --product-name=basicfile -triple=x86_64-apple-macosx12.0.0
|
||||
// RUN: %clang_cc1 %t/main.c --emit-symbol-graph=%t/SymbolGraphs --product-name=basicfile -triple=x86_64-apple-macosx12.0.0
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
|
||||
// RUN: %t/SymbolGraphs/main.c.symbols.json >> %t/output-normalized.json
|
||||
// RUN: %t/SymbolGraphs/main.json >> %t/output-normalized.json
|
||||
// RUN: diff %t/reference.output.json %t/output-normalized.json
|
||||
|
||||
// CHECK-NOT: error:
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf --product-name=GlobalRecord -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api --product-name=GlobalRecord -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf --product-name=GlobalRecord -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api --product-name=GlobalRecord -target arm64-apple-macosx \
|
||||
// RUN: %t/input1.h %t/input2.h %t/input3.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -1,7 +1,17 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --product-name=GlobalRecord -triple arm64-apple-macosx \
|
||||
// RUN: %t/input1.h -verify -o - | FileCheck %s
|
||||
// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
|
||||
// RUN: %t/reference.output.json.in >> %t/reference.output.json
|
||||
// RUN: %clang -extract-api --product-name=GlobalRecord -target arm64-apple-macosx \
|
||||
// RUN: %t/input1.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// 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:
|
||||
|
||||
//--- input1.h
|
||||
int num;
|
||||
@ -14,6 +24,87 @@ char not_emitted;
|
||||
void foo(int);
|
||||
struct Foo { int a; };
|
||||
|
||||
// CHECK-NOT: input2.h
|
||||
|
||||
// expected-no-diagnostics
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "GlobalRecord",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "num"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@num"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Global Variable",
|
||||
"identifier": "c.var"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 4,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input1.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "num"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "num"
|
||||
}
|
||||
],
|
||||
"title": "num"
|
||||
},
|
||||
"pathComponents": [
|
||||
"num"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -7,11 +7,11 @@
|
||||
// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
|
||||
// RUN: %t/objcpp.reference.output.json.in >> %t/objcpp.reference.output.json
|
||||
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf -x c-header -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -x c-header -triple arm64-apple-macosx \
|
||||
// RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf -x objective-c-header -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -x objective-c-header -triple arm64-apple-macosx \
|
||||
// RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf -x objective-c++-header -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -x objective-c++-header -triple arm64-apple-macosx \
|
||||
// RUN: %t/objcpp.h -o %t/objcpp.output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf --product-name=Macros -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api --product-name=Macros -target arm64-apple-macosx \
|
||||
// RUN: -x objective-c-header %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf --product-name=Macros -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api --product-name=Macros -target arm64-apple-macosx \
|
||||
// RUN: -x objective-c-header %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -1,32 +0,0 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --product-name=module -triple arm64-apple-macosx -x c-header %s -o %t/module.symbols.json -verify
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/module.symbols.json --check-prefix METADATA
|
||||
// RUN: FileCheck %s --input-file %t/module.symbols.json --check-prefix MOD
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
// METADATA: "metadata": {
|
||||
// METADATA-NEXT: "formatVersion": {
|
||||
// METADATA-NEXT: "major":
|
||||
// METADATA-NEXT: "minor":
|
||||
// METADATA-NEXT: "patch":
|
||||
// METADATA-NEXT: },
|
||||
// METADATA-NEXT: "generator":
|
||||
// METADATA-NEXT: }
|
||||
|
||||
// MOD: "module": {
|
||||
// MOD-NEXT: "name": "module",
|
||||
// MOD-NEXT: "platform": {
|
||||
// MOD-NEXT: "architecture": "arm64",
|
||||
// MOD-NEXT: "operatingSystem": {
|
||||
// MOD-NEXT: "minimumVersion": {
|
||||
// MOD-NEXT: "major":
|
||||
// MOD-NEXT: "minor":
|
||||
// MOD-NEXT: "patch":
|
||||
// MOD-NEXT: },
|
||||
// MOD-NEXT: "name": "macosx"
|
||||
// MOD-NEXT: },
|
||||
// MOD-NEXT: "vendor": "apple"
|
||||
// MOD-NEXT: }
|
||||
// MOD-NEXT: }
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -1,221 +1,467 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: -triple arm64-apple-macosx -x c++-header %s -o %t/output.symbols.json -verify
|
||||
// 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 -triple arm64-apple-macosx \
|
||||
// RUN: -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
|
||||
|
||||
//--- input.h
|
||||
class Foo {
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GETCOUNT
|
||||
int getCount();
|
||||
// GETCOUNT: "!testRelLabel": "memberOf $ c:@S@Foo@F@getCount# $ c:@S@Foo"
|
||||
// GETCOUNT-LABEL: "!testLabel": "c:@S@Foo@F@getCount#"
|
||||
// GETCOUNT: "accessLevel": "private",
|
||||
// GETCOUNT: "declarationFragments": [
|
||||
// GETCOUNT-NEXT: {
|
||||
// GETCOUNT-NEXT: "kind": "typeIdentifier",
|
||||
// GETCOUNT-NEXT: "preciseIdentifier": "c:I",
|
||||
// GETCOUNT-NEXT: "spelling": "int"
|
||||
// GETCOUNT-NEXT: },
|
||||
// GETCOUNT-NEXT: {
|
||||
// GETCOUNT-NEXT: "kind": "text",
|
||||
// GETCOUNT-NEXT: "spelling": " "
|
||||
// GETCOUNT-NEXT: },
|
||||
// GETCOUNT-NEXT: {
|
||||
// GETCOUNT-NEXT: "kind": "identifier",
|
||||
// GETCOUNT-NEXT: "spelling": "getCount"
|
||||
// GETCOUNT-NEXT: },
|
||||
// GETCOUNT-NEXT: {
|
||||
// GETCOUNT-NEXT: "kind": "text",
|
||||
// GETCOUNT-NEXT: "spelling": "();"
|
||||
// GETCOUNT-NEXT: }
|
||||
// GETCOUNT-NEXT: ],
|
||||
// GETCOUNT: "functionSignature": {
|
||||
// GETCOUNT-NEXT: "returns": [
|
||||
// GETCOUNT-NEXT: {
|
||||
// GETCOUNT-NEXT: "kind": "typeIdentifier",
|
||||
// GETCOUNT-NEXT: "preciseIdentifier": "c:I",
|
||||
// GETCOUNT-NEXT: "spelling": "int"
|
||||
// GETCOUNT-NEXT: }
|
||||
// GETCOUNT-NEXT: ]
|
||||
// GETCOUNT-NEXT: },
|
||||
// GETCOUNT: "displayName": "Instance Method",
|
||||
// GETCOUNT-NEXT: "identifier": "c++.method"
|
||||
// GETCOUNT: "title": "getCount"
|
||||
// GETCOUNT: "pathComponents": [
|
||||
// GETCOUNT-NEXT: "Foo",
|
||||
// GETCOUNT-NEXT: "getCount"
|
||||
// GETCOUNT-NEXT: ]
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix SETL
|
||||
void setLength(int length) noexcept;
|
||||
// SETL: "!testRelLabel": "memberOf $ c:@S@Foo@F@setLength#I# $ c:@S@Foo"
|
||||
// SETL-LABEL: "!testLabel": "c:@S@Foo@F@setLength#I#"
|
||||
// SETL: "declarationFragments": [
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "typeIdentifier",
|
||||
// SETL-NEXT: "preciseIdentifier": "c:v",
|
||||
// SETL-NEXT: "spelling": "void"
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "text",
|
||||
// SETL-NEXT: "spelling": " "
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "identifier",
|
||||
// SETL-NEXT: "spelling": "setLength"
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "text",
|
||||
// SETL-NEXT: "spelling": "("
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "typeIdentifier",
|
||||
// SETL-NEXT: "preciseIdentifier": "c:I",
|
||||
// SETL-NEXT: "spelling": "int"
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "text",
|
||||
// SETL-NEXT: "spelling": " "
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "internalParam",
|
||||
// SETL-NEXT: "spelling": "length"
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "text",
|
||||
// SETL-NEXT: "spelling": ")"
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "text",
|
||||
// SETL-NEXT: "spelling": " "
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "keyword",
|
||||
// SETL-NEXT: "spelling": "noexcept"
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "text",
|
||||
// SETL-NEXT: "spelling": ";"
|
||||
// SETL-NEXT: }
|
||||
// SETL-NEXT: ],
|
||||
// SETL: "functionSignature": {
|
||||
// SETL-NEXT: "parameters": [
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "declarationFragments": [
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "typeIdentifier",
|
||||
// SETL-NEXT: "preciseIdentifier": "c:I",
|
||||
// SETL-NEXT: "spelling": "int"
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "text",
|
||||
// SETL-NEXT: "spelling": " "
|
||||
// SETL-NEXT: },
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "internalParam",
|
||||
// SETL-NEXT: "spelling": "length"
|
||||
// SETL-NEXT: }
|
||||
// SETL-NEXT: ],
|
||||
// SETL-NEXT: "name": "length"
|
||||
// SETL-NEXT: }
|
||||
// SETL-NEXT: ],
|
||||
// SETL-NEXT: "returns": [
|
||||
// SETL-NEXT: {
|
||||
// SETL-NEXT: "kind": "typeIdentifier",
|
||||
// SETL-NEXT: "preciseIdentifier": "c:v",
|
||||
// SETL-NEXT: "spelling": "void"
|
||||
// SETL-NEXT: }
|
||||
// SETL-NEXT: ]
|
||||
// SETL-NEXT: },
|
||||
|
||||
public:
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GETFOO
|
||||
static double getFoo();
|
||||
// GETFOO: "!testRelLabel": "memberOf $ c:@S@Foo@F@getFoo#S $ c:@S@Foo"
|
||||
|
||||
// GETFOO-LABEL: "!testLabel": "c:@S@Foo@F@getFoo#S"
|
||||
// GETFOO: "accessLevel": "public",
|
||||
// GETFOO: "declarationFragments": [
|
||||
// GETFOO-NEXT: {
|
||||
// GETFOO-NEXT: "kind": "keyword",
|
||||
// GETFOO-NEXT: "spelling": "static"
|
||||
// GETFOO-NEXT: },
|
||||
// GETFOO-NEXT: {
|
||||
// GETFOO-NEXT: "kind": "text",
|
||||
// GETFOO-NEXT: "spelling": " "
|
||||
// GETFOO-NEXT: },
|
||||
// GETFOO-NEXT: {
|
||||
// GETFOO-NEXT: "kind": "typeIdentifier",
|
||||
// GETFOO-NEXT: "preciseIdentifier": "c:d",
|
||||
// GETFOO-NEXT: "spelling": "double"
|
||||
// GETFOO-NEXT: },
|
||||
// GETFOO-NEXT: {
|
||||
// GETFOO-NEXT: "kind": "text",
|
||||
// GETFOO-NEXT: "spelling": " "
|
||||
// GETFOO-NEXT: },
|
||||
// GETFOO-NEXT: {
|
||||
// GETFOO-NEXT: "kind": "identifier",
|
||||
// GETFOO-NEXT: "spelling": "getFoo"
|
||||
// GETFOO-NEXT: },
|
||||
// GETFOO-NEXT: {
|
||||
// GETFOO-NEXT: "kind": "text",
|
||||
// GETFOO-NEXT: "spelling": "();"
|
||||
// GETFOO-NEXT: }
|
||||
// GETFOO-NEXT: ],
|
||||
// GETFOO: "functionSignature": {
|
||||
// GETFOO-NEXT: "returns": [
|
||||
// GETFOO-NEXT: {
|
||||
// GETFOO-NEXT: "kind": "typeIdentifier",
|
||||
// GETFOO-NEXT: "preciseIdentifier": "c:d",
|
||||
// GETFOO-NEXT: "spelling": "double"
|
||||
// GETFOO-NEXT: }
|
||||
// GETFOO-NEXT: ]
|
||||
// GETFOO-NEXT: },
|
||||
// GETFOO: "kind": {
|
||||
// GETFOO-NEXT: "displayName": "Static Method",
|
||||
// GETFOO-NEXT: "identifier": "c++.type.method"
|
||||
// GETFOO-NEXT: },
|
||||
|
||||
protected:
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GETBAR
|
||||
constexpr int getBar() const;
|
||||
// GETBAR: "!testRelLabel": "memberOf $ c:@S@Foo@F@getBar#1 $ c:@S@Foo"
|
||||
|
||||
// GETBAR-LABEL: "!testLabel": "c:@S@Foo@F@getBar#1"
|
||||
// GETBAR: "accessLevel": "protected"
|
||||
// GETBAR: "declarationFragments": [
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "keyword",
|
||||
// GETBAR-NEXT: "spelling": "constexpr"
|
||||
// GETBAR-NEXT: },
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "text",
|
||||
// GETBAR-NEXT: "spelling": " "
|
||||
// GETBAR-NEXT: },
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "typeIdentifier",
|
||||
// GETBAR-NEXT: "preciseIdentifier": "c:I",
|
||||
// GETBAR-NEXT: "spelling": "int"
|
||||
// GETBAR-NEXT: },
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "text",
|
||||
// GETBAR-NEXT: "spelling": " "
|
||||
// GETBAR-NEXT: },
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "identifier",
|
||||
// GETBAR-NEXT: "spelling": "getBar"
|
||||
// GETBAR-NEXT: },
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "text",
|
||||
// GETBAR-NEXT: "spelling": "() "
|
||||
// GETBAR-NEXT: },
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "keyword",
|
||||
// GETBAR-NEXT: "spelling": "const"
|
||||
// GETBAR-NEXT: },
|
||||
// GETBAR-NEXT: {
|
||||
// GETBAR-NEXT: "kind": "text",
|
||||
// GETBAR-NEXT: "spelling": ";"
|
||||
// GETBAR-NEXT: }
|
||||
// GETBAR-NEXT: ],
|
||||
};
|
||||
/// expected-no-diagnostics
|
||||
|
||||
// expected-no-diagnostics
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@S@Foo@F@getCount#",
|
||||
"target": "c:@S@Foo",
|
||||
"targetFallback": "Foo"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@S@Foo@F@setLength#I#",
|
||||
"target": "c:@S@Foo",
|
||||
"targetFallback": "Foo"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@S@Foo@F@getBar#1",
|
||||
"target": "c:@S@Foo",
|
||||
"targetFallback": "Foo"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@S@Foo@F@getFoo#S",
|
||||
"target": "c:@S@Foo",
|
||||
"targetFallback": "Foo"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "class"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Foo"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c++",
|
||||
"precise": "c:@S@Foo"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class",
|
||||
"identifier": "c++.class"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Foo"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Foo"
|
||||
}
|
||||
],
|
||||
"title": "Foo"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "private",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getCount"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "();"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c++",
|
||||
"precise": "c:@S@Foo@F@getCount#"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "c++.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 1
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getCount"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getCount"
|
||||
}
|
||||
],
|
||||
"title": "getCount"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Foo",
|
||||
"getCount"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "private",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "setLength"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "internalParam",
|
||||
"spelling": "length"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ")"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "noexcept"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"parameters": [
|
||||
{
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "internalParam",
|
||||
"spelling": "length"
|
||||
}
|
||||
],
|
||||
"name": "length"
|
||||
}
|
||||
],
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c++",
|
||||
"precise": "c:@S@Foo@F@setLength#I#"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "c++.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 7,
|
||||
"line": 3
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "setLength"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "setLength"
|
||||
}
|
||||
],
|
||||
"title": "setLength"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Foo",
|
||||
"setLength"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "protected",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "constexpr"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getBar"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "() "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "const"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c++",
|
||||
"precise": "c:@S@Foo@F@getBar#1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "c++.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 16,
|
||||
"line": 9
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getBar"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getBar"
|
||||
}
|
||||
],
|
||||
"title": "getBar"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Foo",
|
||||
"getBar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "static"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:d",
|
||||
"spelling": "double"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getFoo"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "();"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:d",
|
||||
"spelling": "double"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c++",
|
||||
"precise": "c:@S@Foo@F@getFoo#S"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Static Method",
|
||||
"identifier": "c++.type.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 16,
|
||||
"line": 6
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getFoo"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "getFoo"
|
||||
}
|
||||
],
|
||||
"title": "getFoo"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Foo",
|
||||
"getFoo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -std=c++20 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -std=c++20 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,21 +1,341 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: -triple arm64-apple-macosx -x objective-c-header %s -o - -verify | FileCheck %s
|
||||
// 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 -extract-api -x objective-c-header -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
@protocol Protocol
|
||||
@end
|
||||
// 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
|
||||
@protocol Protocol;
|
||||
|
||||
@interface Interface
|
||||
@end
|
||||
|
||||
@interface Interface (Category) <Protocol>
|
||||
// CHECK-DAG: "!testRelLabel": "conformsTo $ c:objc(cs)Interface $ c:objc(pl)Protocol"
|
||||
@property int Property;
|
||||
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(py)Property $ c:objc(cs)Interface"
|
||||
- (void)InstanceMethod;
|
||||
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(im)InstanceMethod $ c:objc(cs)Interface"
|
||||
+ (void)ClassMethod;
|
||||
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(cm)ClassMethod $ c:objc(cs)Interface"
|
||||
@end
|
||||
|
||||
// expected-no-diagnostics
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)Interface(im)InstanceMethod",
|
||||
"target": "c:objc(cs)Interface",
|
||||
"targetFallback": "Interface"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)Interface(cm)ClassMethod",
|
||||
"target": "c:objc(cs)Interface",
|
||||
"targetFallback": "Interface"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)Interface(py)Property",
|
||||
"target": "c:objc(cs)Interface",
|
||||
"targetFallback": "Interface"
|
||||
},
|
||||
{
|
||||
"kind": "conformsTo",
|
||||
"source": "c:objc(cs)Interface",
|
||||
"target": "c:objc(pl)Protocol",
|
||||
"targetFallback": "Protocol"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Interface"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class",
|
||||
"identifier": "objective-c.class"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 2
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Interface"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Interface"
|
||||
}
|
||||
],
|
||||
"title": "Interface"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- ("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "InstanceMethod"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface(im)InstanceMethod"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "objective-c.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 0,
|
||||
"line": 7
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "InstanceMethod"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "InstanceMethod"
|
||||
}
|
||||
],
|
||||
"title": "InstanceMethod"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface",
|
||||
"InstanceMethod"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "+ ("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ClassMethod"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface(cm)ClassMethod"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Method",
|
||||
"identifier": "objective-c.type.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 0,
|
||||
"line": 8
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ClassMethod"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "+ "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ClassMethod"
|
||||
}
|
||||
],
|
||||
"title": "ClassMethod"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface",
|
||||
"ClassMethod"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface(py)Property"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "objective-c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 14,
|
||||
"line": 6
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Property"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Property"
|
||||
}
|
||||
],
|
||||
"title": "Property"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface",
|
||||
"Property"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: --emit-extension-symbol-graphs --symbol-graph-dir=%t/symbols \
|
||||
// RUN: --product-name=Module -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules-cache \
|
||||
// RUN: -triple arm64-apple-macosx -x objective-c-header %t/input.h -verify
|
||||
|
||||
//--- input.h
|
||||
#include "ExternalModule.h"
|
||||
|
||||
@interface ExtInterface (Category)
|
||||
@property int Property;
|
||||
- (void)InstanceMethod;
|
||||
+ (void)ClassMethod;
|
||||
@end
|
||||
|
||||
@interface ModInterface
|
||||
@end
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
//--- ExternalModule.h
|
||||
@interface ExtInterface
|
||||
@end
|
||||
|
||||
//--- module.modulemap
|
||||
module ExternalModule {
|
||||
header "ExternalModule.h"
|
||||
}
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/symbols/Module.symbols.json --check-prefix MOD
|
||||
// MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(py)Property $ c:objc(cs)ExtInterface"
|
||||
// MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(im)InstanceMethod $ c:objc(cs)ExtInterface"
|
||||
// MOD-NOT: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(cm)ClassMethod $ c:objc(cs)ExtInterface"
|
||||
// MOD-NOT: "!testLabel": "c:objc(cs)ExtInterface(py)Property"
|
||||
// MOD-NOT: "!testLabel": "c:objc(cs)ExtInterface(im)InstanceMethod"
|
||||
// MOD-NOT: "!testLabel": "c:objc(cs)ExtInterface(cm)ClassMethod"
|
||||
// MOD-NOT: "!testLabel": "c:objc(cs)ExtInterface"
|
||||
// MOD-DAG: "!testLabel": "c:objc(cs)ModInterface"
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/symbols/ExternalModule@Module.symbols.json --check-prefix EXT
|
||||
// EXT-DAG: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(py)Property $ c:objc(cs)ExtInterface"
|
||||
// EXT-DAG: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(im)InstanceMethod $ c:objc(cs)ExtInterface"
|
||||
// EXT-DAG: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(cm)ClassMethod $ c:objc(cs)ExtInterface"
|
||||
// EXT-DAG: "!testLabel": "c:objc(cs)ExtInterface(py)Property"
|
||||
// EXT-DAG: "!testLabel": "c:objc(cs)ExtInterface(im)InstanceMethod"
|
||||
// EXT-DAG: "!testLabel": "c:objc(cs)ExtInterface(cm)ClassMethod"
|
||||
// EXT-NOT: "!testLabel": "c:objc(cs)ExtInterface"
|
||||
// EXT-NOT: "!testLabel": "c:objc(cs)ModInterface"
|
@ -1,56 +1,317 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: -x objective-c-header -triple arm64-apple-macosx %s -o - -verify | FileCheck %s
|
||||
// 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 -extract-api -x objective-c-header -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// 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
|
||||
@protocol MyProtocol
|
||||
@end
|
||||
|
||||
@interface MyInterface
|
||||
@property(copy, readwrite) id<MyProtocol> obj1;
|
||||
// CHECK-LABEL: "!testLabel": "c:objc(cs)MyInterface(py)obj1"
|
||||
// CHECK: "declarationFragments": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "keyword",
|
||||
// CHECK-NEXT: "spelling": "@property"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "text",
|
||||
// CHECK-NEXT: "spelling": " ("
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "keyword",
|
||||
// CHECK-NEXT: "spelling": "copy"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "text",
|
||||
// CHECK-NEXT: "spelling": ", "
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "keyword",
|
||||
// CHECK-NEXT: "spelling": "readwrite"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "text",
|
||||
// CHECK-NEXT: "spelling": ") "
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "typeIdentifier",
|
||||
// CHECK-NEXT: "preciseIdentifier": "c:Qoobjc(pl)MyProtocol",
|
||||
// CHECK-NEXT: "spelling": "id<MyProtocol>"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "text",
|
||||
// CHECK-NEXT: "spelling": " "
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "identifier",
|
||||
// CHECK-NEXT: "spelling": "obj1"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "kind": "text",
|
||||
// CHECK-NEXT: "spelling": ";"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
@property(readwrite) id<MyProtocol> *obj2;
|
||||
@end
|
||||
|
||||
// expected-no-diagnostics
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)MyInterface(py)obj1",
|
||||
"target": "c:objc(cs)MyInterface",
|
||||
"targetFallback": "MyInterface"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)MyInterface(py)obj2",
|
||||
"target": "c:objc(cs)MyInterface",
|
||||
"targetFallback": "MyInterface"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyInterface"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)MyInterface"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class",
|
||||
"identifier": "objective-c.class"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 3
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyInterface"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyInterface"
|
||||
}
|
||||
],
|
||||
"title": "MyInterface"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyInterface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "copy"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ", "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "readwrite"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:Qoobjc(pl)MyProtocol",
|
||||
"spelling": "id<MyProtocol>"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "obj1"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)MyInterface(py)obj1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "objective-c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 42,
|
||||
"line": 4
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "obj1"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "obj1"
|
||||
}
|
||||
],
|
||||
"title": "obj1"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyInterface",
|
||||
"obj1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "readwrite"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:Qoobjc(pl)MyProtocol",
|
||||
"spelling": "id<MyProtocol>"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " * "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "obj2"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)MyInterface(py)obj2"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "objective-c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 37,
|
||||
"line": 5
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "obj2"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "obj2"
|
||||
}
|
||||
],
|
||||
"title": "obj2"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyInterface",
|
||||
"obj2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@protocol"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyProtocol"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(pl)MyProtocol"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Protocol",
|
||||
"identifier": "objective-c.protocol"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 10,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyProtocol"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyProtocol"
|
||||
}
|
||||
],
|
||||
"title": "MyProtocol"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyProtocol"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx -x objective-c-header %t/input.h -o %t/output.json -verify
|
||||
// RUN: %t/reference.output.json.in >> %t/reference.output.json
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx -x objective-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" \
|
||||
|
File diff suppressed because it is too large
Load Diff
404
clang/test/ExtractAPI/objc_module_category.m
Normal file
404
clang/test/ExtractAPI/objc_module_category.m
Normal file
@ -0,0 +1,404 @@
|
||||
// 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 -extract-api -x objective-c-header \
|
||||
// RUN: -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// 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
|
||||
#import "Foundation.h"
|
||||
|
||||
/// Doc comment 1
|
||||
@interface NSString (Category1)
|
||||
-(void)method1;
|
||||
@end
|
||||
|
||||
/// Doc comment 2
|
||||
@interface NSString (Category2)
|
||||
-(void)method2;
|
||||
@end
|
||||
|
||||
//--- Foundation.h
|
||||
@interface NSString
|
||||
@end
|
||||
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "extensionTo",
|
||||
"source": "c:objc(cy)NSString@Category1",
|
||||
"target": "c:objc(cs)NSString",
|
||||
"targetFallback": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)NSString(im)method1",
|
||||
"target": "c:objc(cy)NSString@Category1",
|
||||
"targetFallback": "Category1"
|
||||
},
|
||||
{
|
||||
"kind": "extensionTo",
|
||||
"source": "c:objc(cy)NSString@Category2",
|
||||
"target": "c:objc(cs)NSString",
|
||||
"targetFallback": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)NSString(im)method2",
|
||||
"target": "c:objc(cy)NSString@Category2",
|
||||
"targetFallback": "Category2"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cy)NSString@Category1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Module Extension",
|
||||
"identifier": "objective-c.module.extension"
|
||||
}
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:objc(cs)NSString",
|
||||
"spelling": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category1"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ")"
|
||||
}
|
||||
],
|
||||
"docComment": {
|
||||
"lines": [
|
||||
{
|
||||
"range": {
|
||||
"end": {
|
||||
"character": 17,
|
||||
"line": 2
|
||||
},
|
||||
"start": {
|
||||
"character": 4,
|
||||
"line": 2
|
||||
}
|
||||
},
|
||||
"text": "Doc comment 1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cy)NSString@Category1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class Extension",
|
||||
"identifier": "objective-c.class.extension"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 3
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category1"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category1"
|
||||
}
|
||||
],
|
||||
"title": "NSString (Category1)"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- ("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "method1"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)NSString(im)method1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "objective-c.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 0,
|
||||
"line": 4
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "method1"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "method1"
|
||||
}
|
||||
],
|
||||
"title": "method1"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category1",
|
||||
"method1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:objc(cs)NSString",
|
||||
"spelling": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category2"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ")"
|
||||
}
|
||||
],
|
||||
"docComment": {
|
||||
"lines": [
|
||||
{
|
||||
"range": {
|
||||
"end": {
|
||||
"character": 17,
|
||||
"line": 7
|
||||
},
|
||||
"start": {
|
||||
"character": 4,
|
||||
"line": 7
|
||||
}
|
||||
},
|
||||
"text": "Doc comment 2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cy)NSString@Category2"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class Extension",
|
||||
"identifier": "objective-c.class.extension"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 8
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category2"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category2"
|
||||
}
|
||||
],
|
||||
"title": "NSString (Category2)"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- ("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "method2"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)NSString(im)method2"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "objective-c.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 0,
|
||||
"line": 9
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "method2"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "method2"
|
||||
}
|
||||
],
|
||||
"title": "method2"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category2",
|
||||
"method2"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -1,26 +1,608 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: -triple arm64-apple-macosx -x objective-c-header %s -o - -verify | FileCheck %s
|
||||
// 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 -triple arm64-apple-macosx -x objective-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
|
||||
|
||||
//--- input.h
|
||||
@protocol Protocol
|
||||
@property(class) int myProtocolTypeProp;
|
||||
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(pl)Protocol(cpy)myProtocolTypeProp $ c:objc(pl)Protocol"
|
||||
@property int myProtocolInstanceProp;
|
||||
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(pl)Protocol(py)myProtocolInstanceProp $ c:objc(pl)Protocol"
|
||||
@end
|
||||
|
||||
@interface Interface
|
||||
@property(class) int myInterfaceTypeProp;
|
||||
// CHECk-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(cpy)myInterfaceTypeProp $ c:objc(cs)Interface"
|
||||
@property int myInterfaceInstanceProp;
|
||||
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(py)myInterfaceInstanceProp $ c:objc(cs)Interface"
|
||||
@end
|
||||
|
||||
@interface Interface (Category) <Protocol>
|
||||
@property(class) int myCategoryTypeProp;
|
||||
// CHECK-DAG: "!testRelLabel": "memberOf $ c:objc(cs)Interface(cpy)myCategoryTypeProp $ c:objc(cs)Interface"
|
||||
@property int myCategoryInstanceProp;
|
||||
// CHECK-DAG "!testRelLabel": "memberOf $ c:objc(cs)Interface(py)myCategoryInstanceProp $ c:objc(cs)Interface"
|
||||
@end
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)Interface(cpy)myInterfaceTypeProp",
|
||||
"target": "c:objc(cs)Interface",
|
||||
"targetFallback": "Interface"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)Interface(py)myInterfaceInstanceProp",
|
||||
"target": "c:objc(cs)Interface",
|
||||
"targetFallback": "Interface"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)Interface(cpy)myCategoryTypeProp",
|
||||
"target": "c:objc(cs)Interface",
|
||||
"targetFallback": "Interface"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)Interface(py)myCategoryInstanceProp",
|
||||
"target": "c:objc(cs)Interface",
|
||||
"targetFallback": "Interface"
|
||||
},
|
||||
{
|
||||
"kind": "conformsTo",
|
||||
"source": "c:objc(cs)Interface",
|
||||
"target": "c:objc(pl)Protocol",
|
||||
"targetFallback": "Protocol"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(pl)Protocol(cpy)myProtocolTypeProp",
|
||||
"target": "c:objc(pl)Protocol",
|
||||
"targetFallback": "Protocol"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(pl)Protocol(py)myProtocolInstanceProp",
|
||||
"target": "c:objc(pl)Protocol",
|
||||
"targetFallback": "Protocol"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Interface"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class",
|
||||
"identifier": "objective-c.class"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 5
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Interface"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Interface"
|
||||
}
|
||||
],
|
||||
"title": "Interface"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "class"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myInterfaceTypeProp"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface(cpy)myInterfaceTypeProp"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Property",
|
||||
"identifier": "objective-c.type.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 21,
|
||||
"line": 6
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myInterfaceTypeProp"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myInterfaceTypeProp"
|
||||
}
|
||||
],
|
||||
"title": "myInterfaceTypeProp"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface",
|
||||
"myInterfaceTypeProp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myInterfaceInstanceProp"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface(py)myInterfaceInstanceProp"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "objective-c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 14,
|
||||
"line": 7
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myInterfaceInstanceProp"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myInterfaceInstanceProp"
|
||||
}
|
||||
],
|
||||
"title": "myInterfaceInstanceProp"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface",
|
||||
"myInterfaceInstanceProp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "class"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myCategoryTypeProp"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface(cpy)myCategoryTypeProp"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Property",
|
||||
"identifier": "objective-c.type.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 21,
|
||||
"line": 11
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myCategoryTypeProp"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myCategoryTypeProp"
|
||||
}
|
||||
],
|
||||
"title": "myCategoryTypeProp"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface",
|
||||
"myCategoryTypeProp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myCategoryInstanceProp"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)Interface(py)myCategoryInstanceProp"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "objective-c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 14,
|
||||
"line": 12
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myCategoryInstanceProp"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myCategoryInstanceProp"
|
||||
}
|
||||
],
|
||||
"title": "myCategoryInstanceProp"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Interface",
|
||||
"myCategoryInstanceProp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@protocol"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Protocol"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(pl)Protocol"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Protocol",
|
||||
"identifier": "objective-c.protocol"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 10,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Protocol"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Protocol"
|
||||
}
|
||||
],
|
||||
"title": "Protocol"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Protocol"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "class"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myProtocolTypeProp"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(pl)Protocol(cpy)myProtocolTypeProp"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Property",
|
||||
"identifier": "objective-c.type.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 21,
|
||||
"line": 1
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myProtocolTypeProp"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myProtocolTypeProp"
|
||||
}
|
||||
],
|
||||
"title": "myProtocolTypeProp"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Protocol",
|
||||
"myProtocolTypeProp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@property"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myProtocolInstanceProp"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(pl)Protocol(py)myProtocolInstanceProp"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "objective-c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 14,
|
||||
"line": 2
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myProtocolInstanceProp"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "myProtocolInstanceProp"
|
||||
}
|
||||
],
|
||||
"title": "myProtocolInstanceProp"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Protocol",
|
||||
"myProtocolInstanceProp"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf -x objective-c-header -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api -x objective-c-header -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
507
clang/test/ExtractAPI/objc_various_categories.m
Normal file
507
clang/test/ExtractAPI/objc_various_categories.m
Normal file
@ -0,0 +1,507 @@
|
||||
// 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 -extract-api -x objective-c-header \
|
||||
// RUN: -target arm64-apple-macosx \
|
||||
// RUN: %t/myclass_1.h \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// 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
|
||||
#import "myclass_1.h"
|
||||
#import "Foundation.h"
|
||||
|
||||
@interface MyClass1 (MyCategory1)
|
||||
- (int) SomeMethod;
|
||||
@end
|
||||
|
||||
@interface NSString (Category1)
|
||||
-(void) StringMethod;
|
||||
@end
|
||||
|
||||
@interface NSString (Category2)
|
||||
-(void) StringMethod2;
|
||||
@end
|
||||
|
||||
//--- myclass_1.h
|
||||
@interface MyClass1
|
||||
@end
|
||||
|
||||
//--- Foundation.h
|
||||
@interface NSString
|
||||
@end
|
||||
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)MyClass1(im)SomeMethod",
|
||||
"target": "c:objc(cs)MyClass1",
|
||||
"targetFallback": "MyClass1"
|
||||
},
|
||||
{
|
||||
"kind": "extensionTo",
|
||||
"source": "c:objc(cy)NSString@Category1",
|
||||
"target": "c:objc(cs)NSString",
|
||||
"targetFallback": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)NSString(im)StringMethod",
|
||||
"target": "c:objc(cy)NSString@Category1",
|
||||
"targetFallback": "Category1"
|
||||
},
|
||||
{
|
||||
"kind": "extensionTo",
|
||||
"source": "c:objc(cy)NSString@Category2",
|
||||
"target": "c:objc(cs)NSString",
|
||||
"targetFallback": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:objc(cs)NSString(im)StringMethod2",
|
||||
"target": "c:objc(cy)NSString@Category2",
|
||||
"targetFallback": "Category2"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyClass1"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)MyClass1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class",
|
||||
"identifier": "objective-c.class"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/myclass_1.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyClass1"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyClass1"
|
||||
}
|
||||
],
|
||||
"title": "MyClass1"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyClass1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- ("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "SomeMethod"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)MyClass1(im)SomeMethod"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "objective-c.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 0,
|
||||
"line": 4
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "SomeMethod"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "SomeMethod"
|
||||
}
|
||||
],
|
||||
"title": "SomeMethod"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyClass1",
|
||||
"SomeMethod"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cy)NSString@Category1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Module Extension",
|
||||
"identifier": "objective-c.module.extension"
|
||||
}
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:objc(cs)NSString",
|
||||
"spelling": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category1"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ")"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cy)NSString@Category1"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class Extension",
|
||||
"identifier": "objective-c.class.extension"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 7
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category1"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category1"
|
||||
}
|
||||
],
|
||||
"title": "NSString (Category1)"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- ("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "StringMethod"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)NSString(im)StringMethod"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "objective-c.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 0,
|
||||
"line": 8
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "StringMethod"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "StringMethod"
|
||||
}
|
||||
],
|
||||
"title": "StringMethod"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category1",
|
||||
"StringMethod"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "@interface"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:objc(cs)NSString",
|
||||
"spelling": "NSString"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " ("
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category2"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ")"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cy)NSString@Category2"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Class Extension",
|
||||
"identifier": "objective-c.class.extension"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 11,
|
||||
"line": 11
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category2"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Category2"
|
||||
}
|
||||
],
|
||||
"title": "NSString (Category2)"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- ("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ") "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "StringMethod2"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:objc(cs)NSString(im)StringMethod2"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Method",
|
||||
"identifier": "objective-c.method"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 0,
|
||||
"line": 12
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "StringMethod2"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "- "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "StringMethod2"
|
||||
}
|
||||
],
|
||||
"title": "StringMethod2"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Category2",
|
||||
"StringMethod2"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -15,7 +15,7 @@
|
||||
// RUN: %hmaptool write %t/headermap.hmap.json %t/headermap.hmap
|
||||
|
||||
// Input headers use paths to the framework root/DSTROOT
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf -v --product-name=MyFramework \
|
||||
// RUN: %clang_cc1 -extract-api -v --product-name=MyFramework \
|
||||
// RUN: -triple arm64-apple-macosx \
|
||||
// RUN: -iquote%t -I%t/headermap.hmap -F%t/Frameworks \
|
||||
// RUN: -x objective-c-header \
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx \
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx \
|
||||
// RUN: -x c++-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -1,93 +1,391 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: -triple arm64-apple-macosx -x objective-c-header %s -o %t/output.symbols.json -verify
|
||||
// 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 -extract-api --product-name=Typedef -target arm64-apple-macosx \
|
||||
// RUN: -x objective-c-header %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix MYINT
|
||||
// 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
|
||||
typedef int MyInt;
|
||||
// MYINT-LABEL: "!testLabel": "c:typedef.c@T@MyInt"
|
||||
// MYINT: "accessLevel": "public",
|
||||
// MYINT: "declarationFragments": [
|
||||
// MYINT-NEXT: {
|
||||
// MYINT-NEXT: "kind": "keyword",
|
||||
// MYINT-NEXT: "spelling": "typedef"
|
||||
// MYINT-NEXT: },
|
||||
// MYINT-NEXT: {
|
||||
// MYINT-NEXT: "kind": "text",
|
||||
// MYINT-NEXT: "spelling": " "
|
||||
// MYINT-NEXT: },
|
||||
// MYINT-NEXT: {
|
||||
// MYINT-NEXT: "kind": "typeIdentifier",
|
||||
// MYINT-NEXT: "preciseIdentifier": "c:I",
|
||||
// MYINT-NEXT: "spelling": "int"
|
||||
// MYINT-NEXT: },
|
||||
// MYINT-NEXT: {
|
||||
// MYINT-NEXT: "kind": "text",
|
||||
// MYINT-NEXT: "spelling": " "
|
||||
// MYINT-NEXT: },
|
||||
// MYINT-NEXT: {
|
||||
// MYINT-NEXT: "kind": "identifier",
|
||||
// MYINT-NEXT: "spelling": "MyInt"
|
||||
// MYINT-NEXT: },
|
||||
// MYINT-NEXT: {
|
||||
// MYINT-NEXT: "kind": "text",
|
||||
// MYINT-NEXT: "spelling": ";"
|
||||
// MYINT-NEXT: }
|
||||
// MYINT-NEXT: ],
|
||||
// MYINT: "kind": {
|
||||
// MYINT-NEXT: "displayName": "Type Alias",
|
||||
// MYINT-NEXT: "identifier": "objective-c.typealias"
|
||||
// MYINT-NEXT: },
|
||||
// MYINT: "title": "MyInt"
|
||||
// MYINT: "pathComponents": [
|
||||
// MYINT-NEXT: "MyInt"
|
||||
// MYINT-NEXT: ],
|
||||
// MYINT: "type": "c:I"
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix BARPTR
|
||||
typedef struct Bar *BarPtr;
|
||||
// BARPTR-LABEL: "!testLabel": "c:typedef.c@T@BarPtr"
|
||||
// BARPTR: "accessLevel": "public",
|
||||
// BARPTR: "declarationFragments": [
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "keyword",
|
||||
// BARPTR-NEXT: "spelling": "typedef"
|
||||
// BARPTR-NEXT: },
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "text",
|
||||
// BARPTR-NEXT: "spelling": " "
|
||||
// BARPTR-NEXT: },
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "keyword",
|
||||
// BARPTR-NEXT: "spelling": "struct"
|
||||
// BARPTR-NEXT: },
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "text",
|
||||
// BARPTR-NEXT: "spelling": " "
|
||||
// BARPTR-NEXT: },
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "typeIdentifier",
|
||||
// BARPTR-NEXT: "preciseIdentifier": "c:@S@Bar",
|
||||
// BARPTR-NEXT: "spelling": "Bar"
|
||||
// BARPTR-NEXT: },
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "text",
|
||||
// BARPTR-NEXT: "spelling": " * "
|
||||
// BARPTR-NEXT: },
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "identifier",
|
||||
// BARPTR-NEXT: "spelling": "BarPtr"
|
||||
// BARPTR-NEXT: },
|
||||
// BARPTR-NEXT: {
|
||||
// BARPTR-NEXT: "kind": "text",
|
||||
// BARPTR-NEXT: "spelling": ";"
|
||||
// BARPTR-NEXT: }
|
||||
// BARPTR-NEXT: ],
|
||||
// BARPTR: "type": "c:*$@S@Bar"
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json
|
||||
void foo(BarPtr value);
|
||||
|
||||
void baz(BarPtr *value);
|
||||
// CHECK-NOT: struct Bar *
|
||||
|
||||
// expected-no-diagnostics
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "Typedef",
|
||||
"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": "foo"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:input.h@T@BarPtr",
|
||||
"spelling": "BarPtr"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "internalParam",
|
||||
"spelling": "value"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ");"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"parameters": [
|
||||
{
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:input.h@T@BarPtr",
|
||||
"spelling": "BarPtr"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "internalParam",
|
||||
"spelling": "value"
|
||||
}
|
||||
],
|
||||
"name": "value"
|
||||
}
|
||||
],
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:@F@foo"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Function",
|
||||
"identifier": "objective-c.func"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 5,
|
||||
"line": 4
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "foo"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "foo"
|
||||
}
|
||||
],
|
||||
"title": "foo"
|
||||
},
|
||||
"pathComponents": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "baz"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": "("
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:input.h@T@BarPtr",
|
||||
"spelling": "BarPtr"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " * "
|
||||
},
|
||||
{
|
||||
"kind": "internalParam",
|
||||
"spelling": "value"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ");"
|
||||
}
|
||||
],
|
||||
"functionSignature": {
|
||||
"parameters": [
|
||||
{
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:input.h@T@BarPtr",
|
||||
"spelling": "BarPtr"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " * "
|
||||
},
|
||||
{
|
||||
"kind": "internalParam",
|
||||
"spelling": "value"
|
||||
}
|
||||
],
|
||||
"name": "value"
|
||||
}
|
||||
],
|
||||
"returns": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:v",
|
||||
"spelling": "void"
|
||||
}
|
||||
]
|
||||
},
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:@F@baz"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Function",
|
||||
"identifier": "objective-c.func"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 5,
|
||||
"line": 6
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "baz"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "baz"
|
||||
}
|
||||
],
|
||||
"title": "baz"
|
||||
},
|
||||
"pathComponents": [
|
||||
"baz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyInt"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:input.h@T@MyInt"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "objective-c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 12,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyInt"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyInt"
|
||||
}
|
||||
],
|
||||
"title": "MyInt"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyInt"
|
||||
],
|
||||
"type": "c:I"
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "struct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:@S@Bar",
|
||||
"spelling": "Bar"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " * "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "BarPtr"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:input.h@T@BarPtr"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "objective-c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 20,
|
||||
"line": 2
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "BarPtr"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "BarPtr"
|
||||
}
|
||||
],
|
||||
"title": "BarPtr"
|
||||
},
|
||||
"pathComponents": [
|
||||
"BarPtr"
|
||||
],
|
||||
"type": "c:*$@S@Bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,158 +1,468 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c-header %s -o %t/typedefchain.symbols.json -verify
|
||||
// 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=TypedefChain -triple arm64-apple-macosx \
|
||||
// RUN: -x c-header %t/input.h -o %t/output.json -verify
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYSTRUCT
|
||||
// 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
|
||||
|
||||
//--- input.h
|
||||
typedef struct { } MyStruct;
|
||||
// MYSTRUCT-LABEL: "!testLabel": "c:@SA@MyStruct"
|
||||
// MYSTRUCT: "accessLevel": "public",
|
||||
// MYSTRUCT: "declarationFragments": [
|
||||
// MYSTRUCT-NEXT: {
|
||||
// MYSTRUCT-NEXT: "kind": "keyword",
|
||||
// MYSTRUCT-NEXT: "spelling": "typedef"
|
||||
// MYSTRUCT-NEXT: },
|
||||
// MYSTRUCT-NEXT: {
|
||||
// MYSTRUCT-NEXT: "kind": "text",
|
||||
// MYSTRUCT-NEXT: "spelling": " "
|
||||
// MYSTRUCT-NEXT: },
|
||||
// MYSTRUCT-NEXT: {
|
||||
// MYSTRUCT-NEXT: "kind": "keyword",
|
||||
// MYSTRUCT-NEXT: "spelling": "struct"
|
||||
// MYSTRUCT-NEXT: },
|
||||
// MYSTRUCT-NEXT: {
|
||||
// MYSTRUCT-NEXT: "kind": "text",
|
||||
// MYSTRUCT-NEXT: "spelling": " "
|
||||
// MYSTRUCT-NEXT: },
|
||||
// MYSTRUCT-NEXT: {
|
||||
// MYSTRUCT-NEXT: "kind": "identifier",
|
||||
// MYSTRUCT-NEXT: "spelling": "MyStruct"
|
||||
// MYSTRUCT-NEXT: },
|
||||
// MYSTRUCT-NEXT: {
|
||||
// MYSTRUCT-NEXT: "kind": "text",
|
||||
// MYSTRUCT-NEXT: "spelling": ";"
|
||||
// MYSTRUCT-NEXT: }
|
||||
// MYSTRUCT-NEXT: ]
|
||||
// MYSTRUCT: "kind": {
|
||||
// MYSTRUCT-NEXT: "displayName": "Structure",
|
||||
// MYSTRUCT-NEXT: "identifier": "c.struct"
|
||||
// MYSTRUCT: "title": "MyStruct"
|
||||
// MYSTRUCT: "pathComponents": [
|
||||
// MYSTRUCT-NEXT: "MyStruct"
|
||||
// MYSTRUCT-NEXT: ]
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYSTRUCTSTRUCT
|
||||
typedef MyStruct MyStructStruct;
|
||||
// MYSTRUCTSTRUCT-LABEL: "!testLabel": "c:typedef_anonymous_record.c@T@MyStructStruct"
|
||||
// MYSTRUCTSTRUCT: "accessLevel": "public",
|
||||
// MYSTRUCTSTRUCT: "declarationFragments": [
|
||||
// MYSTRUCTSTRUCT-NEXT: {
|
||||
// MYSTRUCTSTRUCT-NEXT: "kind": "keyword",
|
||||
// MYSTRUCTSTRUCT-NEXT: "spelling": "typedef"
|
||||
// MYSTRUCTSTRUCT-NEXT: },
|
||||
// MYSTRUCTSTRUCT-NEXT: {
|
||||
// MYSTRUCTSTRUCT-NEXT: "kind": "text",
|
||||
// MYSTRUCTSTRUCT-NEXT: "spelling": " "
|
||||
// MYSTRUCTSTRUCT-NEXT: },
|
||||
// MYSTRUCTSTRUCT-NEXT: {
|
||||
// MYSTRUCTSTRUCT-NEXT: "kind": "typeIdentifier",
|
||||
// MYSTRUCTSTRUCT-NEXT: "preciseIdentifier": "c:@SA@MyStruct",
|
||||
// MYSTRUCTSTRUCT-NEXT: "spelling": "MyStruct"
|
||||
// MYSTRUCTSTRUCT-NEXT: },
|
||||
// MYSTRUCTSTRUCT-NEXT: {
|
||||
// MYSTRUCTSTRUCT-NEXT: "kind": "text",
|
||||
// MYSTRUCTSTRUCT-NEXT: "spelling": " "
|
||||
// MYSTRUCTSTRUCT-NEXT: },
|
||||
// MYSTRUCTSTRUCT-NEXT: {
|
||||
// MYSTRUCTSTRUCT-NEXT: "kind": "identifier",
|
||||
// MYSTRUCTSTRUCT-NEXT: "spelling": "MyStructStruct"
|
||||
// MYSTRUCTSTRUCT-NEXT: },
|
||||
// MYSTRUCTSTRUCT-NEXT: {
|
||||
// MYSTRUCTSTRUCT-NEXT: "kind": "text",
|
||||
// MYSTRUCTSTRUCT-NEXT: "spelling": ";"
|
||||
// MYSTRUCTSTRUCT-NEXT: }
|
||||
// MYSTRUCTSTRUCT-NEXT:],
|
||||
// MYSTRUCTSTRUCT: "kind": {
|
||||
// MYSTRUCTSTRUCT-NEXT: "displayName": "Type Alias",
|
||||
// MYSTRUCTSTRUCT-NEXT: "identifier": "c.typealias"
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYENUM
|
||||
// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix CASE
|
||||
typedef MyStructStruct MyStructStructStruct;
|
||||
typedef enum { Case } MyEnum;
|
||||
// MYENUM: "source": "c:@EA@MyEnum@Case",
|
||||
// MYENUM-NEXT: "target": "c:@EA@MyEnum",
|
||||
// MYENUM-NEXT: "targetFallback": "MyEnum"
|
||||
// MYENUM-LABEL: "!testLabel": "c:@EA@MyEnum"
|
||||
// MYENUM: "declarationFragments": [
|
||||
// MYENUM-NEXT: {
|
||||
// MYENUM-NEXT: "kind": "keyword",
|
||||
// MYENUM-NEXT: "spelling": "typedef"
|
||||
// MYENUM-NEXT: },
|
||||
// MYENUM-NEXT: {
|
||||
// MYENUM-NEXT: "kind": "text",
|
||||
// MYENUM-NEXT: "spelling": " "
|
||||
// MYENUM-NEXT: },
|
||||
// MYENUM-NEXT: {
|
||||
// MYENUM-NEXT: "kind": "keyword",
|
||||
// MYENUM-NEXT: "spelling": "enum"
|
||||
// MYENUM-NEXT: },
|
||||
// MYENUM-NEXT: {
|
||||
// MYENUM-NEXT: "kind": "text",
|
||||
// MYENUM-NEXT: "spelling": " "
|
||||
// MYENUM-NEXT: },
|
||||
// MYENUM-NEXT: {
|
||||
// MYENUM-NEXT: "kind": "identifier",
|
||||
// MYENUM-NEXT: "spelling": "MyEnum"
|
||||
// MYENUM-NEXT: },
|
||||
// MYENUM-NEXT: {
|
||||
// MYENUM-NEXT: "kind": "text",
|
||||
// MYENUM-NEXT: "spelling": ";"
|
||||
// MYENUM-NEXT: }
|
||||
// MYENUM-NEXT:],
|
||||
// MYENUM: "kind": {
|
||||
// MYENUM-NEXT: "displayName": "Enumeration",
|
||||
// MYENUM-NEXT: "identifier": "c.enum"
|
||||
// MYENUM: "title": "MyEnum"
|
||||
|
||||
// CASE-LABEL: "!testLabel": "c:@EA@MyEnum@Case"
|
||||
// CASE: "pathComponents": [
|
||||
// CASE-NEXT: "MyEnum",
|
||||
// CASE-NEXT: "Case"
|
||||
// CASE-NEXT: ]
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYENUMENUM
|
||||
typedef MyEnum MyEnumEnum;
|
||||
// MYENUMENUM-LABEL: "!testLabel": "c:typedef_anonymous_record.c@T@MyEnumEnum"
|
||||
// MYENUMENUM: "declarationFragments": [
|
||||
// MYENUMENUM-NEXT: {
|
||||
// MYENUMENUM-NEXT: "kind": "keyword",
|
||||
// MYENUMENUM-NEXT: "spelling": "typedef"
|
||||
// MYENUMENUM-NEXT: },
|
||||
// MYENUMENUM-NEXT: {
|
||||
// MYENUMENUM-NEXT: "kind": "text",
|
||||
// MYENUMENUM-NEXT: "spelling": " "
|
||||
// MYENUMENUM-NEXT: },
|
||||
// MYENUMENUM-NEXT: {
|
||||
// MYENUMENUM-NEXT: "kind": "typeIdentifier",
|
||||
// MYENUMENUM-NEXT: "preciseIdentifier": "c:@EA@MyEnum",
|
||||
// MYENUMENUM-NEXT: "spelling": "MyEnum"
|
||||
// MYENUMENUM-NEXT: },
|
||||
// MYENUMENUM-NEXT: {
|
||||
// MYENUMENUM-NEXT: "kind": "text",
|
||||
// MYENUMENUM-NEXT: "spelling": " "
|
||||
// MYENUMENUM-NEXT: },
|
||||
// MYENUMENUM-NEXT: {
|
||||
// MYENUMENUM-NEXT: "kind": "identifier",
|
||||
// MYENUMENUM-NEXT: "spelling": "MyEnumEnum"
|
||||
// MYENUMENUM-NEXT: },
|
||||
// MYENUMENUM-NEXT: {
|
||||
// MYENUMENUM-NEXT: "kind": "text",
|
||||
// MYENUMENUM-NEXT: "spelling": ";"
|
||||
// MYENUMENUM-NEXT: }
|
||||
// MYENUMENUM-NEXT: ],
|
||||
// MYENUMENUM: "kind": {
|
||||
// MYENUMENUM-NEXT: "displayName": "Type Alias",
|
||||
// MYENUMENUM-NEXT: "identifier": "c.typealias"
|
||||
// MYENUMENUM-NEXT: },
|
||||
// MYENUMENUM: "title": "MyEnumEnum"
|
||||
|
||||
typedef MyEnumEnum MyEnumEnumEnum;
|
||||
// expected-no-diagnostics
|
||||
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "TypedefChain",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@EA@MyEnum@Case",
|
||||
"target": "c:@EA@MyEnum",
|
||||
"targetFallback": "MyEnum"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "enum"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnum"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@EA@MyEnum"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Enumeration",
|
||||
"identifier": "c.enum"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 8,
|
||||
"line": 3
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnum"
|
||||
}
|
||||
],
|
||||
"title": "MyEnum"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyEnum"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Case"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@EA@MyEnum@Case"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Enumeration Case",
|
||||
"identifier": "c.enum.case"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 15,
|
||||
"line": 3
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Case"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Case"
|
||||
}
|
||||
],
|
||||
"title": "Case"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyEnum",
|
||||
"Case"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "struct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStruct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@SA@MyStruct"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Structure",
|
||||
"identifier": "c.struct"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 8,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStruct"
|
||||
}
|
||||
],
|
||||
"title": "MyStruct"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyStruct"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:@SA@MyStruct",
|
||||
"spelling": "MyStruct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStructStruct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@T@MyStructStruct"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 17,
|
||||
"line": 1
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStructStruct"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStructStruct"
|
||||
}
|
||||
],
|
||||
"title": "MyStructStruct"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyStructStruct"
|
||||
],
|
||||
"type": "c:@SA@MyStruct"
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:input.h@T@MyStructStruct",
|
||||
"spelling": "MyStructStruct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStructStructStruct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@T@MyStructStructStruct"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 23,
|
||||
"line": 2
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStructStructStruct"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyStructStructStruct"
|
||||
}
|
||||
],
|
||||
"title": "MyStructStructStruct"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyStructStructStruct"
|
||||
],
|
||||
"type": "c:input.h@T@MyStructStruct"
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:@EA@MyEnum",
|
||||
"spelling": "MyEnum"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnumEnum"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@T@MyEnumEnum"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 15,
|
||||
"line": 4
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnumEnum"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnumEnum"
|
||||
}
|
||||
],
|
||||
"title": "MyEnumEnum"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyEnumEnum"
|
||||
],
|
||||
"type": "c:@EA@MyEnum"
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:input.h@T@MyEnumEnum",
|
||||
"spelling": "MyEnumEnum"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnumEnumEnum"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@T@MyEnumEnumEnum"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 19,
|
||||
"line": 5
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnumEnumEnum"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "MyEnumEnumEnum"
|
||||
}
|
||||
],
|
||||
"title": "MyEnumEnumEnum"
|
||||
},
|
||||
"pathComponents": [
|
||||
"MyEnumEnumEnum"
|
||||
],
|
||||
"type": "c:input.h@T@MyEnumEnum"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 -extract-api --pretty-sgf --product-name=TypedefChain -target arm64-apple-macosx \
|
||||
// RUN: %clang -extract-api --product-name=TypedefChain -target arm64-apple-macosx \
|
||||
// RUN: -x objective-c-header %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
|
@ -1,146 +1,445 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
|
||||
// RUN: -x c-header %s -triple arm64-apple-macos -o %t/output.symbols.json -verify
|
||||
// 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 -extract-api -target arm64-apple-macosx \
|
||||
// RUN: %t/input.h -o %t/output.json | FileCheck -allow-empty %s
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix TEST
|
||||
// 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
|
||||
typedef struct Test {
|
||||
} Test;
|
||||
// TEST-LABEL: "!testLabel": "c:@S@Test"
|
||||
// TEST: "declarationFragments": [
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "keyword",
|
||||
// TEST-NEXT: "spelling": "typedef"
|
||||
// TEST-NEXT: },
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "text",
|
||||
// TEST-NEXT: "spelling": " "
|
||||
// TEST-NEXT: },
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "keyword",
|
||||
// TEST-NEXT: "spelling": "struct"
|
||||
// TEST-NEXT: },
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "text",
|
||||
// TEST-NEXT: "spelling": " "
|
||||
// TEST-NEXT: },
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "identifier",
|
||||
// TEST-NEXT: "spelling": "Test"
|
||||
// TEST-NEXT: },
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "text",
|
||||
// TEST-NEXT: "spelling": " { ... } "
|
||||
// TEST-NEXT: },
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "identifier",
|
||||
// TEST-NEXT: "spelling": "Test"
|
||||
// TEST-NEXT: },
|
||||
// TEST-NEXT: {
|
||||
// TEST-NEXT: "kind": "text",
|
||||
// TEST-NEXT: "spelling": ";"
|
||||
// TEST-NEXT: }
|
||||
// TEST-NEXT: ],
|
||||
// TEST: "displayName": "Structure",
|
||||
// TEST: "title": "Test"
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix TEST2
|
||||
typedef enum Test2 {
|
||||
simple
|
||||
} Test2;
|
||||
|
||||
// TEST2-LABEL: "!testLabel": "c:@E@Test2"
|
||||
// TEST2: "declarationFragments": [
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "keyword",
|
||||
// TEST2-NEXT: "spelling": "typedef"
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "text",
|
||||
// TEST2-NEXT: "spelling": " "
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "keyword",
|
||||
// TEST2-NEXT: "spelling": "enum"
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "text",
|
||||
// TEST2-NEXT: "spelling": " "
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "identifier",
|
||||
// TEST2-NEXT: "spelling": "Test2"
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "text",
|
||||
// TEST2-NEXT: "spelling": ": "
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "typeIdentifier",
|
||||
// TEST2-NEXT: "preciseIdentifier": "c:i",
|
||||
// TEST2-NEXT: "spelling": "unsigned int"
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "text",
|
||||
// TEST2-NEXT: "spelling": " { ... } "
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "identifier",
|
||||
// TEST2-NEXT: "spelling": "Test2"
|
||||
// TEST2-NEXT: },
|
||||
// TEST2-NEXT: {
|
||||
// TEST2-NEXT: "kind": "text",
|
||||
// TEST2-NEXT: "spelling": ";"
|
||||
// TEST2-NEXT: }
|
||||
// TEST2-NEXT: ],
|
||||
// TEST2: "displayName": "Enumeration",
|
||||
// TEST2: "title": "Test2"
|
||||
|
||||
struct Foo;
|
||||
|
||||
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix TYPEDEF
|
||||
typedef struct Foo TypedefedFoo;
|
||||
// TYPEDEF-LABEL: "!testLabel": "c:typedef_struct_enum.c@T@TypedefedFoo"
|
||||
// TYPEDEF: "declarationFragments": [
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "keyword",
|
||||
// TYPEDEF-NEXT: "spelling": "typedef"
|
||||
// TYPEDEF-NEXT: },
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "text",
|
||||
// TYPEDEF-NEXT: "spelling": " "
|
||||
// TYPEDEF-NEXT: },
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "keyword",
|
||||
// TYPEDEF-NEXT: "spelling": "struct"
|
||||
// TYPEDEF-NEXT: },
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "text",
|
||||
// TYPEDEF-NEXT: "spelling": " "
|
||||
// TYPEDEF-NEXT: },
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "typeIdentifier",
|
||||
// TYPEDEF-NEXT: "preciseIdentifier": "c:@S@Foo",
|
||||
// TYPEDEF-NEXT: "spelling": "Foo"
|
||||
// TYPEDEF-NEXT: },
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "text",
|
||||
// TYPEDEF-NEXT: "spelling": " "
|
||||
// TYPEDEF-NEXT: },
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "identifier",
|
||||
// TYPEDEF-NEXT: "spelling": "TypedefedFoo"
|
||||
// TYPEDEF-NEXT: },
|
||||
// TYPEDEF-NEXT: {
|
||||
// TYPEDEF-NEXT: "kind": "text",
|
||||
// TYPEDEF-NEXT: "spelling": ";"
|
||||
// TYPEDEF-NEXT: }
|
||||
// TYPEDEF-NEXT: ],
|
||||
// TYPEDEF: "displayName": "Type Alias",
|
||||
// TYPEDEF: "title": "TypedefedFoo"
|
||||
// TYPEDEF: "type": "c:@S@Foo"
|
||||
|
||||
struct Foo {
|
||||
int bar;
|
||||
};
|
||||
|
||||
// expected-no-diagnostics
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@E@Test2@simple",
|
||||
"target": "c:@E@Test2",
|
||||
"targetFallback": "Test2"
|
||||
},
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@S@Foo@FI@bar",
|
||||
"target": "c:@S@Foo",
|
||||
"targetFallback": "Foo"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "enum"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test2"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ": "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:i",
|
||||
"spelling": "unsigned int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " { ... } "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test2"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@E@Test2"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Enumeration",
|
||||
"identifier": "c.enum"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 13,
|
||||
"line": 3
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test2"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test2"
|
||||
}
|
||||
],
|
||||
"title": "Test2"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Test2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "simple"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@E@Test2@simple"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Enumeration Case",
|
||||
"identifier": "c.enum.case"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 2,
|
||||
"line": 4
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "simple"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "simple"
|
||||
}
|
||||
],
|
||||
"title": "simple"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Test2",
|
||||
"simple"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "struct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " { ... } "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@S@Test"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Structure",
|
||||
"identifier": "c.struct"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 15,
|
||||
"line": 0
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Test"
|
||||
}
|
||||
],
|
||||
"title": "Test"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "struct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Foo"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@S@Foo"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Structure",
|
||||
"identifier": "c.struct"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 7,
|
||||
"line": 9
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Foo"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "Foo"
|
||||
}
|
||||
],
|
||||
"title": "Foo"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "bar"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@S@Foo@FI@bar"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 8,
|
||||
"line": 10
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "bar"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "bar"
|
||||
}
|
||||
],
|
||||
"title": "bar"
|
||||
},
|
||||
"pathComponents": [
|
||||
"Foo",
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "struct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:@S@Foo",
|
||||
"spelling": "Foo"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "TypedefedFoo"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@T@TypedefedFoo"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 19,
|
||||
"line": 8
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "TypedefedFoo"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "TypedefedFoo"
|
||||
}
|
||||
],
|
||||
"title": "TypedefedFoo"
|
||||
},
|
||||
"pathComponents": [
|
||||
"TypedefedFoo"
|
||||
],
|
||||
"type": "c:@S@Foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,5 +1,17 @@
|
||||
// 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 -triple arm64-apple-macosx \
|
||||
// RUN: -x c-header %s -o - -verify | FileCheck %s
|
||||
// RUN: -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
|
||||
|
||||
//--- input.h
|
||||
// expected-no-diagnostics
|
||||
|
||||
// Global record
|
||||
int _HiddenGlobal;
|
||||
@ -7,22 +19,399 @@ int exposed_global;
|
||||
|
||||
// Record type
|
||||
struct _HiddenRecord {
|
||||
int HiddenRecordMember;
|
||||
int a;
|
||||
};
|
||||
|
||||
struct ExposedRecord {
|
||||
int ExposedRecordMember;
|
||||
int a;
|
||||
};
|
||||
|
||||
// Typedef
|
||||
typedef struct {} _HiddenTypedef;
|
||||
typedef int ExposedTypedef;
|
||||
typedef _HiddenTypedef ExposedTypedefToHidden;
|
||||
|
||||
// Macros
|
||||
#define _HIDDEN_MACRO 5
|
||||
#define EXPOSED_MACRO 5
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
// CHECK-NOT: _HiddenRecord
|
||||
// CHECK-NOT: HiddenRecordMember
|
||||
// CHECK: ExposedRecord
|
||||
// CHECK: ExposedRecordMember
|
||||
// CHECK-NOT: _HIDDEN_MACRO
|
||||
// CHECK: EXPOSED_MACRO
|
||||
// Symbols that start with '_' should not appear in the reference output
|
||||
//--- reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationships": [
|
||||
{
|
||||
"kind": "memberOf",
|
||||
"source": "c:@S@ExposedRecord@FI@a",
|
||||
"target": "c:@S@ExposedRecord",
|
||||
"targetFallback": "ExposedRecord"
|
||||
}
|
||||
],
|
||||
"symbols": [
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "exposed_global"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@exposed_global"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Global Variable",
|
||||
"identifier": "c.var"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 4,
|
||||
"line": 4
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "exposed_global"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "exposed_global"
|
||||
}
|
||||
],
|
||||
"title": "exposed_global"
|
||||
},
|
||||
"pathComponents": [
|
||||
"exposed_global"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "struct"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedRecord"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@S@ExposedRecord"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Structure",
|
||||
"identifier": "c.struct"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 7,
|
||||
"line": 11
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedRecord"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedRecord"
|
||||
}
|
||||
],
|
||||
"title": "ExposedRecord"
|
||||
},
|
||||
"pathComponents": [
|
||||
"ExposedRecord"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "a"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@S@ExposedRecord@FI@a"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Instance Property",
|
||||
"identifier": "c.property"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 6,
|
||||
"line": 12
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "a"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "a"
|
||||
}
|
||||
],
|
||||
"title": "a"
|
||||
},
|
||||
"pathComponents": [
|
||||
"ExposedRecord",
|
||||
"a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "#define"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "EXPOSED_MACRO"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@335@macro@EXPOSED_MACRO"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Macro",
|
||||
"identifier": "c.macro"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 8,
|
||||
"line": 22
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "EXPOSED_MACRO"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "EXPOSED_MACRO"
|
||||
}
|
||||
],
|
||||
"title": "EXPOSED_MACRO"
|
||||
},
|
||||
"pathComponents": [
|
||||
"EXPOSED_MACRO"
|
||||
]
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:I",
|
||||
"spelling": "int"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedTypedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@T@ExposedTypedef"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 12,
|
||||
"line": 17
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedTypedef"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedTypedef"
|
||||
}
|
||||
],
|
||||
"title": "ExposedTypedef"
|
||||
},
|
||||
"pathComponents": [
|
||||
"ExposedTypedef"
|
||||
],
|
||||
"type": "c:I"
|
||||
},
|
||||
{
|
||||
"accessLevel": "public",
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "keyword",
|
||||
"spelling": "typedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:@SA@_HiddenTypedef",
|
||||
"spelling": "_HiddenTypedef"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedTypedefToHidden"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": ";"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:input.h@T@ExposedTypedefToHidden"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Type Alias",
|
||||
"identifier": "c.typealias"
|
||||
},
|
||||
"location": {
|
||||
"position": {
|
||||
"character": 23,
|
||||
"line": 18
|
||||
},
|
||||
"uri": "file://INPUT_DIR/input.h"
|
||||
},
|
||||
"names": {
|
||||
"navigator": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedTypedefToHidden"
|
||||
}
|
||||
],
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "ExposedTypedefToHidden"
|
||||
}
|
||||
],
|
||||
"title": "ExposedTypedefToHidden"
|
||||
},
|
||||
"pathComponents": [
|
||||
"ExposedTypedefToHidden"
|
||||
],
|
||||
"type": "c:@SA@_HiddenTypedef"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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 --pretty-sgf -triple arm64-apple-macosx -x c-header\
|
||||
// RUN: %clang_cc1 -extract-api -triple arm64-apple-macosx -x c-header\
|
||||
// RUN: %t/input.h -o %t/output.json -verify
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
//--- input.h
|
||||
/// My Union
|
||||
union Union {
|
||||
union Union{
|
||||
/// the a option
|
||||
int a;
|
||||
/// the b option
|
||||
|
@ -14,7 +14,7 @@
|
||||
// RUN: %t/vfsoverlay.yaml.in >> %t/vfsoverlay.yaml
|
||||
|
||||
// Input headers use paths to the framework root/DSTROOT
|
||||
// RUN: %clang_cc1 -extract-api --pretty-sgf -v --product-name=MyFramework \
|
||||
// RUN: %clang_cc1 -extract-api -v --product-name=MyFramework \
|
||||
// RUN: -triple arm64-apple-macosx \
|
||||
// RUN: -iquote%t -ivfsoverlay %t/vfsoverlay.yaml -F%t/Frameworks \
|
||||
// RUN: -x objective-c-header \
|
||||
|
@ -31,8 +31,6 @@ struct Foo {
|
||||
- (void)derivedMethodWithValue:(id<Protocol>)value {
|
||||
int a = 5;
|
||||
}
|
||||
/// Impl only docs
|
||||
- (void)implOnlyMethod { }
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -single-symbol-sgf-at=%s:4:9 local %s | FileCheck -check-prefix=CHECK-FOO %s
|
||||
@ -120,10 +118,3 @@ struct Foo {
|
||||
// CHECK-DERIVED-METHOD-IMPL: "text":"Derived method docs"
|
||||
// CHECK-DERIVED-METHOD-IMPL: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
|
||||
// CHECK-DERIVED-METHOD-IMPL: "title":"derivedMethodWithValue:"
|
||||
|
||||
// RUN: c-index-test -single-symbol-sgf-at=%s:35:11 local %s | FileCheck -check-prefix=CHECK-IMPL-ONLY %s
|
||||
// CHECK-IMPL-ONLY: "relatedSymbols":[]
|
||||
// CHECK-IMPL-ONLY: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Derived(im)implOnlyMethod","target":"c:objc(cs)Derived"
|
||||
// CHECK-IMPL-ONLY: "text":"Impl only docs"
|
||||
// CHECK-IMPL-ONLY: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"}
|
||||
// CHECK-IMPL-ONLY: "title":"implOnlyMethod"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "clang-c/Index.h"
|
||||
#include "clang-c/Platform.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/ExtractAPI/API.h"
|
||||
@ -55,20 +54,41 @@ struct LibClangExtractAPIVisitor
|
||||
if (!shouldDeclBeIncluded(Decl))
|
||||
return true;
|
||||
|
||||
auto *Interface = Decl->getClassInterface();
|
||||
const ObjCInterfaceDecl *Interface = Decl->getClassInterface();
|
||||
StringRef Name = Interface->getName();
|
||||
StringRef USR = API.recordUSR(Decl);
|
||||
PresumedLoc Loc =
|
||||
Context.getSourceManager().getPresumedLoc(Decl->getLocation());
|
||||
LinkageInfo Linkage = Decl->getLinkageAndVisibility();
|
||||
DocComment Comment;
|
||||
if (auto *RawComment = fetchRawCommentForDecl(Interface))
|
||||
Comment = RawComment->getFormattedLines(Context.getSourceManager(),
|
||||
Context.getDiagnostics());
|
||||
|
||||
if (!VisitObjCInterfaceDecl(Interface))
|
||||
return false;
|
||||
// Build declaration fragments and sub-heading by generating them for the
|
||||
// interface.
|
||||
DeclarationFragments Declaration =
|
||||
DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Interface);
|
||||
DeclarationFragments SubHeading =
|
||||
DeclarationFragmentsBuilder::getSubHeading(Decl);
|
||||
|
||||
SmallString<128> USR;
|
||||
index::generateUSRForDecl(Interface, USR);
|
||||
|
||||
if (auto *InterfaceRecord = dyn_cast_if_present<ObjCInterfaceRecord>(
|
||||
API.findRecordForUSR(USR))) {
|
||||
recordObjCMethods(InterfaceRecord, Decl->methods());
|
||||
recordObjCProperties(InterfaceRecord, Decl->properties());
|
||||
recordObjCInstanceVariables(InterfaceRecord, Decl->ivars());
|
||||
// Collect super class information.
|
||||
SymbolReference SuperClass;
|
||||
if (const auto *SuperClassDecl = Decl->getSuperClass()) {
|
||||
SuperClass.Name = SuperClassDecl->getObjCRuntimeNameAsString();
|
||||
SuperClass.USR = API.recordUSR(SuperClassDecl);
|
||||
}
|
||||
|
||||
ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface(
|
||||
Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage,
|
||||
Comment, Declaration, SubHeading, SuperClass, isInSystemHeader(Decl));
|
||||
|
||||
// Record all methods (selectors). This doesn't include automatically
|
||||
// synthesized property methods.
|
||||
recordObjCMethods(ObjCInterfaceRecord, Decl->methods());
|
||||
recordObjCProperties(ObjCInterfaceRecord, Decl->properties());
|
||||
recordObjCInstanceVariables(ObjCInterfaceRecord, Decl->ivars());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -76,14 +96,21 @@ struct LibClangExtractAPIVisitor
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(APISet, CXAPISet)
|
||||
|
||||
// Visits the Decl D and it's transitive DeclContexts recursively, starting from
|
||||
// the outer-most context. This is guaranteed to visit every Decl we need in the
|
||||
// right order to generate symbol graph information for D.
|
||||
static void WalkupFromMostDerivedType(LibClangExtractAPIVisitor &Visitor,
|
||||
Decl *D);
|
||||
|
||||
template <typename DeclTy>
|
||||
static bool WalkupParentContext(DeclContext *Parent,
|
||||
LibClangExtractAPIVisitor &Visitor) {
|
||||
if (auto *D = dyn_cast<DeclTy>(Parent)) {
|
||||
WalkupFromMostDerivedType(Visitor, D);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void WalkupFromMostDerivedType(LibClangExtractAPIVisitor &Visitor,
|
||||
Decl *D) {
|
||||
if (auto *Parent = D->getDeclContext())
|
||||
WalkupFromMostDerivedType(Visitor, cast<Decl>(Parent));
|
||||
|
||||
switch (D->getKind()) {
|
||||
#define ABSTRACT_DECL(DECL)
|
||||
#define DECL(CLASS, BASE) \
|
||||
@ -92,12 +119,20 @@ static void WalkupFromMostDerivedType(LibClangExtractAPIVisitor &Visitor,
|
||||
break;
|
||||
#include "clang/AST/DeclNodes.inc"
|
||||
}
|
||||
|
||||
for (auto *Parent = D->getDeclContext(); Parent != nullptr;
|
||||
Parent = Parent->getParent()) {
|
||||
if (WalkupParentContext<ObjCContainerDecl>(Parent, Visitor))
|
||||
return;
|
||||
if (WalkupParentContext<TagDecl>(Parent, Visitor))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static CXString GenerateCXStringFromSymbolGraphData(llvm::json::Object Obj) {
|
||||
llvm::SmallString<0> BackingString;
|
||||
llvm::raw_svector_ostream OS(BackingString);
|
||||
OS << llvm::formatv("{0}", Value(std::move(Obj)));
|
||||
OS << Value(std::move(Obj));
|
||||
return cxstring::createDup(BackingString.str());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user