llvm-project/clang/test/SemaCXX/enum-attr.cpp
Akira Hatanaka 3c268af42f Add support for attribute enum_extensibility.
This commit adds support for a new attribute that will be used to
distinguish between extensible and inextensible enums. There are three
main purposes of this attribute:

1. Give better control over when enum-related warnings are issued.
For example, in the code below, clang will not issue a -Wassign-enum
warning if the enum is marked "open":

enum __attribute__((enum_extensibility(closed))) EnumClosed {
  B0 = 1, B1 = 10
};

enum __attribute__((enum_extensibility(open))) EnumOpen {
  C0 = 1, C1 = 10
};

enum EnumClosed ec = 100; // warning issued
enum EnumOpen eo = 100; // no warning

2. Enable code-completion and debugging tools to offer better
suggestions.

3. Make it easier for swift's clang importer to determine which swift
type an enum should be mapped to.

For more details, see the discussion I started on cfe-dev:
http://lists.llvm.org/pipermail/cfe-dev/2017-February/052748.html

rdar://problem/12764379
rdar://problem/23145650

Differential Revision: https://reviews.llvm.org/D30766

llvm-svn: 298332
2017-03-21 02:23:00 +00:00

109 lines
2.3 KiB
C++

// RUN: %clang_cc1 -fsyntax-only -verify -Wassign-enum -Wswitch-enum -Wcovered-switch-default -std=c++11 %s
enum Enum {
A0 = 1, A1 = 10
};
enum __attribute__((enum_extensibility(closed))) EnumClosed {
B0 = 1, B1 = 10
};
enum [[clang::enum_extensibility(open)]] EnumOpen {
C0 = 1, C1 = 10
};
enum __attribute__((flag_enum)) EnumFlag {
D0 = 1, D1 = 8
};
enum __attribute__((flag_enum,enum_extensibility(closed))) EnumFlagClosed {
E0 = 1, E1 = 8
};
enum __attribute__((flag_enum,enum_extensibility(open))) EnumFlagOpen {
F0 = 1, F1 = 8
};
void test() {
enum Enum t0;
switch (t0) { // expected-warning{{enumeration value 'A1' not handled in switch}}
case A0: break;
case 16: break; // expected-warning{{case value not in enumerated type}}
}
switch (t0) {
case A0: break;
case A1: break;
default: break; // expected-warning{{default label in switch which covers all enumeration}}
}
enum EnumClosed t1;
switch (t1) { // expected-warning{{enumeration value 'B1' not handled in switch}}
case B0: break;
case 16: break; // expected-warning{{case value not in enumerated type}}
}
switch (t1) {
case B0: break;
case B1: break;
default: break; // expected-warning{{default label in switch which covers all enumeration}}
}
enum EnumOpen t2;
switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}}
case C0: break;
case 16: break;
}
switch (t2) {
case C0: break;
case C1: break;
default: break;
}
enum EnumFlag t3;
switch (t3) { // expected-warning{{enumeration value 'D1' not handled in switch}}
case D0: break;
case 9: break;
case 16: break; // expected-warning{{case value not in enumerated type}}
}
switch (t3) {
case D0: break;
case D1: break;
default: break;
}
enum EnumFlagClosed t4;
switch (t4) { // expected-warning{{enumeration value 'E1' not handled in switch}}
case E0: break;
case 9: break;
case 16: break; // expected-warning{{case value not in enumerated type}}
}
switch (t4) {
case E0: break;
case E1: break;
default: break;
}
enum EnumFlagOpen t5;
switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}}
case F0: break;
case 9: break;
case 16: break;
}
switch (t5) {
case F0: break;
case F1: break;
default: break;
}
}