diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index c7cd98eebf8739beb0f6cdbd39cb1ea9d2c28040..533074ec34bcc7027814eb67d9ffc6e5681c0978 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -674,9 +674,12 @@ void DeclPrinter::VisitRecordDecl(RecordDecl *D) { Out << ' ' << *D; #if ENABLE_BSC // Handling anonymous struct/union defined through typedef for rewriting - else if (Context.getLangOpts().BSC) { + else if (Policy.RewriteBSC) { if (TypedefNameDecl *TND = D->getTypedefNameForAnonDecl()) Out << ' ' << "_TD_" << TND->getName(); + else if (!D->isAnonymousStructOrUnion()) { + Out << ' ' << "__unnamed_" << D->getID(); + } } #endif diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 1319623c653120031c9b57e9e688dc3fd9fbac93..fc5e9bfdf5bab8b73cda3a21a39a837d1d14a97f 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1450,6 +1450,13 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { assert(Typedef->getIdentifier() && "Typedef without identifier?"); OS << Typedef->getIdentifier()->getName(); } else { +#if ENABLE_BSC + if (Policy.RewriteBSC) { + OS << "__unnamed_" << D->getID(); + spaceBeforePlaceHolder(OS); + return; + } +#endif // Make an unambiguous representation for anonymous types, e.g. // (anonymous enum at /usr/include/string.h:120:9) OS << (Policy.MSVCFormatting ? '`' : '('); diff --git a/clang/lib/Frontend/Rewrite/RewriteBSC.cpp b/clang/lib/Frontend/Rewrite/RewriteBSC.cpp index 38ee46fa29b8f1a5bcb0952af116bcbb3fd16b48..6ef36d3118218c0a64b99332089e7506e68a8e50 100644 --- a/clang/lib/Frontend/Rewrite/RewriteBSC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteBSC.cpp @@ -35,9 +35,7 @@ public: } // recording appear index - void addNode(RecordDecl *RD) { - nodes.insert({RD, nodes.size()}); - } + void addNode(RecordDecl *RD) { nodes.insert({RD, nodes.size()}); } std::vector topologicalSort() { std::map inDegree; @@ -92,7 +90,7 @@ private: // use T as the key and add S to its value. std::map> typeDependencyMap; // map to memo the appear index - std::map nodes; + std::map nodes; }; class TypeDependencyVisitor : public DeclVisitor { @@ -591,14 +589,15 @@ void RewriteBSC::RewriteDecls() { Buf << ";\n\n"; } else { if (TagDecl *TD = dyn_cast(D)) { - // For an anonymous tagdecl with typedef, use pretty printer. Otherwise, - // use original string text. - if (!TD->getTypedefNameForAnonDecl()) { + // For an anonymous tagdecl with typedef or unnamed recorddecl, use + // pretty printer. Otherwise, use original string text. + if (TD->getTypedefNameForAnonDecl() || + (!TD->getIdentifier() && isa(TD))) { + D->print(Buf, Policy); + } else { const char *startBuf = SM->getCharacterData(D->getBeginLoc()); const char *endBuf = SM->getCharacterData(D->getEndLoc()); Buf << std::string(startBuf, endBuf - startBuf + 1); - } else { - D->print(Buf, Policy); } Buf << ";\n\n"; } else { @@ -821,11 +820,6 @@ void RewriteBSC::RewriteNonGenericFuncAndVar(std::vector &DeclList) { if (FD->isAsyncSpecified()) break; if (!FD->isTemplateInstantiation()) { - if (!SM->isWrittenInMainFile(SM->getSpellingLoc(FD->getBeginLoc())) && - !SM->isWrittenInMainFile(SM->getSpellingLoc(FD->getEndLoc())) && - FD->getStorageClass() == StorageClass::SC_Extern) - break; - // If it is BscMethod or macro expansion function, output the code // according to AST; Otherwise, simply retrieve the source code if (DeclsWithoutBSCFeature.find(FD) == DeclsWithoutBSCFeature.end() || diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern.cbs new file mode 100644 index 0000000000000000000000000000000000000000..f39fc37168562d994fec43123cab8b99e5d8d975 --- /dev/null +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern.cbs @@ -0,0 +1,5 @@ +#include "extern_func_decl_in_header.hbs" + +int Entryf1(struct S **p) { + return 0; +} \ No newline at end of file diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern_func_decl_in_header.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern_func_decl_in_header.cbs new file mode 100644 index 0000000000000000000000000000000000000000..929fd8863a63bdf461bfb4c0fbfa3ceb536a4033 --- /dev/null +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern_func_decl_in_header.cbs @@ -0,0 +1,34 @@ +// RUN: %clang %s %S/extern.cbs -o %t.output +// RUN: %t.output +// RUN: %clang -rewrite-bsc %s -o %t-rw1.c +// RUN: %clang -rewrite-bsc %S/extern.cbs -o %t-rw2.c +// RUN: FileCheck --input-file=%t-rw1.c %s +// RUN: %clang %t-rw1.c %t-rw2.c -o %t-rw.output +// RUN: %t-rw.output + +#include "extern_func_decl_in_header.hbs" + +Foo(f1) + +Ptr table = { Entryf1 }; + +int main(void) { + return 0; +} + +// CHECK: #define Foo(Name) extern int Entry##Name(struct S **p); + +// CHECK: struct S; +// CHECK-NEXT: typedef int (*Ptr)(struct S **); + +// CHECK: struct S { +// CHECK-NEXT: int x; +// CHECK-NEXT: }; + +// CHECK: extern int Entryf1(struct S **p); + +// CHECK: Ptr table = {Entryf1}; + +// CHECK: int main(void) { +// CHECK-NEXT: return 0; +// CHECK-NEXT: } \ No newline at end of file diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern_func_decl_in_header.hbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern_func_decl_in_header.hbs new file mode 100644 index 0000000000000000000000000000000000000000..828c110217fc787a153dd20410dc53d799710cf5 --- /dev/null +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/extern_func_decl_in_header.hbs @@ -0,0 +1,12 @@ +#ifndef HEADER_H +#define HEADER_H + +struct S { + int x; +}; + +typedef int (*Ptr)(struct S **p); + +#define Foo(Name) extern int Entry##Name(struct S **p); + +#endif diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/lit.local.cfg b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/lit.local.cfg new file mode 100644 index 0000000000000000000000000000000000000000..1a5b1b56de8dd53fe4404a4e4973ab34dadec2a3 --- /dev/null +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/extern_func_decl_in_header/lit.local.cfg @@ -0,0 +1,4 @@ +import os +import lit.formats + +config.excludes = ['extern.cbs'] \ No newline at end of file diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/unnamed_struct_or_union/unnamed_struct_or_union.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/unnamed_struct_or_union/unnamed_struct_or_union.cbs new file mode 100644 index 0000000000000000000000000000000000000000..4b198228250d0de99dea3ad88599d7d2d308866c --- /dev/null +++ b/clang/test/BSC/Positive/Driver/rewrite-bsc/unnamed_struct_or_union/unnamed_struct_or_union.cbs @@ -0,0 +1,51 @@ +// 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 { + int a; +} s = { 2 }; + +static struct { + int b; +} p = { 3 }; + +union { + char c; + int a; +} q; + +int main() { + q.a = 4; + return q.a + 1 - s.a - p.b; +} + +// CHECK: struct __unnamed_{{[0-9]+}}; +// CHECK-NEXT: struct __unnamed_{{[0-9]+}}; +// CHECK-NEXT: union __unnamed_{{[0-9]+}}; +// CHECK-NEXT: struct __unnamed_{{[0-9]+}} { +// CHECK-NEXT: int a; +// CHECK-NEXT: }; + +// CHECK: struct __unnamed_{{[0-9]+}} { +// CHECK-NEXT: int b; +// CHECK-NEXT: }; + +// CHECK: union __unnamed_{{[0-9]+}} { +// CHECK-NEXT: char c; +// CHECK-NEXT: int a; +// CHECK-NEXT: }; + +// CHECK: struct __unnamed_{{[0-9]+}} s = {2}; + +// CHECK: static struct __unnamed_{{[0-9]+}} p = {3}; + +// CHECK: union __unnamed_{{[0-9]+}} q; + +// CHECK: int main() { +// CHECK-NEXT: q.a = 4; +// CHECK-NEXT: return q.a + 1 - s.a - p.b; +// CHECK-NEXT: } \ No newline at end of file