/
AttrDocs.td
4060 lines (3300 loc) · 163 KB
/
AttrDocs.td
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//==--- AttrDocs.td - Attribute documentation ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
// To test that the documentation builds cleanly, you must run clang-tblgen to
// convert the .td file into a .rst file, and then run sphinx to convert the
// .rst file into an HTML file. After completing testing, you should revert the
// generated .rst file so that the modified version does not get checked in to
// version control.
//
// To run clang-tblgen to generate the .rst file:
// clang-tblgen -gen-attr-docs -I <root>/llvm/tools/clang/include
// <root>/llvm/tools/clang/include/clang/Basic/Attr.td -o
// <root>/llvm/tools/clang/docs/AttributeReference.rst
//
// To run sphinx to generate the .html files (note that sphinx-build must be
// available on the PATH):
// Windows (from within the clang\docs directory):
// make.bat html
// Non-Windows (from within the clang\docs directory):
// make -f Makefile.sphinx html
def GlobalDocumentation {
code Intro =[{..
-------------------------------------------------------------------
NOTE: This file is automatically generated by running clang-tblgen
-gen-attr-docs. Do not edit this file by hand!!
-------------------------------------------------------------------
===================
Attributes in Clang
===================
.. contents::
:local:
.. |br| raw:: html
<br/>
Introduction
============
This page lists the attributes currently supported by Clang.
}];
}
def SectionDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``section`` attribute allows you to specify a specific section a
global variable or function should be in after translation.
}];
let Heading = "section, __declspec(allocate)";
}
def InitSegDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The attribute applied by ``pragma init_seg()`` controls the section into
which global initialization function pointers are emitted. It is only
available with ``-fms-extensions``. Typically, this function pointer is
emitted into ``.CRT$XCU`` on Windows. The user can change the order of
initialization by using a different section name with the same
``.CRT$XC`` prefix and a suffix that sorts lexicographically before or
after the standard ``.CRT$XCU`` sections. See the init_seg_
documentation on MSDN for more information.
.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx
}];
}
def TLSModelDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``tls_model`` attribute allows you to specify which thread-local storage
model to use. It accepts the following strings:
* global-dynamic
* local-dynamic
* initial-exec
* local-exec
TLS models are mutually exclusive.
}];
}
def DLLExportDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``__declspec(dllexport)`` attribute declares a variable, function, or
Objective-C interface to be exported from the module. It is available under the
``-fdeclspec`` flag for compatibility with various compilers. The primary use
is for COFF object files which explicitly specify what interfaces are available
for external use. See the dllexport_ documentation on MSDN for more
information.
.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
}];
}
def DLLImportDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``__declspec(dllimport)`` attribute declares a variable, function, or
Objective-C interface to be imported from an external module. It is available
under the ``-fdeclspec`` flag for compatibility with various compilers. The
primary use is for COFF object files which explicitly specify what interfaces
are imported from external modules. See the dllimport_ documentation on MSDN
for more information.
.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
}];
}
def ThreadDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``__declspec(thread)`` attribute declares a variable with thread local
storage. It is available under the ``-fms-extensions`` flag for MSVC
compatibility. See the documentation for `__declspec(thread)`_ on MSDN.
.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
GNU ``__thread`` keyword. The variable must not have a destructor and must have
a constant initializer, if any. The attribute only applies to variables
declared with static storage duration, such as globals, class static data
members, and static locals.
}];
}
def NoEscapeDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
``noescape`` placed on a function parameter of a pointer type is used to inform
the compiler that the pointer cannot escape: that is, no reference to the object
the pointer points to that is derived from the parameter value will survive
after the function returns. Users are responsible for making sure parameters
annotated with ``noescape`` do not actuallly escape.
For example:
.. code-block:: c
int *gp;
void nonescapingFunc(__attribute__((noescape)) int *p) {
*p += 100; // OK.
}
void escapingFunc(__attribute__((noescape)) int *p) {
gp = p; // Not OK.
}
Additionally, when the parameter is a `block pointer
<https://clang.llvm.org/docs/BlockLanguageSpec.html>`, the same restriction
applies to copies of the block. For example:
.. code-block:: c
typedef void (^BlockTy)();
BlockTy g0, g1;
void nonescapingFunc(__attribute__((noescape)) BlockTy block) {
block(); // OK.
}
void escapingFunc(__attribute__((noescape)) BlockTy block) {
g0 = block; // Not OK.
g1 = Block_copy(block); // Not OK either.
}
}];
}
def CarriesDependencyDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``carries_dependency`` attribute specifies dependency propagation into and
out of functions.
When specified on a function or Objective-C method, the ``carries_dependency``
attribute means that the return value carries a dependency out of the function,
so that the implementation need not constrain ordering upon return from that
function. Implementations of the function and its caller may choose to preserve
dependencies instead of emitting memory ordering instructions such as fences.
Note, this attribute does not change the meaning of the program, but may result
in generation of more efficient code.
}];
}
def CPUSpecificCPUDispatchDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``cpu_specific`` and ``cpu_dispatch`` attributes are used to define and
resolve multiversioned functions. This form of multiversioning provides a
mechanism for declaring versions across translation units and manually
specifying the resolved function list. A specified CPU defines a set of minimum
features that are required for the function to be called. The result of this is
that future processors execute the most restrictive version of the function the
new processor can execute.
Function versions are defined with ``cpu_specific``, which takes one or more CPU
names as a parameter. For example:
.. code-block:: c
// Declares and defines the ivybridge version of single_cpu.
__attribute__((cpu_specific(ivybridge)))
void single_cpu(void){}
// Declares and defines the atom version of single_cpu.
__attribute__((cpu_specific(atom)))
void single_cpu(void){}
// Declares and defines both the ivybridge and atom version of multi_cpu.
__attribute__((cpu_specific(ivybridge, atom)))
void multi_cpu(void){}
A dispatching (or resolving) function can be declared anywhere in a project's
source code with ``cpu_dispatch``. This attribute takes one or more CPU names
as a parameter (like ``cpu_specific``). Functions marked with ``cpu_dispatch``
are not expected to be defined, only declared. If such a marked function has a
definition, any side effects of the function are ignored; trivial function
bodies are permissible for ICC compatibility.
.. code-block:: c
// Creates a resolver for single_cpu above.
__attribute__((cpu_dispatch(ivybridge, atom)))
void single_cpu(void){}
// Creates a resolver for multi_cpu, but adds a 3rd version defined in another
// translation unit.
__attribute__((cpu_dispatch(ivybridge, atom, sandybridge)))
void multi_cpu(void){}
Note that it is possible to have a resolving function that dispatches based on
more or fewer options than are present in the program. Specifying fewer will
result in the omitted options not being considered during resolution. Specifying
a version for resolution that isn't defined in the program will result in a
linking failure.
It is also possible to specify a CPU name of ``generic`` which will be resolved
if the executing processor doesn't satisfy the features required in the CPU
name. The behavior of a program executing on a processor that doesn't satisfy
any option of a multiversioned function is undefined.
}];
}
def C11NoReturnDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
A function declared as ``_Noreturn`` shall not return to its caller. The
compiler will generate a diagnostic for a function declared as ``_Noreturn``
that appears to be capable of returning to its caller.
}];
}
def CXX11NoReturnDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
A function declared as ``[[noreturn]]`` shall not return to its caller. The
compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
that appears to be capable of returning to its caller.
}];
}
def AssertCapabilityDocs : Documentation {
let Category = DocCatFunction;
let Heading = "assert_capability, assert_shared_capability";
let Content = [{
Marks a function that dynamically tests whether a capability is held, and halts
the program if it is not held.
}];
}
def AcquireCapabilityDocs : Documentation {
let Category = DocCatFunction;
let Heading = "acquire_capability, acquire_shared_capability";
let Content = [{
Marks a function as acquiring a capability.
}];
}
def TryAcquireCapabilityDocs : Documentation {
let Category = DocCatFunction;
let Heading = "try_acquire_capability, try_acquire_shared_capability";
let Content = [{
Marks a function that attempts to acquire a capability. This function may fail to
actually acquire the capability; they accept a Boolean value determining
whether acquiring the capability means success (true), or failing to acquire
the capability means success (false).
}];
}
def ReleaseCapabilityDocs : Documentation {
let Category = DocCatFunction;
let Heading = "release_capability, release_shared_capability";
let Content = [{
Marks a function as releasing a capability.
}];
}
def AssumeAlignedDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Use ``__attribute__((assume_aligned(<alignment>[,<offset>]))`` on a function
declaration to specify that the return value of the function (which must be a
pointer type) has the specified offset, in bytes, from an address with the
specified alignment. The offset is taken to be zero if omitted.
.. code-block:: c++
// The returned pointer value has 32-byte alignment.
void *a() __attribute__((assume_aligned (32)));
// The returned pointer value is 4 bytes greater than an address having
// 32-byte alignment.
void *b() __attribute__((assume_aligned (32, 4)));
Note that this attribute provides information to the compiler regarding a
condition that the code already ensures is true. It does not cause the compiler
to enforce the provided alignment assumption.
}];
}
def AllocSizeDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``alloc_size`` attribute can be placed on functions that return pointers in
order to hint to the compiler how many bytes of memory will be available at the
returned pointer. ``alloc_size`` takes one or two arguments.
- ``alloc_size(N)`` implies that argument number N equals the number of
available bytes at the returned pointer.
- ``alloc_size(N, M)`` implies that the product of argument number N and
argument number M equals the number of available bytes at the returned
pointer.
Argument numbers are 1-based.
An example of how to use ``alloc_size``
.. code-block:: c
void *my_malloc(int a) __attribute__((alloc_size(1)));
void *my_calloc(int a, int b) __attribute__((alloc_size(1, 2)));
int main() {
void *const p = my_malloc(100);
assert(__builtin_object_size(p, 0) == 100);
void *const a = my_calloc(20, 5);
assert(__builtin_object_size(a, 0) == 100);
}
.. Note:: This attribute works differently in clang than it does in GCC.
Specifically, clang will only trace ``const`` pointers (as above); we give up
on pointers that are not marked as ``const``. In the vast majority of cases,
this is unimportant, because LLVM has support for the ``alloc_size``
attribute. However, this may cause mildly unintuitive behavior when used with
other attributes, such as ``enable_if``.
}];
}
def CodeSegDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``__declspec(code_seg)`` attribute enables the placement of code into separate
named segments that can be paged or locked in memory individually. This attribute
is used to control the placement of instantiated templates and compiler-generated
code. See the documentation for `__declspec(code_seg)`_ on MSDN.
.. _`__declspec(code_seg)`: http://msdn.microsoft.com/en-us/library/dn636922.aspx
}];
}
def AllocAlignDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Use ``__attribute__((alloc_align(<alignment>))`` on a function
declaration to specify that the return value of the function (which must be a
pointer type) is at least as aligned as the value of the indicated parameter. The
parameter is given by its index in the list of formal parameters; the first
parameter has index 1 unless the function is a C++ non-static member function,
in which case the first parameter has index 2 to account for the implicit ``this``
parameter.
.. code-block:: c++
// The returned pointer has the alignment specified by the first parameter.
void *a(size_t align) __attribute__((alloc_align(1)));
// The returned pointer has the alignment specified by the second parameter.
void *b(void *v, size_t align) __attribute__((alloc_align(2)));
// The returned pointer has the alignment specified by the second visible
// parameter, however it must be adjusted for the implicit 'this' parameter.
void *Foo::b(void *v, size_t align) __attribute__((alloc_align(3)));
Note that this attribute merely informs the compiler that a function always
returns a sufficiently aligned pointer. It does not cause the compiler to
emit code to enforce that alignment. The behavior is undefined if the returned
poitner is not sufficiently aligned.
}];
}
def EnableIfDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
.. Note:: Some features of this attribute are experimental. The meaning of
multiple enable_if attributes on a single declaration is subject to change in
a future version of clang. Also, the ABI is not standardized and the name
mangling may change in future versions. To avoid that, use asm labels.
The ``enable_if`` attribute can be placed on function declarations to control
which overload is selected based on the values of the function's arguments.
When combined with the ``overloadable`` attribute, this feature is also
available in C.
.. code-block:: c++
int isdigit(int c);
int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
void foo(char c) {
isdigit(c);
isdigit(10);
isdigit(-10); // results in a compile-time error.
}
The enable_if attribute takes two arguments, the first is an expression written
in terms of the function parameters, the second is a string explaining why this
overload candidate could not be selected to be displayed in diagnostics. The
expression is part of the function signature for the purposes of determining
whether it is a redeclaration (following the rules used when determining
whether a C++ template specialization is ODR-equivalent), but is not part of
the type.
The enable_if expression is evaluated as if it were the body of a
bool-returning constexpr function declared with the arguments of the function
it is being applied to, then called with the parameters at the call site. If the
result is false or could not be determined through constant expression
evaluation, then this overload will not be chosen and the provided string may
be used in a diagnostic if the compile fails as a result.
Because the enable_if expression is an unevaluated context, there are no global
state changes, nor the ability to pass information from the enable_if
expression to the function body. For example, suppose we want calls to
strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
strbuf) only if the size of strbuf can be determined:
.. code-block:: c++
__attribute__((always_inline))
static inline size_t strnlen(const char *s, size_t maxlen)
__attribute__((overloadable))
__attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
"chosen when the buffer size is known but 'maxlen' is not")))
{
return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
}
Multiple enable_if attributes may be applied to a single declaration. In this
case, the enable_if expressions are evaluated from left to right in the
following manner. First, the candidates whose enable_if expressions evaluate to
false or cannot be evaluated are discarded. If the remaining candidates do not
share ODR-equivalent enable_if expressions, the overload resolution is
ambiguous. Otherwise, enable_if overload resolution continues with the next
enable_if attribute on the candidates that have not been discarded and have
remaining enable_if attributes. In this way, we pick the most specific
overload out of a number of viable overloads using enable_if.
.. code-block:: c++
void f() __attribute__((enable_if(true, ""))); // #1
void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2
void g(int i, int j) __attribute__((enable_if(i, ""))); // #1
void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2
In this example, a call to f() is always resolved to #2, as the first enable_if
expression is ODR-equivalent for both declarations, but #1 does not have another
enable_if expression to continue evaluating, so the next round of evaluation has
only a single candidate. In a call to g(1, 1), the call is ambiguous even though
#2 has more enable_if attributes, because the first enable_if expressions are
not ODR-equivalent.
Query for this feature with ``__has_attribute(enable_if)``.
Note that functions with one or more ``enable_if`` attributes may not have
their address taken, unless all of the conditions specified by said
``enable_if`` are constants that evaluate to ``true``. For example:
.. code-block:: c
const int TrueConstant = 1;
const int FalseConstant = 0;
int f(int a) __attribute__((enable_if(a > 0, "")));
int g(int a) __attribute__((enable_if(a == 0 || a != 0, "")));
int h(int a) __attribute__((enable_if(1, "")));
int i(int a) __attribute__((enable_if(TrueConstant, "")));
int j(int a) __attribute__((enable_if(FalseConstant, "")));
void fn() {
int (*ptr)(int);
ptr = &f; // error: 'a > 0' is not always true
ptr = &g; // error: 'a == 0 || a != 0' is not a truthy constant
ptr = &h; // OK: 1 is a truthy constant
ptr = &i; // OK: 'TrueConstant' is a truthy constant
ptr = &j; // error: 'FalseConstant' is a constant, but not truthy
}
Because ``enable_if`` evaluation happens during overload resolution,
``enable_if`` may give unintuitive results when used with templates, depending
on when overloads are resolved. In the example below, clang will emit a
diagnostic about no viable overloads for ``foo`` in ``bar``, but not in ``baz``:
.. code-block:: c++
double foo(int i) __attribute__((enable_if(i > 0, "")));
void *foo(int i) __attribute__((enable_if(i <= 0, "")));
template <int I>
auto bar() { return foo(I); }
template <typename T>
auto baz() { return foo(T::number); }
struct WithNumber { constexpr static int number = 1; };
void callThem() {
bar<sizeof(WithNumber)>();
baz<WithNumber>();
}
This is because, in ``bar``, ``foo`` is resolved prior to template
instantiation, so the value for ``I`` isn't known (thus, both ``enable_if``
conditions for ``foo`` fail). However, in ``baz``, ``foo`` is resolved during
template instantiation, so the value for ``T::number`` is known.
}];
}
def DiagnoseIfDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``diagnose_if`` attribute can be placed on function declarations to emit
warnings or errors at compile-time if calls to the attributed function meet
certain user-defined criteria. For example:
.. code-block:: c
int abs(int a)
__attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning")));
int must_abs(int a)
__attribute__((diagnose_if(a >= 0, "Redundant abs call", "error")));
int val = abs(1); // warning: Redundant abs call
int val2 = must_abs(1); // error: Redundant abs call
int val3 = abs(val);
int val4 = must_abs(val); // Because run-time checks are not emitted for
// diagnose_if attributes, this executes without
// issue.
``diagnose_if`` is closely related to ``enable_if``, with a few key differences:
* Overload resolution is not aware of ``diagnose_if`` attributes: they're
considered only after we select the best candidate from a given candidate set.
* Function declarations that differ only in their ``diagnose_if`` attributes are
considered to be redeclarations of the same function (not overloads).
* If the condition provided to ``diagnose_if`` cannot be evaluated, no
diagnostic will be emitted.
Otherwise, ``diagnose_if`` is essentially the logical negation of ``enable_if``.
As a result of bullet number two, ``diagnose_if`` attributes will stack on the
same function. For example:
.. code-block:: c
int foo() __attribute__((diagnose_if(1, "diag1", "warning")));
int foo() __attribute__((diagnose_if(1, "diag2", "warning")));
int bar = foo(); // warning: diag1
// warning: diag2
int (*fooptr)(void) = foo; // warning: diag1
// warning: diag2
constexpr int supportsAPILevel(int N) { return N < 5; }
int baz(int a)
__attribute__((diagnose_if(!supportsAPILevel(10),
"Upgrade to API level 10 to use baz", "error")));
int baz(int a)
__attribute__((diagnose_if(!a, "0 is not recommended.", "warning")));
int (*bazptr)(int) = baz; // error: Upgrade to API level 10 to use baz
int v = baz(0); // error: Upgrade to API level 10 to use baz
Query for this feature with ``__has_attribute(diagnose_if)``.
}];
}
def PassObjectSizeDocs : Documentation {
let Category = DocCatVariable; // Technically it's a parameter doc, but eh.
let Content = [{
.. Note:: The mangling of functions with parameters that are annotated with
``pass_object_size`` is subject to change. You can get around this by
using ``__asm__("foo")`` to explicitly name your functions, thus preserving
your ABI; also, non-overloadable C functions with ``pass_object_size`` are
not mangled.
The ``pass_object_size(Type)`` attribute can be placed on function parameters to
instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite
of said function, and implicitly pass the result of this call in as an invisible
argument of type ``size_t`` directly after the parameter annotated with
``pass_object_size``. Clang will also replace any calls to
``__builtin_object_size(param, Type)`` in the function by said implicit
parameter.
Example usage:
.. code-block:: c
int bzero1(char *const p __attribute__((pass_object_size(0))))
__attribute__((noinline)) {
int i = 0;
for (/**/; i < (int)__builtin_object_size(p, 0); ++i) {
p[i] = 0;
}
return i;
}
int main() {
char chars[100];
int n = bzero1(&chars[0]);
assert(n == sizeof(chars));
return 0;
}
If successfully evaluating ``__builtin_object_size(param, Type)`` at the
callsite is not possible, then the "failed" value is passed in. So, using the
definition of ``bzero1`` from above, the following code would exit cleanly:
.. code-block:: c
int main2(int argc, char *argv[]) {
int n = bzero1(argv);
assert(n == -1);
return 0;
}
``pass_object_size`` plays a part in overload resolution. If two overload
candidates are otherwise equally good, then the overload with one or more
parameters with ``pass_object_size`` is preferred. This implies that the choice
between two identical overloads both with ``pass_object_size`` on one or more
parameters will always be ambiguous; for this reason, having two such overloads
is illegal. For example:
.. code-block:: c++
#define PS(N) __attribute__((pass_object_size(N)))
// OK
void Foo(char *a, char *b); // Overload A
// OK -- overload A has no parameters with pass_object_size.
void Foo(char *a PS(0), char *b PS(0)); // Overload B
// Error -- Same signature (sans pass_object_size) as overload B, and both
// overloads have one or more parameters with the pass_object_size attribute.
void Foo(void *a PS(0), void *b);
// OK
void Bar(void *a PS(0)); // Overload C
// OK
void Bar(char *c PS(1)); // Overload D
void main() {
char known[10], *unknown;
Foo(unknown, unknown); // Calls overload B
Foo(known, unknown); // Calls overload B
Foo(unknown, known); // Calls overload B
Foo(known, known); // Calls overload B
Bar(known); // Calls overload D
Bar(unknown); // Calls overload D
}
Currently, ``pass_object_size`` is a bit restricted in terms of its usage:
* Only one use of ``pass_object_size`` is allowed per parameter.
* It is an error to take the address of a function with ``pass_object_size`` on
any of its parameters. If you wish to do this, you can create an overload
without ``pass_object_size`` on any parameters.
* It is an error to apply the ``pass_object_size`` attribute to parameters that
are not pointers. Additionally, any parameter that ``pass_object_size`` is
applied to must be marked ``const`` at its function's definition.
}];
}
def OverloadableDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Clang provides support for C++ function overloading in C. Function overloading
in C is introduced using the ``overloadable`` attribute. For example, one
might provide several overloaded versions of a ``tgsin`` function that invokes
the appropriate standard function computing the sine of a value with ``float``,
``double``, or ``long double`` precision:
.. code-block:: c
#include <math.h>
float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }
Given these declarations, one can call ``tgsin`` with a ``float`` value to
receive a ``float`` result, with a ``double`` to receive a ``double`` result,
etc. Function overloading in C follows the rules of C++ function overloading
to pick the best overload given the call arguments, with a few C-specific
semantics:
* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a
floating-point promotion (per C99) rather than as a floating-point conversion
(as in C++).
* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is
considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are
compatible types.
* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
and ``U`` are compatible types. This conversion is given "conversion" rank.
* If no viable candidates are otherwise available, we allow a conversion from a
pointer of type ``T*`` to a pointer of type ``U*``, where ``T`` and ``U`` are
incompatible. This conversion is ranked below all other types of conversions.
Please note: ``U`` lacking qualifiers that are present on ``T`` is sufficient
for ``T`` and ``U`` to be incompatible.
The declaration of ``overloadable`` functions is restricted to function
declarations and definitions. If a function is marked with the ``overloadable``
attribute, then all declarations and definitions of functions with that name,
except for at most one (see the note below about unmarked overloads), must have
the ``overloadable`` attribute. In addition, redeclarations of a function with
the ``overloadable`` attribute must have the ``overloadable`` attribute, and
redeclarations of a function without the ``overloadable`` attribute must *not*
have the ``overloadable`` attribute. e.g.,
.. code-block:: c
int f(int) __attribute__((overloadable));
float f(float); // error: declaration of "f" must have the "overloadable" attribute
int f(int); // error: redeclaration of "f" must have the "overloadable" attribute
int g(int) __attribute__((overloadable));
int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute
int h(int);
int h(int) __attribute__((overloadable)); // error: declaration of "h" must not
// have the "overloadable" attribute
Functions marked ``overloadable`` must have prototypes. Therefore, the
following code is ill-formed:
.. code-block:: c
int h() __attribute__((overloadable)); // error: h does not have a prototype
However, ``overloadable`` functions are allowed to use a ellipsis even if there
are no named parameters (as is permitted in C++). This feature is particularly
useful when combined with the ``unavailable`` attribute:
.. code-block:: c++
void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error
Functions declared with the ``overloadable`` attribute have their names mangled
according to the same rules as C++ function names. For example, the three
``tgsin`` functions in our motivating example get the mangled names
``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two
caveats to this use of name mangling:
* Future versions of Clang may change the name mangling of functions overloaded
in C, so you should not depend on an specific mangling. To be completely
safe, we strongly urge the use of ``static inline`` with ``overloadable``
functions.
* The ``overloadable`` attribute has almost no meaning when used in C++,
because names will already be mangled and functions are already overloadable.
However, when an ``overloadable`` function occurs within an ``extern "C"``
linkage specification, it's name *will* be mangled in the same way as it
would in C.
For the purpose of backwards compatibility, at most one function with the same
name as other ``overloadable`` functions may omit the ``overloadable``
attribute. In this case, the function without the ``overloadable`` attribute
will not have its name mangled.
For example:
.. code-block:: c
// Notes with mangled names assume Itanium mangling.
int f(int);
int f(double) __attribute__((overloadable));
void foo() {
f(5); // Emits a call to f (not _Z1fi, as it would with an overload that
// was marked with overloadable).
f(1.0); // Emits a call to _Z1fd.
}
Support for unmarked overloads is not present in some versions of clang. You may
query for it using ``__has_extension(overloadable_unmarked)``.
Query for this attribute with ``__has_attribute(overloadable)``.
}];
}
def ObjCMethodFamilyDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Many methods in Objective-C have conventional meanings determined by their
selectors. It is sometimes useful to be able to mark a method as having a
particular conventional meaning despite not having the right selector, or as
not having the conventional meaning that its selector would suggest. For these
use cases, we provide an attribute to specifically describe the "method family"
that a method belongs to.
**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of
``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This
attribute can only be placed at the end of a method declaration:
.. code-block:: objc
- (NSString *)initMyStringValue __attribute__((objc_method_family(none)));
Users who do not wish to change the conventional meaning of a method, and who
merely want to document its non-standard retain and release semantics, should
use the retaining behavior attributes (``ns_returns_retained``,
``ns_returns_not_retained``, etc).
Query for this feature with ``__has_attribute(objc_method_family)``.
}];
}
def RetainBehaviorDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The behavior of a function with respect to reference counting for Foundation
(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming
convention (e.g. functions starting with "get" are assumed to return at
``+0``).
It can be overriden using a family of the following attributes. In
Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to
a function communicates that the object is returned at ``+1``, and the caller
is responsible for freeing it.
Similiarly, the annotation ``__attribute__((ns_returns_not_retained))``
specifies that the object is returned at ``+0`` and the ownership remains with
the callee.
The annotation ``__attribute__((ns_consumes_self))`` specifies that
the Objective-C method call consumes the reference to ``self``, e.g. by
attaching it to a supplied parameter.
Additionally, parameters can have an annotation
``__attribute__((ns_consumed))``, which specifies that passing an owned object
as that parameter effectively transfers the ownership, and the caller is no
longer responsible for it.
These attributes affect code generation when interacting with ARC code, and
they are used by the Clang Static Analyzer.
In C programs using CoreFoundation, a similar set of attributes:
``__attribute__((cf_returns_not_retained))``,
``__attribute__((cf_returns_retained))`` and ``__attribute__((cf_consumed))``
have the same respective semantics when applied to CoreFoundation objects.
These attributes affect code generation when interacting with ARC code, and
they are used by the Clang Static Analyzer.
Finally, in C++ interacting with XNU kernel (objects inheriting from OSObject),
the same attribute family is present:
``__attribute__((os_returns_not_retained))``,
``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``,
with the same respective semantics.
Similar to ``__attribute__((ns_consumes_self))``,
``__attribute__((os_consumes_this))`` specifies that the method call consumes
the reference to "this" (e.g., when attaching it to a different object supplied
as a parameter).
Out parameters (parameters the function is meant to write into,
either via pointers-to-pointers or references-to-pointers)
may be annotated with ``__attribute__((os_returns_retained))``
or ``__attribute__((os_returns_not_retained))`` which specifies that the object
written into the out parameter should (or respectively should not) be released
after use.
Since often out parameters may or may not be written depending on the exit
code of the function,
annotations ``__attribute__((os_returns_retained_on_zero))``
and ``__attribute__((os_returns_retained_on_non_zero))`` specify that
an out parameter at ``+1`` is written if and only if the function returns a zero
(respectively non-zero) error code.
Observe that return-code-dependent out parameter annotations are only
available for retained out parameters, as non-retained object do not have to be
released by the callee.
These attributes are only used by the Clang Static Analyzer.
The family of attributes ``X_returns_X_retained`` can be added to functions,
C++ methods, and Objective-C methods and properties.
Attributes ``X_consumed`` can be added to parameters of methods, functions,
and Objective-C methods.
}];
}
def NoDebugDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
The ``nodebug`` attribute allows you to suppress debugging information for a
function or method, or for a variable that is not a parameter or a non-static
data member.
}];
}
def NoDuplicateDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``noduplicate`` attribute can be placed on function declarations to control
whether function calls to this function can be duplicated or not as a result of
optimizations. This is required for the implementation of functions with
certain special requirements, like the OpenCL "barrier" function, that might
need to be run concurrently by all the threads that are executing in lockstep
on the hardware. For example this attribute applied on the function
"nodupfunc" in the code below avoids that:
.. code-block:: c
void nodupfunc() __attribute__((noduplicate));
// Setting it as a C++11 attribute is also valid
// void nodupfunc() [[clang::noduplicate]];
void foo();
void bar();
nodupfunc();
if (a > n) {
foo();
} else {
bar();
}
gets possibly modified by some optimizations into code similar to this:
.. code-block:: c
if (a > n) {
nodupfunc();
foo();
} else {
nodupfunc();
bar();
}
where the call to "nodupfunc" is duplicated and sunk into the two branches
of the condition.
}];
}
def ConvergentDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``convergent`` attribute can be placed on a function declaration. It is
translated into the LLVM ``convergent`` attribute, which indicates that the call
instructions of a function with this attribute cannot be made control-dependent
on any additional values.
In languages designed for SPMD/SIMT programming model, e.g. OpenCL or CUDA,
the call instructions of a function with this attribute must be executed by
all work items or threads in a work group or sub group.
This attribute is different from ``noduplicate`` because it allows duplicating
function calls if it can be proved that the duplicated function calls are
not made control-dependent on any additional values, e.g., unrolling a loop
executed by all work items.
Sample usage:
.. code-block:: c
void convfunc(void) __attribute__((convergent));
// Setting it as a C++11 attribute is also valid in a C++ program.
// void convfunc(void) [[clang::convergent]];
}];
}
def NoSplitStackDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
The ``no_split_stack`` attribute disables the emission of the split stack
preamble for a particular function. It has no effect if ``-fsplit-stack``
is not specified.