blob: 352e1e473580a682bfc265b389fd72aabbe0cd06 [file] [log] [blame]
Matthias Gehre23092ca2019-08-07 10:45:36 +00001// RUN: %clang_cc1 -ast-dump %s | \
2// RUN: FileCheck --implicit-check-not OwnerAttr --implicit-check-not PointerAttr %s
3
4// Test attribute inference for types in the standard library.
5namespace std {
6// Attributes are inferred for a (complete) class.
7class any {
8 // CHECK: CXXRecordDecl {{.*}} any
9 // CHECK: OwnerAttr {{.*}}
10};
11
12// Attributes are inferred for instantiations of a complete template.
13template <typename T>
14class vector {
15public:
16 class iterator {};
17 // CHECK: ClassTemplateDecl {{.*}} vector
18 // CHECK: OwnerAttr {{.*}}
19 // CHECK: CXXRecordDecl {{.*}} iterator
20 // CHECK: PointerAttr {{.*}}
21 // CHECK: ClassTemplateSpecializationDecl {{.*}} vector
22 // CHECK: TemplateArgument type 'int'
23 // CHECK: OwnerAttr
24 // CHECK: CXXRecordDecl {{.*}} iterator
25 // CHECK: PointerAttr {{.*}}
26};
27static_assert(sizeof(vector<int>), ""); // Force instantiation.
28static_assert(sizeof(vector<int>::iterator), ""); // Force instantiation.
29
30// If std::container::iterator is a using declaration, attributes are inferred
31// for the underlying class.
32template <typename T>
33class __set_iterator {};
34// CHECK: ClassTemplateDecl {{.*}} __set_iterator
35// CHECK: PointerAttr
36// CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator
37// CHECK: TemplateArgument type 'int'
38// CHECK: PointerAttr
39
40template <typename T>
41class set {
42 // CHECK: ClassTemplateDecl {{.*}} set
43 // CHECK: OwnerAttr {{.*}}
44 // CHECK: ClassTemplateSpecializationDecl {{.*}} set
45 // CHECK: OwnerAttr {{.*}}
46public:
47 using iterator = __set_iterator<T>;
48};
49static_assert(sizeof(set<int>::iterator), ""); // Force instantiation.
50
51// If std::container::iterator is a typedef, attributes are inferred for the
52// underlying class.
53template <typename T>
54class __map_iterator {};
55// CHECK: ClassTemplateDecl {{.*}} __map_iterator
56// CHECK: PointerAttr
57// CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator
58// CHECK: TemplateArgument type 'int'
59// CHECK: PointerAttr
60
61template <typename T>
62class map {
63 // CHECK: ClassTemplateDecl {{.*}} map
64 // CHECK: OwnerAttr {{.*}}
65 // CHECK: ClassTemplateSpecializationDecl {{.*}} map
66 // CHECK: OwnerAttr {{.*}}
67public:
68 typedef __map_iterator<T> iterator;
69};
70static_assert(sizeof(map<int>::iterator), ""); // Force instantiation.
71
72// Inline namespaces are ignored when checking if
73// the class lives in the std namespace.
74inline namespace inlinens {
75template <typename T>
76class __unordered_map_iterator {};
77// CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator
78// CHECK: PointerAttr
79// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator
80// CHECK: TemplateArgument type 'int'
81// CHECK: PointerAttr
82
83template <typename T>
84class unordered_map {
85 // CHECK: ClassTemplateDecl {{.*}} unordered_map
86 // CHECK: OwnerAttr {{.*}}
87 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map
88 // CHECK: OwnerAttr {{.*}}
89public:
90 typedef __unordered_map_iterator<T> iterator;
91};
92static_assert(sizeof(unordered_map<int>::iterator), ""); // Force instantiation.
93} // namespace inlinens
94
Matthias Gehref64f4882019-09-06 08:56:30 +000095// The iterator typedef is a DependentNameType.
96template <typename T>
97class __unordered_multimap_iterator {};
98// CHECK: ClassTemplateDecl {{.*}} __unordered_multimap_iterator
99// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multimap_iterator
100// CHECK: TemplateArgument type 'int'
101// CHECK: PointerAttr
102
103template <typename T>
104class __unordered_multimap_base {
105public:
106 using iterator = __unordered_multimap_iterator<T>;
107};
108
109template <typename T>
110class unordered_multimap {
111 // CHECK: ClassTemplateDecl {{.*}} unordered_multimap
112 // CHECK: OwnerAttr {{.*}}
113 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multimap
114 // CHECK: OwnerAttr {{.*}}
115public:
116 using _Mybase = __unordered_multimap_base<T>;
117 using iterator = typename _Mybase::iterator;
118};
119static_assert(sizeof(unordered_multimap<int>::iterator), ""); // Force instantiation.
120
121// The canonical declaration of the iterator template is not its definition.
122template <typename T>
123class __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
129
130template <typename T>
131class __unordered_multiset_iterator {
132 // CHECK: ClassTemplateDecl {{.*}} prev {{.*}} __unordered_multiset_iterator
133 // CHECK: PointerAttr
134};
135
136template <typename T>
137class unordered_multiset {
138 // CHECK: ClassTemplateDecl {{.*}} unordered_multiset
139 // CHECK: OwnerAttr {{.*}}
140 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multiset
141 // CHECK: OwnerAttr {{.*}}
142public:
143 using iterator = __unordered_multiset_iterator<T>;
144};
145
146static_assert(sizeof(unordered_multiset<int>::iterator), ""); // Force instantiation.
147
Matthias Gehre23092ca2019-08-07 10:45:36 +0000148// std::list has an implicit gsl::Owner attribute,
149// but explicit attributes take precedence.
150template <typename T>
151class [[gsl::Pointer]] list{};
152// CHECK: ClassTemplateDecl {{.*}} list
153// CHECK: PointerAttr {{.*}}
154// CHECK: ClassTemplateSpecializationDecl {{.*}} list
155// CHECK: PointerAttr {{.*}}
156
157static_assert(sizeof(list<int>), ""); // Force instantiation.
158
159// Forward declared template (Owner).
160template <
161 class CharT,
162 class Traits>
163class basic_regex;
164// CHECK: ClassTemplateDecl {{.*}} basic_regex
165// CHECK: OwnerAttr {{.*}}
166
167// Forward declared template (Pointer).
168template <class T>
169class reference_wrapper;
170// CHECK: ClassTemplateDecl {{.*}} reference_wrapper
171// CHECK: PointerAttr {{.*}}
172
173class some_unknown_type;
174// CHECK: CXXRecordDecl {{.*}} some_unknown_type
175
176} // namespace std
177
178namespace user {
179// If a class is not in the std namespace, we don't infer the attributes.
180class any {
181};
182} // namespace user