Skip to content

Commit 7d09df7

Browse files
andrurogerzcompnerd
authored andcommitted
reposition export annotation on extern variable declarations and declarations with existing attributes
1 parent d733d4e commit 7d09df7

File tree

6 files changed

+129
-17
lines changed

6 files changed

+129
-17
lines changed

Sources/idt/idt.cc

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,17 @@ class visitor : public clang::RecursiveASTVisitor<visitor> {
343343
if (contains(get_ignored_symbols(), FD->getNameAsString()))
344344
return;
345345

346-
clang::SourceLocation SLoc =
347-
FD->getTemplatedKind() == clang::FunctionDecl::TK_NonTemplate
348-
? FD->getBeginLoc()
349-
: FD->getInnerLocStart();
350-
unexported_public_interface(FD)
346+
// Use the inner start location so that the annotation comes after
347+
// any template information.
348+
clang::SourceLocation SLoc = FD->getInnerLocStart();
349+
350+
// If the function declaration has any existing attributes, the export macro
351+
// should be inserted after them. We can approximate this location using the
352+
// function's return type location.
353+
if (!FD->attrs().empty())
354+
SLoc = FD->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
355+
356+
unexported_public_interface(FD, SLoc)
351357
<< FD << clang::FixItHint::CreateInsertion(SLoc, export_macro + " ");
352358
}
353359

@@ -399,7 +405,15 @@ class visitor : public clang::RecursiveASTVisitor<visitor> {
399405
return;
400406

401407
clang::SourceLocation SLoc = VD->getBeginLoc();
402-
unexported_public_interface(VD)
408+
409+
// If the variable declaration has any existing attributes, the export macro
410+
// should be inserted after them. Similarly, if the variable has external
411+
// storage, the export macro should be inserted after the extern keyword. We
412+
// can approximate this location using the variable's type location.
413+
if (!VD->attrs().empty() || VD->hasExternalStorage())
414+
SLoc = VD->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
415+
416+
unexported_public_interface(VD, SLoc)
403417
<< VD << clang::FixItHint::CreateInsertion(SLoc, export_macro + " ");
404418
}
405419

Tests/Functions.hh

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// RUN: %idt -export-macro IDT_TEST_ABI %s 2>&1 | %FileCheck %s
2+
3+
// CHECK: Functions.hh:[[@LINE+1]]:78: remark: unexported public interface 'function_1'
4+
__attribute__((always_inline)) [[deprecated("this function is deprecated")]] int function_1(int);
5+
6+
// CHECK: Functions.hh:[[@LINE+1]]:59: remark: unexported public interface 'function_2'
7+
__attribute__((deprecated("this function is deprecated")))int function_2(int);
8+
9+
// CHECK: Functions.hh:[[@LINE+1]]:55: remark: unexported public interface 'function_3'
10+
[[nodiscard]] __attribute__((noinline)) /* comment */ int function_3(int);
11+
12+
// CHECK: Functions.hh:[[@LINE+1]]:73: remark: unexported public interface 'function_4'
13+
__attribute__((noinline)) [[deprecated("this function is deprecated")]] int function_4(int);
14+
15+
// CHECK: Functions.hh:[[@LINE+2]]:15: remark: unexported public interface 'function_5'
16+
[[nodiscard]] __attribute__((deprecated("this function is deprecated")))
17+
/* comment */ int function_5(int);
18+
19+
// CHECK: Functions.hh:[[@LINE+2]]:1: remark: unexported public interface 'function_6'
20+
[[nodiscard]]
21+
int function_6(int);
22+
23+
// CHECK: Functions.hh:[[@LINE+3]]:1: remark: unexported public interface 'function_7'
24+
[[nodiscard]] [[deprecated("this function is deprecated")]] /* two line
25+
comment */
26+
int function_7(int);
27+
28+
// CHECK: Functions.hh:[[@LINE+2]]:15: remark: unexported public interface 'function_8'
29+
[[nodiscard]] // this is a comment
30+
/* comment */ int function_8(int);
31+
32+
// CHECK: Functions.hh:[[@LINE+2]]:58: remark: unexported public interface 'function_9'
33+
[[nodiscard]] // this is a comment
34+
__attribute((deprecated("this function is deprecated"))) int function_9(int);
35+
36+
// CHECK: Functions.hh:[[@LINE+1]]:21: remark: unexported public interface 'function_10'
37+
[[nodiscard]] const void *function_10(int);
38+
39+
struct Class {
40+
// CHECK: Functions.hh:[[@LINE+1]]:49: remark: unexported public interface 'method_1'
41+
[[deprecated("this function is deprecated")]] int method_1(int);
42+
43+
// CHECK: Functions.hh:[[@LINE+1]]:48: remark: unexported public interface 'method_2'
44+
[[deprecated("this function is deprecated")]]int method_2(int);
45+
46+
// CHECK: Functions.hh:[[@LINE+1]]:31: remark: unexported public interface 'method_3'
47+
[[nodiscard]] /* comment */ int method_3(int);
48+
49+
// CHECK: Functions.hh:[[@LINE+2]]:17: remark: unexported public interface 'method_4'
50+
[[nodiscard]]
51+
/* comment */ int method_4(int);
52+
53+
// CHECK: Functions.hh:[[@LINE+2]]:3: remark: unexported public interface 'method_5'
54+
[[nodiscard]]
55+
int method_5(int);
56+
57+
// CHECK: Functions.hh:[[@LINE+3]]:3: remark: unexported public interface 'method_6'
58+
[[nodiscard]] /* two line
59+
comment */
60+
int method_6(int);
61+
62+
// CHECK: Functions.hh:[[@LINE+2]]:3: remark: unexported public interface 'method_7'
63+
[[nodiscard]] // this is a comment
64+
int method_7(int);
65+
66+
// CHECK: Functions.hh:[[@LINE+2]]:49: remark: unexported public interface 'method_8'
67+
[[nodiscard]] // this is a comment
68+
[[deprecated("this function is deprecated")]] int method_8(int);
69+
};

