diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index 14d2a2189da238fe70db4fa9d6392f8bf22d18fe..3e33b91430459eb44118c051e14bf2245136b08f 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -77,7 +77,7 @@ struct PrintingPolicy { CleanUglifiedParameters(false), EntireContentsOfLargeArray(true), UseEnumerators(true) #if ENABLE_BSC - , RewriteBSC(false), FunctionDeclaraionOnly(false) + , RewriteBSC(false), FunctionDeclarationOnly(false) #endif { } @@ -322,7 +322,7 @@ struct PrintingPolicy { /// Whether printing function declaration only while rewriting BSC source /// code. - unsigned FunctionDeclaraionOnly : 1; + unsigned FunctionDeclarationOnly : 1; #endif /// Callbacks to use to allow the behavior of printing to be customized. diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index d7b9524b3c1369709b307d13fc5ba2a1732b8942..a99b138d417431c1aec659d8772e88ae7500810a 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -958,7 +958,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } #if ENABLE_BSC - if (!Policy.FunctionDeclaraionOnly) { + if (!Policy.FunctionDeclarationOnly) { #endif if (D->getBody()) D->getBody()->printPrettyControlled(Out, nullptr, SubPolicy, diff --git a/clang/lib/Frontend/Rewrite/RewriteBSC.cpp b/clang/lib/Frontend/Rewrite/RewriteBSC.cpp index 76d2d513e6a31ab676a7d95689676dc7ae3e9c52..464a26f320f24a313b570a2d65be69fe5cc9cd98 100644 --- a/clang/lib/Frontend/Rewrite/RewriteBSC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteBSC.cpp @@ -205,6 +205,7 @@ private: std::set RetrieveFileIDsFromIncludeStack(const Decl *D); void RewriteMacroDirectives(); void RewriteDecls(); + void RewriteRecordDeclaration(std::vector &DeclList); void RewriteTypedefAndEnum(std::vector &DeclList); void RewriteTypeDefinitions(std::vector &DeclList); void @@ -536,10 +537,13 @@ void RewriteBSC::RewriteDecls() { // avoid repeatedly rewrite of Template Functions. std::set RewritedFunctionDeclarationSet; - // Step 1: Collect all enum decls and typedef decls into DeclList. + // Step 1: Collect all record decls and instatiation struct decls. + RewriteRecordDeclaration(DeclList); + + // Step 2: Collect all enum decls and typedef decls into DeclList. RewriteTypedefAndEnum(DeclList); - // Step 2: Rewrite type definitions of user defined types, which is sorted by + // Step 3: Rewrite type definitions of user defined types, which is sorted by // type dependencies. RewriteTypeDefinitions(DeclList); @@ -568,18 +572,69 @@ void RewriteBSC::RewriteDecls() { } } - // Step 3: Collect all instatiation function declarations. - Policy.FunctionDeclaraionOnly = true; + // Step 4: Collect all instatiation function declarations. + Policy.FunctionDeclarationOnly = true; RewriteInstantFunctionDecl(DeclList, RewritedFunctionDeclarationSet); - // Step 4: Collect non-generic function definitions and var decls. - Policy.FunctionDeclaraionOnly = false; + // Step 5: Collect non-generic function definitions and var decls. + Policy.FunctionDeclarationOnly = false; RewriteNonGenericFuncAndVar(DeclList); - // Step 5: Collect all instatiation function definition. + // Step 6: Collect all instatiation function definition. RewriteInstantFunctionDef(DeclList); } +void RewriteBSC::RewriteRecordDeclaration(std::vector &DeclList) { + for (Decl *D : TUDecl->decls()) { + // Skip declarations in header files with suffix .h. + if (IsInStandardHeaderFile(SM, D->getLocation())) { + continue; + } + switch (D->getKind()) { + case Decl::Record: { + RecordDecl *RD = dyn_cast(D); + // Skip incomplete record decl. + if (!RD->isCompleteDefinition()) + break; + // Because we only want to print the declaration of the struct, + // we set it to incomplete before printing, and then restore it after + // printing. + RD->setCompleteDefinition(false); + RD->print(Buf, Policy); + Buf << ";\n"; + RD->setCompleteDefinition(true); + break; + } + case Decl::ClassTemplate: { + ClassTemplateDecl *CTD = cast(D); + // Skip incomplete generic struct decl. + RecordDecl *RD = NULL; + if ((RD = dyn_cast(CTD->getTemplatedDecl()))) { + if (!RD->isCompleteDefinition()) { + break; + } + } + for (ClassTemplateSpecializationDecl *CTSD : CTD->specializations()) { + // Because we only want to print the declaration of the generic struct, + // we set it to incomplete before printing, and then restore it after + // printing. + RD->setCompleteDefinition(false); + bool isCompleted = CTSD->isCompleteDefinition(); + if (isCompleted) + CTSD->setCompleteDefinition(false); + CTSD->print(Buf, Policy); + Buf << ";\n"; + RD->setCompleteDefinition(true); + CTSD->setCompleteDefinition(isCompleted); + } + break; + } + default: + break; + } + } +} + void RewriteBSC::RewriteTypedefAndEnum(std::vector &DeclList) { for (Decl *D : TUDecl->decls()) { // Skip declarations in header files with suffix .h. diff --git a/clang/lib/Sema/BSC/SemaBSCTrait.cpp b/clang/lib/Sema/BSC/SemaBSCTrait.cpp index 683b146b90444ec83e652e524bd87de12ac643d9..fb974bd00cfd2c8fdd30108359dce4686348610d 100644 --- a/clang/lib/Sema/BSC/SemaBSCTrait.cpp +++ b/clang/lib/Sema/BSC/SemaBSCTrait.cpp @@ -336,7 +336,6 @@ static bool IsImplTraitDeclIllegal(Sema &S, QualType TraitQT, QualType &ImplQT, SourceLocation TypeLoc, TraitDecl *TD, QualType OriginTraitTy) { CXXScopeSpec SS; - NamedDecl *Def = nullptr; if (ImplQT.getCanonicalType()->isRecordType()) { const RecordDecl *RD = diff --git a/clang/test/BSC/Positive/Coroutine/Atmoic/rewrite_atmoic.cbs b/clang/test/BSC/Positive/Coroutine/Atmoic/rewrite_atmoic.cbs index 79326c62873d106d94b056f8e2660fc61b5063d0..79d385c7ead59915745d6e7ad5f22435890a2268 100644 --- a/clang/test/BSC/Positive/Coroutine/Atmoic/rewrite_atmoic.cbs +++ b/clang/test/BSC/Positive/Coroutine/Atmoic/rewrite_atmoic.cbs @@ -46,6 +46,7 @@ int main() { // CHECK: #include // CHECK-EMPTY: // CHECK-EMPTY: +// CHECK-NEXT: struct Person_int_10; // CHECK-NEXT: struct Person_int_10 { // CHECK-NEXT: char name[50]; // CHECK-NEXT: int age; diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_4/rewrite_bsc_generic_4.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_4/rewrite_bsc_generic_4.cbs index 44c6c182a8acc8ef6379c5c5f5cd8ed6a574671b..1505912666f6abb7bb1bc98a85fa4236d08c1105 100644 --- a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_4/rewrite_bsc_generic_4.cbs +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_4/rewrite_bsc_generic_4.cbs @@ -19,20 +19,20 @@ int main() { test(bb); } - -// CHECK:struct Block +// CHECK: struct Block; +// CHECK-NEXT:struct Block // CHECK-NEXT: { // CHECK-NEXT: int a; -// CHECK-NEXT:}; +// CHECK-NEXT: }; // CHECK-EMPTY: -// CHECK-NEXT:static void test_struct_Block(struct Block a); +// CHECK-NEXT: static void test_struct_Block(struct Block a); // CHECK-EMPTY: -// CHECK-NEXT:int main(void) { -// CHECK-NEXT: int b1 = 2; -// CHECK-NEXT: struct Block bb; -// CHECK-NEXT: test_struct_Block(bb); -// CHECK-NEXT:} +// CHECK-NEXT: int main(void) { +// CHECK-NEXT: int b1 = 2; +// CHECK-NEXT: struct Block bb; +// CHECK-NEXT: test_struct_Block(bb); +// CHECK-NEXT: } // CHECK-EMPTY: -// CHECK-NEXT:static void test_struct_Block(struct Block a) { +// CHECK-NEXT: static void test_struct_Block(struct Block a) { // CHECK-NEXT: int c = 1; // CHECK-NEXT: } \ No newline at end of file diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_constant_suffix/rewrite_bsc_generic_constant_suffix.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_constant_suffix/rewrite_bsc_generic_constant_suffix.cbs index 1abbc6643f413d243acaacd78fb4d8d03e9a0156..7aeadab1c86e4e2fb44172ebea9edd2590c27510 100644 --- a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_constant_suffix/rewrite_bsc_generic_constant_suffix.cbs +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_constant_suffix/rewrite_bsc_generic_constant_suffix.cbs @@ -60,6 +60,7 @@ int main() { // CHECK: #include // CHECK-EMPTY: // CHECK-EMPTY: +// CHECK-NEXT: struct S_5; // CHECK-NEXT: typedef short MyShort; // CHECK-EMPTY: // CHECK-NEXT: struct S_5 { diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_struct_with_header/rewrite_bsc_generic_struct_with_header.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_struct_with_header/rewrite_bsc_generic_struct_with_header.cbs index feeb761d2e67b3fca197d05ee41571a14f1bd686..9ecb7682e0b4f9a0040e66714ba95bf625afedd1 100644 --- a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_struct_with_header/rewrite_bsc_generic_struct_with_header.cbs +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_struct_with_header/rewrite_bsc_generic_struct_with_header.cbs @@ -20,6 +20,9 @@ int main() { // CHECK: #include // CHECK-EMPTY: // CHECK-EMPTY: +// CHECK-NEXT: struct _BSC_ListNode_struct_S; +// CHECK-NEXT: struct LinkedList_struct_S; +// CHECK-NEXT: struct S; // CHECK-NEXT: struct S { // CHECK-NEXT: int a; // CHECK-NEXT: }; diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_2/rewrite_bsc_generic_with_header_2.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_2/rewrite_bsc_generic_with_header_2.cbs index 30c05d1a3182dad4dbe2c3cc97302c3cfad9dcde..bd5a9d760c7aad8c82a28d8cd45ef274b12e4a83 100644 --- a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_2/rewrite_bsc_generic_with_header_2.cbs +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_2/rewrite_bsc_generic_with_header_2.cbs @@ -30,6 +30,11 @@ int main() { // CHECK-NEXT: #include // CHECK-EMPTY: // CHECK-EMPTY: +// CHECK-NEXT: struct S_int_char; +// CHECK-NEXT: struct G_struct_S_int_char; +// CHECK-NEXT: struct G_int; +// CHECK-NEXT: struct A; +// CHECK-NEXT: struct B; // CHECK-NEXT: typedef int (*myFunc)(struct B *); // CHECK-EMPTY: // CHECK-NEXT: typedef struct A MyStruct; diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_3/rewrite_bsc_generic_with_header_3.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_3/rewrite_bsc_generic_with_header_3.cbs index 44f3b722f5ffb028d9e96831707b377786dad85c..b46d2e12d276dfccea36313c3f95725e17ac05e5 100644 --- a/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_3/rewrite_bsc_generic_with_header_3.cbs +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/Generic/rewrite_bsc_generic_with_header_3/rewrite_bsc_generic_with_header_3.cbs @@ -51,6 +51,10 @@ int main() { // CHECK-NEXT: #include // CHECK-EMPTY: // CHECK-EMPTY: +// CHECK-NEXT: struct BSCGenericStruct_int; +// CHECK-NEXT: struct UserHBSStruct; +// CHECK-NEXT: struct CBSGenericFieldStruct; +// CHECK-NEXT: struct CBSStruct; // CHECK-NEXT: enum UserHBSEnum { // CHECK-NEXT: UFIRST, // CHECK-NEXT: USECOND, diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/rewrite_bsc_type_dependency_4/rewrite_bsc_type_dependency_4.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/rewrite_bsc_type_dependency_4/rewrite_bsc_type_dependency_4.cbs new file mode 100644 index 0000000000000000000000000000000000000000..861571bade9e76af9a33411b1d68cf0eb9f4b33f --- /dev/null +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/rewrite_bsc_type_dependency_4/rewrite_bsc_type_dependency_4.cbs @@ -0,0 +1,56 @@ +// 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 + +trait F {}; +struct S {}; +struct S; +typedef trait F* (*pollFunc) (struct S s); + +typedef struct EQueueFunc { + pollFunc func; +} EQueueFunc; + +trait F* poll(struct S s) { + trait F *t; + return t; +} + +int main() { + EQueueFunc f = {.func = poll}; + struct S s; + f.func(s); + return 0; +} + +// CHECK: struct __Trait_F_Vtable_int; +// CHECK-NEXT: struct __Trait_F_int; +// CHECK-NEXT: struct S; +// CHECK-NEXT: struct EQueueFunc; +// CHECK-NEXT: typedef struct __Trait_F_int (*pollFunc)(struct S); +// CHECK-EMPTY: +// CHECK-NEXT: typedef struct EQueueFunc EQueueFunc; +// CHECK-EMPTY: +// CHECK-NEXT: struct S {}; +// CHECK-EMPTY: +// CHECK-NEXT: struct __Trait_F_int { +// CHECK-NEXT: void *data; +// CHECK-NEXT: struct __Trait_F_Vtable_int *vtable; +// CHECK-NEXT: }; +// CHECK-EMPTY: +// CHECK-NEXT: struct EQueueFunc { +// CHECK-NEXT: pollFunc func; +// CHECK-NEXT: }; +// CHECK-EMPTY: +// CHECK-NEXT: struct __Trait_F_int poll(struct S s) { +// CHECK-NEXT: struct __Trait_F_int t; +// CHECK-NEXT: return t; +// CHECK-NEXT: } +// CHECK-EMPTY: +// CHECK-NEXT: int main(void) { +// CHECK-NEXT: EQueueFunc f = {.func = poll}; +// CHECK-NEXT: struct S s; +// CHECK-NEXT: f.func(s); +// CHECK-NEXT: return 0; +// CHECK-NEXT: } \ No newline at end of file diff --git a/clang/test/BSC/Positive/Trait/r3/implicit_cast_trait/implicit_cast_trait.cbs b/clang/test/BSC/Positive/Trait/r3/implicit_cast_trait/implicit_cast_trait.cbs index 8f0eb1a1e4ff54ba97576e62dc67e362f0cb393b..192920d2665abf7209683ed4e7044e7057bbd1fa 100644 --- a/clang/test/BSC/Positive/Trait/r3/implicit_cast_trait/implicit_cast_trait.cbs +++ b/clang/test/BSC/Positive/Trait/r3/implicit_cast_trait/implicit_cast_trait.cbs @@ -32,6 +32,10 @@ int main() { // CHECK: #include // CHECK-EMPTY: // CHECK-EMPTY: +// CHECK-NEXT: struct __Trait_F_Vtable; +// CHECK-NEXT: struct __Trait_F; +// CHECK-NEXT: struct __Trait_F_Owned; +// CHECK-NEXT: struct __Trait_F_Borrow; // CHECK-NEXT: struct __Trait_F_Vtable { // CHECK-NEXT: int (*foo)(void *); // CHECK-NEXT: };