summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
authorJaved Absar <javed.absar@arm.com>2017-06-05 10:11:57 +0000
committerJaved Absar <javed.absar@arm.com>2017-06-05 10:11:57 +0000
commit7c78710146c10e25cd149914210013905d70d6d6 (patch)
tree68099d75a27c12fbc744658ed441e2e8abf1c591 /test/CodeGenCXX
parent6235d9b1ad493fbbd905e46b2b6afab52eeeb2cb (diff)
Add support for #pragma clang section
This patch provides a means to specify section-names for global variables, functions and static variables, using #pragma directives. This feature is only defined to work sensibly for ELF targets. One can specify section names as: #pragma clang section bss="myBSS" data="myData" rodata="myRodata" text="myText" One can "unspecify" a section name with empty string e.g. #pragma clang section bss="" data="" text="" rodata="" Reviewers: Roger Ferrer, Jonathan Roelofs, Reid Kleckner Differential Revision: https://reviews.llvm.org/D33412 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304705 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/clang-sections-tentative.c41
-rw-r--r--test/CodeGenCXX/clang-sections.cpp78
2 files changed, 119 insertions, 0 deletions
diff --git a/test/CodeGenCXX/clang-sections-tentative.c b/test/CodeGenCXX/clang-sections-tentative.c
new file mode 100644
index 0000000000..e663079b9a
--- /dev/null
+++ b/test/CodeGenCXX/clang-sections-tentative.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -x c -emit-llvm -triple arm-none-eabi -o - %s | FileCheck %s
+
+// Test that section attributes are attached to C tentative definitions as per
+// '#pragma clang section' directives.
+
+#pragma clang section bss = ".bss.1"
+int x; // bss.1
+
+#pragma clang section bss = ""
+int x; // stays in .bss.1
+int y; // not assigned a section attribute
+int z; // not assigned a section attribute
+
+#pragma clang section bss = ".bss.2"
+int x; // stays in .bss.1
+int y; // .bss.2
+
+// Test the same for `const` declarations.
+#pragma clang section rodata = ".rodata.1"
+const int cx; // rodata.1
+
+#pragma clang section rodata = ""
+const int cx; // stays in .rodata.1
+const int cy; // not assigned a section attribute
+const int cz; // not assigned a rodata section attribute
+
+#pragma clang section rodata = ".rodata.2"
+const int cx; // stays in .rodata.1
+const int cy; // .rodata.2
+
+// CHECK: @x = global i32 0, align 4 #0
+// CHECK: @y = global i32 0, align 4 #1
+// CHECK: @z = common global i32 0, align 4
+// CHECK: @cx = constant i32 0, align 4 #2
+// CHECK: @cy = constant i32 0, align 4 #3
+// CHECK: @cz = constant i32 0, align 4 #1
+
+// CHECK: attributes #0 = { "bss-section"=".bss.1" }
+// CHECK: attributes #1 = { "bss-section"=".bss.2" }
+// CHECK: attributes #2 = { "bss-section"=".bss.2" "rodata-section"=".rodata.1" }
+// CHECK: attributes #3 = { "bss-section"=".bss.2" "rodata-section"=".rodata.2" }
diff --git a/test/CodeGenCXX/clang-sections.cpp b/test/CodeGenCXX/clang-sections.cpp
new file mode 100644
index 0000000000..4fe42eaf77
--- /dev/null
+++ b/test/CodeGenCXX/clang-sections.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -emit-llvm -triple arm-none-eabi -o - %s | FileCheck %s
+// Test that global variables, statics and functions are attached section-attributes
+// as per '#pragma clang section' directives.
+
+extern "C" {
+// test with names for each section
+#pragma clang section bss="my_bss.1" data="my_data.1" rodata="my_rodata.1"
+#pragma clang section text="my_text.1"
+int a; // my_bss.1
+int b = 1; // my_data.1
+int c[4]; // my_bss.1
+short d[5] = {0}; // my_bss.1
+short e[6] = {0, 0, 1}; // my_data.1
+extern const int f;
+const int f = 2; // my_rodata.1
+int foo(void) { // my_text.1
+ return b;
+}
+static int g[2]; // my_bss.1
+#pragma clang section bss=""
+int h; // default - .bss
+#pragma clang section data="" bss="my_bss.2" text="my_text.2"
+int i = 0; // my_bss.2
+extern const int j;
+const int j = 4; // default - .rodata
+int k; // my_bss.2
+extern int zoo(int *x, int *y);
+int goo(void) { // my_text.2
+ static int lstat_h; // my_bss.2
+ return zoo(g, &lstat_h);
+}
+#pragma clang section rodata="my_rodata.2" data="my_data.2"
+int l = 5; // my_data.2
+extern const int m;
+const int m = 6; // my_rodata.2
+#pragma clang section rodata="" data="" bss="" text=""
+int n; // default
+int o = 6; // default
+extern const int p;
+const int p = 7; // default
+int hoo(void) {
+ return b;
+}
+}
+//CHECK: @a = global i32 0, align 4 #0
+//CHECK: @b = global i32 1, align 4 #0
+//CHECK: @c = global [4 x i32] zeroinitializer, align 4 #0
+//CHECK: @d = global [5 x i16] zeroinitializer, align 2 #0
+//CHECK: @e = global [6 x i16] [i16 0, i16 0, i16 1, i16 0, i16 0, i16 0], align 2 #0
+//CHECK: @f = constant i32 2, align 4 #0
+
+//CHECK: @h = global i32 0, align 4 #1
+//CHECK: @i = global i32 0, align 4 #2
+//CHECK: @j = constant i32 4, align 4 #2
+//CHECK: @k = global i32 0, align 4 #2
+//CHECK: @_ZZ3gooE7lstat_h = internal global i32 0, align 4 #2
+//CHECK: @_ZL1g = internal global [2 x i32] zeroinitializer, align 4 #0
+
+//CHECK: @l = global i32 5, align 4 #3
+//CHECK: @m = constant i32 6, align 4 #3
+
+//CHECK: @n = global i32 0, align 4
+//CHECK: @o = global i32 6, align 4
+//CHECK: @p = constant i32 7, align 4
+
+//CHECK: define i32 @foo() #4 {
+//CHECK: define i32 @goo() #5 {
+//CHECK: declare i32 @zoo(i32*, i32*) #6
+//CHECK: define i32 @hoo() #7 {
+
+//CHECK: attributes #0 = { "bss-section"="my_bss.1" "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+//CHECK: attributes #1 = { "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+//CHECK: attributes #2 = { "bss-section"="my_bss.2" "rodata-section"="my_rodata.1" }
+//CHECK: attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "rodata-section"="my_rodata.2" }
+//CHECK: attributes #4 = { {{.*"implicit-section-name"="my_text.1".*}} }
+//CHECK: attributes #5 = { {{.*"implicit-section-name"="my_text.2".*}} }
+//CHECK-NOT: attributes #6 = { {{.*"implicit-section-name".*}} }
+//CHECK-NOT: attributes #7 = { {{.*"implicit-section-name".*}} }