diff --git a/clang/lib/Frontend/Rewrite/RewriteBSC.cpp b/clang/lib/Frontend/Rewrite/RewriteBSC.cpp index cc24e52ef5a5d724d4e13fa808b7e4d28763ebf2..38ee46fa29b8f1a5bcb0952af116bcbb3fd16b48 100644 --- a/clang/lib/Frontend/Rewrite/RewriteBSC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteBSC.cpp @@ -116,15 +116,16 @@ public: Visit(FieldDecl); graph.addDependency(FieldDecl, RD); } - if (const ArrayType *AT = dyn_cast(FieldType)) { - // Recursive to get innermost element type. - QualType ElementType = AT->getElementType(); - while (const ArrayType *at = dyn_cast(ElementType)) { - ElementType = at->getElementType(); + if (const ArrayType *AT = FieldType->getAsArrayTypeUnsafe()) { + RecordDecl *FieldDecl = ProcessArrayType(AT); + if (FieldDecl) { + Visit(FieldDecl); + graph.addDependency(FieldDecl, RD); } - if (const RecordType *RT = ElementType->getAs()) { - RecordDecl *FieldDecl = RT->getDecl(); - // Recursive for nested type definitions. + } + if (const PointerType *PT = FieldType->getAs()) { + RecordDecl *FieldDecl = ProcessPointerType(PT); + if (FieldDecl) { Visit(FieldDecl); graph.addDependency(FieldDecl, RD); } @@ -138,6 +139,33 @@ public: } } + RecordDecl *ProcessArrayType(const ArrayType *AT) { + // Recursive to get innermost element type. + QualType ElementType = AT->getElementType(); + while (const ArrayType *at = ElementType->getAsArrayTypeUnsafe()) { + ElementType = at->getElementType(); + } + if (const RecordType *RT = ElementType->getAs()) { + return RT->getDecl(); + } + if (const PointerType *PT = ElementType->getAs()) { + return ProcessPointerType(PT); + } + return nullptr; + } + + RecordDecl *ProcessPointerType(const PointerType *PT) { + // Recursive to get innermost pointee type. + QualType PointeeType = PT->getPointeeType(); + while (const PointerType *InnerPT = PointeeType->getAs()) { + PointeeType = InnerPT->getPointeeType(); + } + if (const ArrayType *AT = PointeeType->getAsArrayTypeUnsafe()) { + return ProcessArrayType(AT); + } + return nullptr; + } + std::vector Sort() { return graph.topologicalSort(); } private: diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/rewrite_pointee_array_type/rewrite_pointee_array_type.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/rewrite_pointee_array_type/rewrite_pointee_array_type.cbs new file mode 100644 index 0000000000000000000000000000000000000000..b7277ab05091ec3bb4cbc1e2603ed68b900bb688 --- /dev/null +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/rewrite_pointee_array_type/rewrite_pointee_array_type.cbs @@ -0,0 +1,64 @@ +// RUN: %clang %s -o %t.output +// RUN: %t.output +// RUN: %clang -rewrite-bsc %s -o %t-rw.c +// RUN: FileCheck --input-file=%t-rw.c %s +// RUN: %clang %t-rw.c -o %t-rw.output +// RUN: %t-rw.output + +struct T { + T1 (*a[2])[5]; + T2 (**b)[2]; + T3 (*c)[5]; +}; + +struct S { + int a; +}; + +struct M { + int a; +}; + +struct N { + int a; +}; + +void test(T t) { +} + +int main() { + T t; + test(t); + return 0; +} + +// CHECK: struct T_struct_S_struct_M_struct_N; +// CHECK-NEXT: struct S; +// CHECK-NEXT: struct M; +// CHECK-NEXT: struct N; +// CHECK-NEXT: struct S { +// CHECK-NEXT: int a; +// CHECK-NEXT: }; + +// CHECK: struct M { +// CHECK-NEXT: int a; +// CHECK-NEXT: }; + +// CHECK: struct N { +// CHECK-NEXT: int a; +// CHECK-NEXT: }; + +// CHECK: struct T_struct_S_struct_M_struct_N { +// CHECK-NEXT: struct S (*a[2])[5]; +// CHECK-NEXT: struct M (**b)[2]; +// CHECK-NEXT: struct N (*c)[5]; +// CHECK-NEXT: }; + +// CHECK: void test(struct T_struct_S_struct_M_struct_N t) { +// CHECK-NEXT: } + +// CHECK: int main(void) { +// CHECK-NEXT: struct T_struct_S_struct_M_struct_N t; +// CHECK-NEXT: test(t); +// CHECK-NEXT: return 0; +// CHECK-NEXT: }