Tests/MissingInclude.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ void function();
1616
// CHECK-NO-INCLUDE: MissingInclude.hh:[[@LINE-2]]:1: remark: unexported public interface 'function'
1717

1818
extern int variable;
19-
// CHECK-ADD-INCLUDE: MissingInclude.hh:[[@LINE-1]]:1: remark: unexported public interface 'variable'
20-
// CHECK-NO-INCLUDE: MissingInclude.hh:[[@LINE-2]]:1: remark: unexported public interface 'variable'
19+
// CHECK-ADD-INCLUDE: MissingInclude.hh:[[@LINE-1]]:8: remark: unexported public interface 'variable'
20+
// CHECK-NO-INCLUDE: MissingInclude.hh:[[@LINE-2]]:8: remark: unexported public interface 'variable'

Tests/MultipleFiles.hh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
// CHECK: Variables.hh:11:3: remark: unexported public interface 'public_static_const_class_field'
55
// CHECK: Variables.hh:29:3: remark: unexported public interface 'public_static_struct_field'
66
// CHECK: Variables.hh:32:3: remark: unexported public interface 'public_static_const_struct_field'
7-
// CHECK: Variables.hh:46:1: remark: unexported public interface 'extern_variable'
8-
// CHECK: Variables.hh:49:1: remark: unexported public interface 'extern_const_variable'
9-
// CHECK: Variables.hh:52:1: remark: unexported public interface 'ignored_extern_variable'
10-
// CHECK: Variables.hh:59:3: remark: unexported public interface 'extern_local_variable'
11-
// CHECK: TemplateFunctions.hh:10:1: remark: unexported public interface 'template_function_inline<char>'
7+
// CHECK: Variables.hh:46:8: remark: unexported public interface 'extern_variable'
8+
// CHECK: Variables.hh:49:14: remark: unexported public interface 'extern_const_variable'
9+
// CHECK: Variables.hh:52:14: remark: unexported public interface 'const_extern_variable'
10+
// CHECK: Variables.hh:55:8: remark: unexported public interface 'ignored_extern_variable'
11+
// CHECK: Variables.hh:62:10: remark: unexported public interface 'extern_local_variable'
12+
// CHECK: TemplateFunctions.hh:10:13: remark: unexported public interface 'template_function_inline<char>'

