183 lines
5.6 KiB
C++
183 lines
5.6 KiB
C++
// RUN: %clang_cc1 -ast-dump %s | \
|
|
// RUN: FileCheck --implicit-check-not OwnerAttr --implicit-check-not PointerAttr %s
|
|
|
|
// Test attribute inference for types in the standard library.
|
|
namespace std {
|
|
// Attributes are inferred for a (complete) class.
|
|
class any {
|
|
// CHECK: CXXRecordDecl {{.*}} any
|
|
// CHECK: OwnerAttr {{.*}}
|
|
};
|
|
|
|
// Attributes are inferred for instantiations of a complete template.
|
|
template <typename T>
|
|
class vector {
|
|
public:
|
|
class iterator {};
|
|
// CHECK: ClassTemplateDecl {{.*}} vector
|
|
// CHECK: OwnerAttr {{.*}}
|
|
// CHECK: CXXRecordDecl {{.*}} iterator
|
|
// CHECK: PointerAttr {{.*}}
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} vector
|
|
// CHECK: TemplateArgument type 'int'
|
|
// CHECK: OwnerAttr
|
|
// CHECK: CXXRecordDecl {{.*}} iterator
|
|
// CHECK: PointerAttr {{.*}}
|
|
};
|
|
static_assert(sizeof(vector<int>), ""); // Force instantiation.
|
|
static_assert(sizeof(vector<int>::iterator), ""); // Force instantiation.
|
|
|
|
// If std::container::iterator is a using declaration, attributes are inferred
|
|
// for the underlying class.
|
|
template <typename T>
|
|
class __set_iterator {};
|
|
// CHECK: ClassTemplateDecl {{.*}} __set_iterator
|
|
// CHECK: PointerAttr
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} __set_iterator
|
|
// CHECK: TemplateArgument type 'int'
|
|
// CHECK: PointerAttr
|
|
|
|
template <typename T>
|
|
class set {
|
|
// CHECK: ClassTemplateDecl {{.*}} set
|
|
// CHECK: OwnerAttr {{.*}}
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} set
|
|
// CHECK: OwnerAttr {{.*}}
|
|
public:
|
|
using iterator = __set_iterator<T>;
|
|
};
|
|
static_assert(sizeof(set<int>::iterator), ""); // Force instantiation.
|
|
|
|
// If std::container::iterator is a typedef, attributes are inferred for the
|
|
// underlying class.
|
|
template <typename T>
|
|
class __map_iterator {};
|
|
// CHECK: ClassTemplateDecl {{.*}} __map_iterator
|
|
// CHECK: PointerAttr
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} __map_iterator
|
|
// CHECK: TemplateArgument type 'int'
|
|
// CHECK: PointerAttr
|
|
|
|
template <typename T>
|
|
class map {
|
|
// CHECK: ClassTemplateDecl {{.*}} map
|
|
// CHECK: OwnerAttr {{.*}}
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} map
|
|
// CHECK: OwnerAttr {{.*}}
|
|
public:
|
|
typedef __map_iterator<T> iterator;
|
|
};
|
|
static_assert(sizeof(map<int>::iterator), ""); // Force instantiation.
|
|
|
|
// Inline namespaces are ignored when checking if
|
|
// the class lives in the std namespace.
|
|
inline namespace inlinens {
|
|
template <typename T>
|
|
class __unordered_map_iterator {};
|
|
// CHECK: ClassTemplateDecl {{.*}} __unordered_map_iterator
|
|
// CHECK: PointerAttr
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_map_iterator
|
|
// CHECK: TemplateArgument type 'int'
|
|
// CHECK: PointerAttr
|
|
|
|
template <typename T>
|
|
class unordered_map {
|
|
// CHECK: ClassTemplateDecl {{.*}} unordered_map
|
|
// CHECK: OwnerAttr {{.*}}
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_map
|
|
// CHECK: OwnerAttr {{.*}}
|
|
public:
|
|
typedef __unordered_map_iterator<T> iterator;
|
|
};
|
|
static_assert(sizeof(unordered_map<int>::iterator), ""); // Force instantiation.
|
|
} // namespace inlinens
|
|
|
|
// The iterator typedef is a DependentNameType.
|
|
template <typename T>
|
|
class __unordered_multimap_iterator {};
|
|
// CHECK: ClassTemplateDecl {{.*}} __unordered_multimap_iterator
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multimap_iterator
|
|
// CHECK: TemplateArgument type 'int'
|
|
// CHECK: PointerAttr
|
|
|
|
template <typename T>
|
|
class __unordered_multimap_base {
|
|
public:
|
|
using iterator = __unordered_multimap_iterator<T>;
|
|
};
|
|
|
|
template <typename T>
|
|
class unordered_multimap {
|
|
// CHECK: ClassTemplateDecl {{.*}} unordered_multimap
|
|
// CHECK: OwnerAttr {{.*}}
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multimap
|
|
// CHECK: OwnerAttr {{.*}}
|
|
public:
|
|
using _Mybase = __unordered_multimap_base<T>;
|
|
using iterator = typename _Mybase::iterator;
|
|
};
|
|
static_assert(sizeof(unordered_multimap<int>::iterator), ""); // Force instantiation.
|
|
|
|
// The canonical declaration of the iterator template is not its definition.
|
|
template <typename T>
|
|
class __unordered_multiset_iterator;
|
|
// CHECK: ClassTemplateDecl {{.*}} __unordered_multiset_iterator
|
|
// CHECK: PointerAttr
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} __unordered_multiset_iterator
|
|
// CHECK: TemplateArgument type 'int'
|
|
// CHECK: PointerAttr
|
|
|
|
template <typename T>
|
|
class __unordered_multiset_iterator {
|
|
// CHECK: ClassTemplateDecl {{.*}} prev {{.*}} __unordered_multiset_iterator
|
|
// CHECK: PointerAttr
|
|
};
|
|
|
|
template <typename T>
|
|
class unordered_multiset {
|
|
// CHECK: ClassTemplateDecl {{.*}} unordered_multiset
|
|
// CHECK: OwnerAttr {{.*}}
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} unordered_multiset
|
|
// CHECK: OwnerAttr {{.*}}
|
|
public:
|
|
using iterator = __unordered_multiset_iterator<T>;
|
|
};
|
|
|
|
static_assert(sizeof(unordered_multiset<int>::iterator), ""); // Force instantiation.
|
|
|
|
// std::list has an implicit gsl::Owner attribute,
|
|
// but explicit attributes take precedence.
|
|
template <typename T>
|
|
class [[gsl::Pointer]] list{};
|
|
// CHECK: ClassTemplateDecl {{.*}} list
|
|
// CHECK: PointerAttr {{.*}}
|
|
// CHECK: ClassTemplateSpecializationDecl {{.*}} list
|
|
// CHECK: PointerAttr {{.*}}
|
|
|
|
static_assert(sizeof(list<int>), ""); // Force instantiation.
|
|
|
|
// Forward declared template (Owner).
|
|
template <
|
|
class CharT,
|
|
class Traits>
|
|
class basic_regex;
|
|
// CHECK: ClassTemplateDecl {{.*}} basic_regex
|
|
// CHECK: OwnerAttr {{.*}}
|
|
|
|
// Forward declared template (Pointer).
|
|
template <class T>
|
|
class reference_wrapper;
|
|
// CHECK: ClassTemplateDecl {{.*}} reference_wrapper
|
|
// CHECK: PointerAttr {{.*}}
|
|
|
|
class some_unknown_type;
|
|
// CHECK: CXXRecordDecl {{.*}} some_unknown_type
|
|
|
|
} // namespace std
|
|
|
|
namespace user {
|
|
// If a class is not in the std namespace, we don't infer the attributes.
|
|
class any {
|
|
};
|
|
} // namespace user
|