Skip to content

Commit e376af5

Browse files
committed
Refactor gathering of field type info from a binary into two steps: collect and output.
The collect step can then be used for other tools, such as the `BinaryScanningTool`.
1 parent f93bc64 commit e376af5

File tree

6 files changed

+108
-18
lines changed

6 files changed

+108
-18
lines changed

include/swift-c/StaticMirror/BinaryScan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/// SWIFTSTATICMIRROR_VERSION_MINOR should increase when there are API additions.
2626
/// SWIFTSTATICMIRROR_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
2727
#define SWIFTSTATICMIRROR_VERSION_MAJOR 0
28-
#define SWIFTSTATICMIRROR_VERSION_MINOR 2 // Added associated-type gather
28+
#define SWIFTSTATICMIRROR_VERSION_MINOR 3 // Added filed type info gather
2929

3030
SWIFTSTATICMIRROR_BEGIN_DECLS
3131

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,29 @@ struct AssociatedTypeCollectionResult {
317317
std::vector<std::string> Errors;
318318
};
319319

320+
struct PropertyTypeInfo {
321+
std::string Label;
322+
std::string TypeMangledName;
323+
std::string TypeFullyQualifiedName;
324+
std::string TypeDiagnosticPrintName;
325+
};
326+
327+
struct EnumCaseInfo {
328+
std::string Label;
329+
};
330+
331+
struct FieldMetadata {
332+
std::string MangledTypeName;
333+
std::string FullyQualifiedName;
334+
std::vector<PropertyTypeInfo> Properties;
335+
std::vector<EnumCaseInfo> EnumCases;
336+
};
337+
338+
struct FieldTypeCollectionResult {
339+
std::vector<FieldMetadata> FieldInfos;
340+
std::vector<std::string> Errors;
341+
};
342+
320343
/// An implementation of MetadataReader's BuilderType concept for
321344
/// building TypeRefs, and parsing field metadata from any images
322345
/// it has been made aware of.
@@ -899,6 +922,7 @@ class TypeRefBuilder {
899922

900923
void dumpTypeRef(RemoteRef<char> MangledName, std::ostream &stream,
901924
bool printTypeName = false);
925+
FieldTypeCollectionResult collectFieldTypes(llvm::Optional<std::string> forMangledTypeName);
902926
void dumpFieldSection(std::ostream &stream);
903927
AssociatedTypeCollectionResult collectAssociatedTypes(llvm::Optional<std::string> forMangledTypeName);
904928
void dumpAssociatedTypeSection(std::ostream &stream);

include/swift/StaticMirror/BinaryScanningTool.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ class BinaryScanningTool {
5454
reflection::AssociatedTypeCollectionResult
5555
collectAllAssociatedTypes();
5656

57+
/// Collect all field type infos of the specified type
58+
reflection::FieldTypeCollectionResult
59+
collectFieldTypes(const std::string &mangledTypeName);
60+
61+
/// Collect field type infos of all discovered types
62+
reflection::FieldTypeCollectionResult
63+
collectAllFieldTypes();
64+
5765
private:
5866
// Note: binaryOrError and objectOrError own the memory for our ObjectFile;
5967
// once they go out of scope, we can no longer do anything.

lib/StaticMirror/BinaryScanningTool.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,15 @@ AssociatedTypeCollectionResult
8787
BinaryScanningTool::collectAllAssociatedTypes() {
8888
return Context->Builder.collectAssociatedTypes(llvm::Optional<std::string>());
8989
}
90+
91+
FieldTypeCollectionResult
92+
BinaryScanningTool::collectFieldTypes(const std::string &mangledTypeName) {
93+
return Context->Builder.collectFieldTypes(mangledTypeName);
94+
}
95+
96+
FieldTypeCollectionResult
97+
BinaryScanningTool::collectAllFieldTypes() {
98+
return Context->Builder.collectFieldTypes(llvm::Optional<std::string>());
99+
}
90100
} // end namespace static_mirror
91101
} // end namespace swift

stdlib/public/Reflection/TypeRefBuilder.cpp

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -432,30 +432,76 @@ void TypeRefBuilder::dumpTypeRef(RemoteRef<char> MangledName,
432432
stream << "\n";
433433
}
434434