Tests/TemplateFunctions.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ template <> void template_function_inline<int>(int &) { }
88
// CHECK-NOT: TemplateFunctions.hh:[[@LINE-1]]:1: remark: unexported public interface 'template_function_inline<int>'
99

1010
template <> void template_function_inline<char>(char &);
11-
// CHECK: TemplateFunctions.hh:[[@LINE-1]]:1: remark: unexported public interface 'template_function_inline<char>'
11+
// CHECK: TemplateFunctions.hh:[[@LINE-1]]:13: remark: unexported public interface 'template_function_inline<char>'
1212
// CHECK-FIXIT: template <> IDT_TEST_ABI void template_function_inline<char>(char &);

Tests/Variables.hh

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ private:
4444
};
4545

4646
extern int extern_variable;
47-
// CHECK: Variables.hh:[[@LINE-1]]:1: remark: unexported public interface 'extern_variable'
47+
// CHECK: Variables.hh:[[@LINE-1]]:8: remark: unexported public interface 'extern_variable'
4848

4949
extern const int extern_const_variable;
50-
// CHECK: Variables.hh:[[@LINE-1]]:1: remark: unexported public interface 'extern_const_variable'
50+
// CHECK: Variables.hh:[[@LINE-1]]:14: remark: unexported public interface 'extern_const_variable'
51+
52+
const extern int const_extern_variable;
53+
// CHECK: Variables.hh:[[@LINE-1]]:14: remark: unexported public interface 'const_extern_variable'
5154

5255
extern int ignored_extern_variable;
5356
// CHECK-NOT: Variables.hh:[[@LINE-1]]:{{.*}}
@@ -57,8 +60,33 @@ int global_variable;
5760

5861
void function() {
5962
extern int extern_local_variable;
60-
// CHECK: Variables.hh:[[@LINE-1]]:3: remark: unexported public interface 'extern_local_variable'
63+
// CHECK: Variables.hh:[[@LINE-1]]:10: remark: unexported public interface 'extern_local_variable'
6164

6265
int local_variable;
6366
// CHECK-NOT: Variables.hh:[[@LINE-1]]:{{.*}}
6467
}
68+
69+
extern StructWithFields* extern_struct_pointer;
70+
// CHECK:Variables.hh:[[@LINE-1]]:8: remark: unexported public interface 'extern_struct_pointer'
71+
72+
extern const StructWithFields* extern_immutable_struct_pointer;
73+
// CHECK:Variables.hh:[[@LINE-1]]:14: remark: unexported public interface 'extern_immutable_struct_pointer'
74+
75+
[[deprecated("do not use")]]extern int extern_cpp_deprecated_int;
76+
// CHECK:Variables.hh:[[@LINE-1]]:36: remark: unexported public interface 'extern_cpp_deprecated_int'
77+
78+
__attribute((deprecated("do not use"))) extern int extern_deprecated_int;
79+
// CHECK:Variables.hh:[[@LINE-1]]:48: remark: unexported public interface 'extern_deprecated_int'
80+
81+
__attribute((deprecated("do not use")))extern
82+
int extern_deprecated_int_2_line;
83+
// CHECK:Variables.hh:[[@LINE-1]]:1: remark: unexported public interface 'extern_deprecated_int_2_line'
84+
85+
[[deprecated("do not use")]] /* comment */extern int extern_cpp_deprecated_int_comment;
86+
// CHECK:Variables.hh:[[@LINE-1]]:50: remark: unexported public interface 'extern_cpp_deprecated_int_comment'
87+
88+
extern volatile unsigned long *extern_volatile_unsigned_long_ptr;
89+
// CHECK:Variables.hh:[[@LINE-1]]:17: remark: unexported public interface 'extern_volatile_unsigned_long_ptr'
90+
91+
extern unsigned long extern_unsigned_long_aligned [[gnu::aligned(16)]];
92+
// CHECK:Variables.hh:[[@LINE-1]]:8: remark: unexported public interface 'extern_unsigned_long_aligned'

0 commit comments

Comments
 (0)