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.
30 // If std::container::iterator is a using declaration, attributes are inferred
31 // for the underlying class.
33 class __set_iterator
{};
34 // CHECK: ClassTemplateDecl {{.*}} __set_iterator
36 // CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator
37 // CHECK: TemplateArgument type 'int'
42 // CHECK: ClassTemplateDecl {{.*}} set
43 // CHECK: OwnerAttr {{.*}}
44 // CHECK: ClassTemplateSpecializationDecl {{.*}} set
45 // CHECK: OwnerAttr {{.*}}
47 using iterator
= __set_iterator
<T
>;
49 static_assert(sizeof(set
<int>::iterator
), ""); // Force instantiation.
51 // If std::container::iterator is a typedef, attributes are inferred for the
54 class __map_iterator
{};
55 // CHECK: ClassTemplateDecl {{.*}} __map_iterator
57 // CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator
58 // CHECK: TemplateArgument type 'int'
63 // CHECK: ClassTemplateDecl {{.*}} map
64 // CHECK: OwnerAttr {{.*}}
65 // CHECK: ClassTemplateSpecializationDecl {{.*}} map
66 // CHECK: OwnerAttr {{.*}}
68 typedef __map_iterator
<T
> iterator
;
70 static_assert(sizeof(map
<int>::iterator
), ""); // Force instantiation.
72 // Inline namespaces are ignored when checking if
73 // the class lives in the std namespace.
74 inline namespace inlinens
{
76 class __unordered_map_iterator
{};
77 // CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator
79 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator
80 // CHECK: TemplateArgument type 'int'
85 // CHECK: ClassTemplateDecl {{.*}} unordered_map
86 // CHECK: OwnerAttr {{.*}}
87 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map
88 // CHECK: OwnerAttr {{.*}}
90 typedef __unordered_map_iterator
<T
> iterator
;
92 static_assert(sizeof(unordered_map
<int>::iterator
), ""); // Force instantiation.
93 } // namespace inlinens
95 // The iterator typedef is a DependentNameType.
97 class __unordered_multimap_iterator
{};
98 // CHECK: ClassTemplateDecl {{.*}} __unordered_multimap_iterator
99 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multimap_iterator
100 // CHECK: TemplateArgument type 'int'
101 // CHECK: PointerAttr
103 template <typename T
>
104 class __unordered_multimap_base
{
106 using iterator
= __unordered_multimap_iterator
<T
>;
109 template <typename T
>
110 class unordered_multimap
{
111 // CHECK: ClassTemplateDecl {{.*}} unordered_multimap
112 // CHECK: OwnerAttr {{.*}}
113 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multimap
114 // CHECK: OwnerAttr {{.*}}
116 using _Mybase
= __unordered_multimap_base
<T
>;
117 using iterator
= typename
_Mybase::iterator
;
119 static_assert(sizeof(unordered_multimap
<int>::iterator
), ""); // Force instantiation.
121 // The canonical declaration of the iterator template is not its definition.
122 template <typename T
>
123 class __unordered_multiset_iterator
;
124 // CHECK: ClassTemplateDecl {{.*}} __unordered_multiset_iterator
125 // CHECK: PointerAttr
126 // CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multiset_iterator
127 // CHECK: TemplateArgument type 'int'
128 // CHECK: PointerAttr
130 template <typename T
>
131 class __unordered_multiset_iterator
{
132 // CHECK: ClassTemplateDecl {{.*}} prev {{.*}} __unordered_multiset_iterator
133 // CHECK: PointerAttr
136 template <typename T
>
137 class unordered_multiset
{
138 // CHECK: ClassTemplateDecl {{.*}} unordered_multiset
139 // CHECK: OwnerAttr {{.*}}
140 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multiset
141 // CHECK: OwnerAttr {{.*}}
143 using iterator
= __unordered_multiset_iterator
<T
>;
146 static_assert(sizeof(unordered_multiset
<int>::iterator
), ""); // Force instantiation.
148 // std::list has an implicit gsl::Owner attribute,
149 // but explicit attributes take precedence.
150 template <typename T
>
151 class [[gsl::Pointer
]] list
{};
152 // CHECK: ClassTemplateDecl {{.*}} list
153 // CHECK: PointerAttr {{.*}}
154 // CHECK: ClassTemplateSpecializationDecl {{.*}} list
155 // CHECK: PointerAttr {{.*}}
157 static_assert(sizeof(list
<int>), ""); // Force instantiation.
159 // Forward declared template (Owner).
164 // CHECK: ClassTemplateDecl {{.*}} basic_regex
165 // CHECK: OwnerAttr {{.*}}
167 // Forward declared template (Pointer).
169 class reference_wrapper
;
170 // CHECK: ClassTemplateDecl {{.*}} reference_wrapper
171 // CHECK: PointerAttr {{.*}}
173 class some_unknown_type
;
174 // CHECK: CXXRecordDecl {{.*}} some_unknown_type
179 // If a class is not in the std namespace, we don't infer the attributes.