blob: 29675c2ac7e9b072f14be8d665d8c88d98ba48c1 [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
95// std::list has an implicit gsl::Owner attribute,
96// but explicit attributes take precedence.
97template <typename T>
98class [[gsl::Pointer]] list{};
99// CHECK: ClassTemplateDecl {{.*}} list
100// CHECK: PointerAttr {{.*}}
101// CHECK: ClassTemplateSpecializationDecl {{.*}} list
102// CHECK: PointerAttr {{.*}}
103
104static_assert(sizeof(list<int>), ""); // Force instantiation.
105
106// Forward declared template (Owner).
107template <
108 class CharT,
109 class Traits>
110class basic_regex;
111// CHECK: ClassTemplateDecl {{.*}} basic_regex
112// CHECK: OwnerAttr {{.*}}
113
114// Forward declared template (Pointer).
115template <class T>
116class reference_wrapper;
117// CHECK: ClassTemplateDecl {{.*}} reference_wrapper
118// CHECK: PointerAttr {{.*}}
119
120class some_unknown_type;
121// CHECK: CXXRecordDecl {{.*}} some_unknown_type
122
123} // namespace std
124
125namespace user {
126// If a class is not in the std namespace, we don't infer the attributes.
127class any {
128};
129} // namespace user