200 lines · cpp
1// RUN: %clang_cc1 -ast-dump %s | \2// RUN: FileCheck --implicit-check-not OwnerAttr --implicit-check-not PointerAttr %s3 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 {{.*}} any9 // 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 {{.*}} vector18 // CHECK: OwnerAttr {{.*}}19 // CHECK: CXXRecordDecl {{.*}} iterator20 // CHECK: PointerAttr {{.*}}21 // CHECK: ClassTemplateSpecializationDecl {{.*}} vector22 // CHECK: TemplateArgument type 'int'23 // CHECK: OwnerAttr24 // CHECK: CXXRecordDecl {{.*}} iterator25 // CHECK: PointerAttr {{.*}}26};27static_assert(sizeof(vector<int>), ""); // Force instantiation.28static_assert(sizeof(vector<int>::iterator), ""); // Force instantiation.29 30template <>31class vector<bool> {};32// CHECK: ClassTemplateSpecializationDecl {{.*}} vector33// CHECK: OwnerAttr {{.*}}34 35// If std::container::iterator is a using declaration, attributes are inferred36// for the underlying class.37template <typename T>38class __set_iterator {};39// CHECK: ClassTemplateDecl {{.*}} __set_iterator40// CHECK: PointerAttr41// CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator42// CHECK: TemplateArgument type 'int'43// CHECK: PointerAttr44 45template <typename T>46class set {47 // CHECK: ClassTemplateDecl {{.*}} set48 // CHECK: OwnerAttr {{.*}}49 // CHECK: ClassTemplateSpecializationDecl {{.*}} set50 // CHECK: OwnerAttr {{.*}}51public:52 using iterator = __set_iterator<T>;53};54static_assert(sizeof(set<int>::iterator), ""); // Force instantiation.55 56// If std::container::iterator is a typedef, attributes are inferred for the57// underlying class.58template <typename T>59class __map_iterator {};60// CHECK: ClassTemplateDecl {{.*}} __map_iterator61// CHECK: PointerAttr62// CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator63// CHECK: TemplateArgument type 'int'64// CHECK: PointerAttr65 66template <typename T>67class map {68 // CHECK: ClassTemplateDecl {{.*}} map69 // CHECK: OwnerAttr {{.*}}70 // CHECK: ClassTemplateSpecializationDecl {{.*}} map71 // CHECK: OwnerAttr {{.*}}72public:73 typedef __map_iterator<T> iterator;74};75static_assert(sizeof(map<int>::iterator), ""); // Force instantiation.76 77// Inline namespaces are ignored when checking if78// the class lives in the std namespace.79inline namespace inlinens {80template <typename T>81class __unordered_map_iterator {};82// CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator83// CHECK: PointerAttr84// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator85// CHECK: TemplateArgument type 'int'86// CHECK: PointerAttr87 88template <typename T>89class unordered_map {90 // CHECK: ClassTemplateDecl {{.*}} unordered_map91 // CHECK: OwnerAttr {{.*}}92 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map93 // CHECK: OwnerAttr {{.*}}94public:95 typedef __unordered_map_iterator<T> iterator;96};97static_assert(sizeof(unordered_map<int>::iterator), ""); // Force instantiation.98} // namespace inlinens99 100// The iterator typedef is a DependentNameType.101template <typename T>102class __unordered_multimap_iterator {};103// CHECK: ClassTemplateDecl {{.*}} __unordered_multimap_iterator104// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multimap_iterator105// CHECK: TemplateArgument type 'int'106// CHECK: PointerAttr107 108template <typename T>109class __unordered_multimap_base {110public:111 using iterator = __unordered_multimap_iterator<T>;112};113 114template <typename T>115class unordered_multimap {116 // CHECK: ClassTemplateDecl {{.*}} unordered_multimap117 // CHECK: OwnerAttr {{.*}}118 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multimap119 // CHECK: OwnerAttr {{.*}}120public:121 using _Mybase = __unordered_multimap_base<T>;122 using iterator = typename _Mybase::iterator;123};124static_assert(sizeof(unordered_multimap<int>::iterator), ""); // Force instantiation.125 126// The canonical declaration of the iterator template is not its definition.127template <typename T>128class __unordered_multiset_iterator;129// CHECK: ClassTemplateDecl {{.*}} __unordered_multiset_iterator130// CHECK: PointerAttr131// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multiset_iterator132// CHECK: TemplateArgument type 'int'133// CHECK: PointerAttr134 135template <typename T>136class __unordered_multiset_iterator {137 // CHECK: ClassTemplateDecl {{.*}} prev {{.*}} __unordered_multiset_iterator138 // CHECK: PointerAttr139};140 141template <typename T>142class unordered_multiset {143 // CHECK: ClassTemplateDecl {{.*}} unordered_multiset144 // CHECK: OwnerAttr {{.*}}145 // CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multiset146 // CHECK: OwnerAttr {{.*}}147public:148 using iterator = __unordered_multiset_iterator<T>;149};150 151static_assert(sizeof(unordered_multiset<int>::iterator), ""); // Force instantiation.152 153// std::list has an implicit gsl::Owner attribute,154// but explicit attributes take precedence.155template <typename T>156class [[gsl::Pointer]] list{};157// CHECK: ClassTemplateDecl {{.*}} list158// CHECK: PointerAttr {{.*}}159// CHECK: ClassTemplateSpecializationDecl {{.*}} list160// CHECK: PointerAttr {{.*}}161 162static_assert(sizeof(list<int>), ""); // Force instantiation.163 164// Forward declared template (Owner).165template <166 class CharT,167 class Traits>168class basic_regex;169// CHECK: ClassTemplateDecl {{.*}} basic_regex170// CHECK: OwnerAttr {{.*}}171 172// Forward declared template (Pointer).173template <class T>174class reference_wrapper;175// CHECK: ClassTemplateDecl {{.*}} reference_wrapper176// CHECK: PointerAttr {{.*}}177 178class some_unknown_type;179// CHECK: CXXRecordDecl {{.*}} some_unknown_type180 181using size_t = unsigned;182inline constexpr size_t dynamic_extent = -1;183template <typename _Tp, size_t _Extent = dynamic_extent>184class span;185// CHECK: CXXRecordDecl {{.*}} span186// CHECK: PointerAttr {{.*}}187 188 189template <typename _Tp>190struct span<_Tp, dynamic_extent> {};191// CHECK: ClassTemplatePartialSpecializationDecl {{.*}} span192// CHECK: PointerAttr {{.*}}193} // namespace std194 195namespace user {196// If a class is not in the std namespace, we don't infer the attributes.197class any {198};199} // namespace user200