llvm-capstone/clang/test/SemaTemplate/instantiate-enum.cpp
Richard Smith 74f02347ca PR13403 (+duplicates): implement C++ DR1310 (http://wg21.link/cwg1310).
Under this defect resolution, the injected-class-name of a class or class
template cannot be used except in very limited circumstances (when declaring a
constructor, in a nested-name-specifier, in a base-specifier, or in an
elaborated-type-specifier). This is apparently done to make parsing easier, but
it's a pain for us since we don't know whether a template-id using the
injected-class-name is valid at the point when we annotate it (we don't yet
know whether the template-id will become part of an elaborated-type-specifier).

As a tentative resolution to a perceived language defect, mem-initializer-ids
are added to the list of exceptions here (they generally follow the same rules
as base-specifiers).

When the reference to the injected-class-name uses the 'typename' or 'template'
keywords, we permit it to be used to name a type or template as an extension;
other compilers also accept some cases in this area. There are also a couple of
corner cases with dependent template names that we do not yet diagnose, but
which will also get this treatment.

llvm-svn: 292518
2017-01-19 21:00:13 +00:00

44 lines
579 B
C++

// RUN: %clang_cc1 -fsyntax-only %s
template<typename T, T I, int J>
struct adder {
enum {
value = I + J,
value2
};
};
int array1[adder<long, 3, 4>::value == 7? 1 : -1];
namespace PR6375 {
template<typename T>
void f() {
enum Enum
{
enumerator1 = 0xFFFFFFF,
enumerator2 = enumerator1 - 1
};
int xb1 = enumerator1;
int xe1 = enumerator2;
}
template void f<int>();
}
namespace EnumScoping {
template <typename T>
struct C {
struct X {};
enum {
value = 42
};
};
void f(int i, C<int>::X c) {
int value;
}
}