435-
void TypeRefBuilder::dumpFieldSection(std::ostream &stream) {
435+
FieldTypeCollectionResult TypeRefBuilder::collectFieldTypes(
436+
llvm::Optional<std::string> forMangledTypeName) {
437+
FieldTypeCollectionResult result;
436438
for (const auto &sections : ReflectionInfos) {
437439
for (auto descriptor : sections.Field) {
438-
auto TypeDemangling =
439-
demangleTypeRef(readTypeRef(descriptor, descriptor->MangledTypeName));
440-
auto TypeName = nodeToString(TypeDemangling);
440+
auto typeRef = readTypeRef(descriptor, descriptor->MangledTypeName);
441+
auto typeName = nodeToString(demangleTypeRef(typeRef));
442+
auto optionalMangledTypeName = normalizeReflectionName(typeRef);
441443
clearNodeFactory();
442-
stream << TypeName.c_str() << "\n";
443-
for (size_t i = 0; i < TypeName.size(); ++i)
444-
stream << "-";
445-
stream << "\n";
446-
for (auto &fieldRef : *descriptor.getLocalBuffer()) {
447-
auto field = descriptor.getField(fieldRef);
448-
auto fieldName = getTypeRefString(readTypeRef(field, field->FieldName));
449-
stream.write(fieldName.data(), fieldName.size());
450-
if (field->hasMangledTypeName()) {
451-
stream << ": ";
452-
dumpTypeRef(readTypeRef(field, field->MangledTypeName), stream);
453-
} else {
454-
stream << "\n\n";
444+
if (optionalMangledTypeName.hasValue()) {
445+
auto mangledTypeName =
446+
optionalMangledTypeName.getValue().insert(0, "$s");
447+
if (forMangledTypeName.hasValue()) {
448+
if (mangledTypeName != forMangledTypeName.getValue())
449+
continue;
455450
}
451+
452+
std::vector<PropertyTypeInfo> properties;
453+
std::vector<EnumCaseInfo> enumCases;
454+
for (auto &fieldRef : *descriptor.getLocalBuffer()) {
455+
auto field = descriptor.getField(fieldRef);
456+
auto fieldName = getTypeRefString(readTypeRef(field, field->FieldName));
457+
if (field->hasMangledTypeName()) {
458+
std::string mangledFieldTypeName =
459+
std::string(field->MangledTypeName);
460+
auto fieldTypeRef = readTypeRef(field, field->MangledTypeName);
461+
auto optionalMangledfieldTypeName =
462+
normalizeReflectionName(fieldTypeRef);
463+
if (optionalMangledfieldTypeName.hasValue()) {
464+
mangledFieldTypeName =
465+
"$s" + optionalMangledfieldTypeName.getValue();
466+
}
467+
auto fieldTypeDemangleTree = demangleTypeRef(fieldTypeRef);
468+
auto fieldTypeName = nodeToString(fieldTypeDemangleTree);
469+
std::stringstream OS;
470+
dumpTypeRef(fieldTypeRef, OS);
471+
properties.emplace_back(PropertyTypeInfo{fieldName.str(),
472+
mangledFieldTypeName,
473+
fieldTypeName, OS.str()});
474+
} else {
475+
enumCases.emplace_back(EnumCaseInfo{fieldName.str()});
476+
}
477+
}
478+
result.FieldInfos.emplace_back(FieldMetadata{
479+
mangledTypeName, typeName, properties, enumCases});
456480
}
457481
}
458482
}
483+
484+
return result;
485+
}
486+
487+
void TypeRefBuilder::dumpFieldSection(std::ostream &stream) {
488+
auto fieldInfoCollectionResult =
489+
collectFieldTypes(llvm::Optional<std::string>());
490+
for (const auto &info : fieldInfoCollectionResult.FieldInfos) {
491+
stream << info.FullyQualifiedName << "\n";
492+
for (size_t i = 0; i < info.FullyQualifiedName.size(); ++i)
493+
stream << "-";
494+
stream << "\n";
495+
for (const auto &field : info.Properties) {
496+
stream << field.Label;
497+
stream << ": ";
498+
stream << field.TypeDiagnosticPrintName;
499+
}
500+
for (const auto &field : info.EnumCases) {
501+
stream << field.Label;
502+
stream << "\n\n";
503+
}
504+
}
459505
}
460506

461507
AssociatedTypeCollectionResult TypeRefBuilder::collectAssociatedTypes(

tools/swift-reflection-dump/swift-reflection-dump.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "llvm/Support/CommandLine.h"
3131
#include "llvm/Support/Error.h"
3232

33+
#include "swift/StaticMirror/BinaryScanningTool.h"
34+
3335
#if defined(_WIN32)
3436
#include <io.h>
3537
#else

0 commit comments

Comments
 (0)