1 // RUN: %clang_cc1 -ast-dump %s | \
2 // RUN: FileCheck --implicit-check-not OwnerAttr --implicit-check-not PointerAttr %s
4 // Test attribute inference for types in the standard library.
6 // Attributes are inferred for a (complete) class.
8 // CHECK: CXXRecordDecl {{.*}} any
9 // CHECK: OwnerAttr {{.*}}
12 // Attributes are inferred for instantiations of a complete template.
17 // CHECK: ClassTemplateDecl {{.*}} vector
18 // CHECK: OwnerAttr {{.*}}
19 // CHECK: CXXRecordDecl {{.*}} iterator
20 // CHECK: PointerAttr {{.*}}
21 // CHECK: ClassTemplateSpecializationDecl {{.*}} vector
22 // CHECK: TemplateArgument type 'int'
24 // CHECK: CXXRecordDecl {{.*}} iterator
25 // CHECK: PointerAttr {{.*}}
27 static_assert(sizeof(vector
<int>), ""); // Force instantiation.
28 static_assert(sizeof(vector
<int>::iterator
), ""); // Force instantiation.
31 class vector
<bool> {};
32 // CHECK: ClassTemplateSpecializationDecl {{.*}} vector
33 // CHECK: OwnerAttr {{.*}}
35 // If std::container::iterator is a using declaration, attributes are inferred
36 // for the underlying class.
38 class __set_iterator
{};
39 // CHECK: ClassTemplateDecl {{.*}} __set_iterator
41 // CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator
42 // CHECK: TemplateArgument type 'int'
47 // CHECK: ClassTemplateDecl {{.*}} set
48 // CHECK: OwnerAttr {{.*}}
49 // CHECK: ClassTemplateSpecializationDecl {{.*}} set
50 // CHECK: OwnerAttr {{.*}}
52 using iterator
= __set_iterator
<T
>;
54 static_assert(sizeof(set
<int>::iterator
), ""); // Force instantiation.
56 // If std::container::iterator is a typedef, attributes are inferred for the
59 class __map_iterator
{};
60 // CHECK: ClassTemplateDecl {{.*}} __map_iterator
62 // CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator
63 // CHECK: TemplateArgument type 'int'
68 // CHECK: ClassTemplateDecl {{.*}} map
69 // CHECK: OwnerAttr {{.*}}
70 // CHECK: ClassTemplateSpecializationDecl {{.*}} map
71 // CHECK: OwnerAttr {{.*}}
73 typedef __map_iterator
<T
> iterator
;
75 static_assert(sizeof(map
<int>::iterator
), ""); // Force instantiation.
77 // Inline namespaces are ignored when checking if
78 // the class lives in the std namespace.
79 inline namespace inlinens
{
81 class __unordered_map_iterator
{};
82 // CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator
84 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator
85 // CHECK: TemplateArgument type 'int'
90 // CHECK: ClassTemplateDecl {{.*}} unordered_map
91 // CHECK: OwnerAttr {{.*}}
92 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map
93 // CHECK: OwnerAttr {{.*}}
95 typedef __unordered_map_iterator
<T
> iterator
;
97 static_assert(sizeof(unordered_map
<int>::iterator
), ""); // Force instantiation.
98 } // namespace inlinens
100 // The iterator typedef is a DependentNameType.
101 template <typename T
>
102 class __unordered_multimap_iterator
{};
103 // CHECK: ClassTemplateDecl {{.*}} __unordered_multimap_iterator
104 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multimap_iterator
105 // CHECK: TemplateArgument type 'int'
106 // CHECK: PointerAttr
108 template <typename T
>
109 class __unordered_multimap_base
{
111 using iterator
= __unordered_multimap_iterator
<T
>;
114 template <typename T
>
115 class unordered_multimap
{
116 // CHECK: ClassTemplateDecl {{.*}} unordered_multimap
117 // CHECK: OwnerAttr {{.*}}
118 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multimap
119 // CHECK: OwnerAttr {{.*}}
121 using _Mybase
= __unordered_multimap_base
<T
>;
122 using iterator
= typename
_Mybase::iterator
;
124 static_assert(sizeof(unordered_multimap
<int>::iterator
), ""); // Force instantiation.
126 // The canonical declaration of the iterator template is not its definition.
127 template <typename T
>
128 class __unordered_multiset_iterator
;
129 // CHECK: ClassTemplateDecl {{.*}} __unordered_multiset_iterator
130 // CHECK: PointerAttr
131 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multiset_iterator
132 // CHECK: TemplateArgument type 'int'
133 // CHECK: PointerAttr
135 template <typename T
>
136 class __unordered_multiset_iterator
{
137 // CHECK: ClassTemplateDecl {{.*}} prev {{.*}} __unordered_multiset_iterator
138 // CHECK: PointerAttr
141 template <typename T
>
142 class unordered_multiset
{
143 // CHECK: ClassTemplateDecl {{.*}} unordered_multiset
144 // CHECK: OwnerAttr {{.*}}
145 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multiset
146 // CHECK: OwnerAttr {{.*}}
148 using iterator
= __unordered_multiset_iterator
<T
>;
151 static_assert(sizeof(unordered_multiset
<int>::iterator
), ""); // Force instantiation.
153 // std::list has an implicit gsl::Owner attribute,
154 // but explicit attributes take precedence.
155 template <typename T
>
156 class [[gsl::Pointer
]] list
{};
157 // CHECK: ClassTemplateDecl {{.*}} list
158 // CHECK: PointerAttr {{.*}}
159 // CHECK: ClassTemplateSpecializationDecl {{.*}} list
160 // CHECK: PointerAttr {{.*}}
162 static_assert(sizeof(list
<int>), ""); // Force instantiation.
164 // Forward declared template (Owner).
169 // CHECK: ClassTemplateDecl {{.*}} basic_regex
170 // CHECK: OwnerAttr {{.*}}
172 // Forward declared template (Pointer).
174 class reference_wrapper
;
175 // CHECK: ClassTemplateDecl {{.*}} reference_wrapper
176 // CHECK: PointerAttr {{.*}}
178 class some_unknown_type
;
179 // CHECK: CXXRecordDecl {{.*}} some_unknown_type
181 using size_t = unsigned;
182 inline constexpr size_t dynamic_extent
= -1;
183 template <typename _Tp
, size_t _Extent
= dynamic_extent
>
185 // CHECK: CXXRecordDecl {{.*}} span
186 // CHECK: PointerAttr {{.*}}
189 template <typename _Tp
>
190 struct span
<_Tp
, dynamic_extent
> {};
191 // CHECK: ClassTemplatePartialSpecializationDecl {{.*}} span
192 // CHECK: PointerAttr {{.*}}
196 // If a class is not in the std namespace, we don't infer the attributes.