Skip to content

Commit 691acba

Browse files
committed
[Parser] Improve parsing of types with structural generics
1 parent 129360b commit 691acba

File tree

4 files changed

+66
-11
lines changed

4 files changed

+66
-11
lines changed

ClassDump.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@
455455
ALWAYS_SEARCH_USER_PATHS = NO;
456456
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
457457
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
458-
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
458+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
459459
CLANG_CXX_LIBRARY = "libc++";
460460
CLANG_ENABLE_MODULES = YES;
461461
CLANG_ENABLE_OBJC_ARC = YES;
@@ -521,7 +521,7 @@
521521
ALWAYS_SEARCH_USER_PATHS = NO;
522522
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
523523
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
524-
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
524+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
525525
CLANG_CXX_LIBRARY = "libc++";
526526
CLANG_ENABLE_MODULES = YES;
527527
CLANG_ENABLE_OBJC_ARC = YES;

ClassDump/Services/CDTypeParser.m

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -538,24 +538,60 @@ + (CDRecordType *)recordTypeForEncodingStart:(const char *const)start end:(const
538538
CDRecordType *record = [CDRecordType new];
539539
record.isUnion = isUnion;
540540

541-
size_t nameOffset = 1;
542-
while (start[nameOffset] != '=' && start[nameOffset] != '}') {
543-
nameOffset++;
541+
const char *chr = start;
542+
543+
unsigned openTokens = 1;
544+
while (1) {
545+
const char token = *++chr;
546+
547+
if (isStruct) {
548+
switch (token) {
549+
case '{':
550+
openTokens++;
551+
break;
552+
case '}':
553+
openTokens--;
554+
break;
555+
default:
556+
break;
557+
}
558+
}
559+
560+
if (isUnion) {
561+
switch (token) {
562+
case '(':
563+
openTokens++;
564+
break;
565+
case ')':
566+
openTokens--;
567+
break;
568+
default:
569+
break;
570+
}
571+
}
572+
573+
if (openTokens == 0) {
574+
break; // we've reached the end - we're done
575+
}
576+
if (openTokens == 1 && token == '=') {
577+
break; // we hit the name indicator for the current "scope"
578+
}
544579
}
545-
nameOffset++;
580+
// we've already read this token, move over
581+
chr++;
546582

547583
// anonymous indicator
548-
if (nameOffset != 3 && start[1] != '?') {
549-
record.name = [[NSString alloc] initWithBytes:(start + 1) length:(nameOffset - 2) encoding:NSUTF8StringEncoding];
584+
if (chr != (start + 3) && start[1] != '?') {
585+
record.name = [[NSString alloc] initWithBytes:(start + 1) length:((chr - start) - 2) encoding:NSUTF8StringEncoding];
550586
}
551587
// no content, usually caused by multiple levels of indirection
552-
if (nameOffset == (end - start)) {
588+
if (chr == end) {
553589
return record;
554590
}
555591

556592
NSMutableArray<CDVariableModel *> *fields = [NSMutableArray array];
557593

558-
for (const char *chr = start + nameOffset; chr < endToken;) {
594+
while (chr < endToken) {
559595
CDVariableModel *variableModel = [CDVariableModel new];
560596

561597
if (*chr == '"') {

ClassDumpTests/CDParseCppTests.mm

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ @implementation CDParseCppTests
3535
};
3636
}
3737

38+
39+
struct MatrixDimensions {
40+
unsigned width, height;
41+
};
42+
43+
template<MatrixDimensions Dimensions>
44+
class MatrixFixedPoint {
45+
short storage[Dimensions.height][Dimensions.width];
46+
};
47+
48+
3849
- (void)testClass {
3950
CDParseType *type = [CDTypeParser typeForEncoding:@encode(SuperUser)];
4051
XCTAssert([[type stringForVariableName:@"var"] isEqualToString:@"struct SuperUser { "
@@ -59,4 +70,11 @@ - (void)testNamespace {
5970
"} var"]);
6071
}
6172

73+
- (void)testStructuralGenerics {
74+
CDParseType *type = [CDTypeParser typeForEncoding:@encode(MatrixFixedPoint<MatrixDimensions { 32, 8 }>)];
75+
XCTAssert([[type stringForVariableName:@"var"] isEqualToString:@"struct MatrixFixedPoint<MatrixDimensions{32, 8}> { "
76+
"short x0[8][32]; "
77+
"} var"]);
78+
}
79+
6280
@end

Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ let package = Package(
2828
dependencies: ["ClassDumpRuntime"],
2929
path: "ClassDumpTests"
3030
),
31-
]
31+
],
32+
cxxLanguageStandard: .cxx20
3233
)

0 commit comments

Comments
 (0)