From: Nico Weber Date: Wed, 24 Sep 2014 03:28:54 +0000 (+0000) Subject: Follow-up to r218292: Add more REVERTIBLE_TYPE_TRAITs. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6bdce8e8b7cb316d87eeb10db2b0a4a9a9d8a02;p=clang Follow-up to r218292: Add more REVERTIBLE_TYPE_TRAITs. r218292 reverted r197496 because it broke things. In addition to breaking things, r197496 also made all traits starting with __is_ revertible. Reinstantiate that part of r197496 because code out there (e.g. libc++) depends on this behavior. Fixes PR21045. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218365 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 8ea5396694..08f73d4d09 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1229,22 +1229,55 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, if (TagType == DeclSpec::TST_struct && !Tok.is(tok::identifier) && Tok.getIdentifierInfo() && - (Tok.is(tok::kw___is_arithmetic) || + (Tok.is(tok::kw___is_abstract) || + Tok.is(tok::kw___is_arithmetic) || + Tok.is(tok::kw___is_array) || + Tok.is(tok::kw___is_base_of) || + Tok.is(tok::kw___is_class) || + Tok.is(tok::kw___is_complete_type) || + Tok.is(tok::kw___is_compound) || + Tok.is(tok::kw___is_const) || + Tok.is(tok::kw___is_constructible) || Tok.is(tok::kw___is_convertible) || + Tok.is(tok::kw___is_convertible_to) || + Tok.is(tok::kw___is_destructible) || Tok.is(tok::kw___is_empty) || + Tok.is(tok::kw___is_enum) || Tok.is(tok::kw___is_floating_point) || + Tok.is(tok::kw___is_final) || Tok.is(tok::kw___is_function) || Tok.is(tok::kw___is_fundamental) || Tok.is(tok::kw___is_integral) || + Tok.is(tok::kw___is_interface_class) || + Tok.is(tok::kw___is_literal) || + Tok.is(tok::kw___is_lvalue_expr) || + Tok.is(tok::kw___is_lvalue_reference) || Tok.is(tok::kw___is_member_function_pointer) || + Tok.is(tok::kw___is_member_object_pointer) || Tok.is(tok::kw___is_member_pointer) || + Tok.is(tok::kw___is_nothrow_assignable) || + Tok.is(tok::kw___is_nothrow_constructible) || + Tok.is(tok::kw___is_nothrow_destructible) || + Tok.is(tok::kw___is_object) || Tok.is(tok::kw___is_pod) || Tok.is(tok::kw___is_pointer) || + Tok.is(tok::kw___is_polymorphic) || + Tok.is(tok::kw___is_reference) || + Tok.is(tok::kw___is_rvalue_expr) || + Tok.is(tok::kw___is_rvalue_reference) || Tok.is(tok::kw___is_same) || Tok.is(tok::kw___is_scalar) || + Tok.is(tok::kw___is_sealed) || Tok.is(tok::kw___is_signed) || + Tok.is(tok::kw___is_standard_layout) || + Tok.is(tok::kw___is_trivial) || + Tok.is(tok::kw___is_trivially_assignable) || + Tok.is(tok::kw___is_trivially_constructible) || + Tok.is(tok::kw___is_trivially_copyable) || + Tok.is(tok::kw___is_union) || Tok.is(tok::kw___is_unsigned) || - Tok.is(tok::kw___is_void))) + Tok.is(tok::kw___is_void) || + Tok.is(tok::kw___is_volatile))) // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the // name of struct templates, but some are keywords in GCC >= 4.3 // and Clang. Therefore, when we see the token sequence "struct diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 2b0daad60f..e121902bf0 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -719,22 +719,55 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \ = RTT_JOIN(tok::kw_,Name) + REVERTIBLE_TYPE_TRAIT(__is_abstract); REVERTIBLE_TYPE_TRAIT(__is_arithmetic); + REVERTIBLE_TYPE_TRAIT(__is_array); + REVERTIBLE_TYPE_TRAIT(__is_base_of); + REVERTIBLE_TYPE_TRAIT(__is_class); + REVERTIBLE_TYPE_TRAIT(__is_complete_type); + REVERTIBLE_TYPE_TRAIT(__is_compound); + REVERTIBLE_TYPE_TRAIT(__is_const); + REVERTIBLE_TYPE_TRAIT(__is_constructible); REVERTIBLE_TYPE_TRAIT(__is_convertible); + REVERTIBLE_TYPE_TRAIT(__is_convertible_to); + REVERTIBLE_TYPE_TRAIT(__is_destructible); REVERTIBLE_TYPE_TRAIT(__is_empty); + REVERTIBLE_TYPE_TRAIT(__is_enum); REVERTIBLE_TYPE_TRAIT(__is_floating_point); + REVERTIBLE_TYPE_TRAIT(__is_final); REVERTIBLE_TYPE_TRAIT(__is_function); REVERTIBLE_TYPE_TRAIT(__is_fundamental); REVERTIBLE_TYPE_TRAIT(__is_integral); + REVERTIBLE_TYPE_TRAIT(__is_interface_class); + REVERTIBLE_TYPE_TRAIT(__is_literal); + REVERTIBLE_TYPE_TRAIT(__is_lvalue_expr); + REVERTIBLE_TYPE_TRAIT(__is_lvalue_reference); REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer); + REVERTIBLE_TYPE_TRAIT(__is_member_object_pointer); REVERTIBLE_TYPE_TRAIT(__is_member_pointer); + REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); + REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); + REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); + REVERTIBLE_TYPE_TRAIT(__is_object); REVERTIBLE_TYPE_TRAIT(__is_pod); REVERTIBLE_TYPE_TRAIT(__is_pointer); + REVERTIBLE_TYPE_TRAIT(__is_polymorphic); + REVERTIBLE_TYPE_TRAIT(__is_reference); + REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); + REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); REVERTIBLE_TYPE_TRAIT(__is_same); REVERTIBLE_TYPE_TRAIT(__is_scalar); + REVERTIBLE_TYPE_TRAIT(__is_sealed); REVERTIBLE_TYPE_TRAIT(__is_signed); + REVERTIBLE_TYPE_TRAIT(__is_standard_layout); + REVERTIBLE_TYPE_TRAIT(__is_trivial); + REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); + REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); + REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); + REVERTIBLE_TYPE_TRAIT(__is_union); REVERTIBLE_TYPE_TRAIT(__is_unsigned); REVERTIBLE_TYPE_TRAIT(__is_void); + REVERTIBLE_TYPE_TRAIT(__is_volatile); #undef REVERTIBLE_TYPE_TRAIT #undef RTT_JOIN } diff --git a/test/PCH/cxx-traits.cpp b/test/PCH/cxx-traits.cpp index 42656a3ad5..fc3e1335dd 100644 --- a/test/PCH/cxx-traits.cpp +++ b/test/PCH/cxx-traits.cpp @@ -1,8 +1,8 @@ // Test this without pch. -// RUN: %clang_cc1 -include %S/cxx-traits.h -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fms-extensions -include %S/cxx-traits.h -std=c++11 -fsyntax-only -verify %s -// RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/cxx-traits.h -// RUN: %clang_cc1 -std=c++11 -include-pch %t -DPCH -fsyntax-only -verify %s +// RUN: %clang_cc1 -fms-extensions -x c++-header -std=c++11 -emit-pch -o %t %S/cxx-traits.h +// RUN: %clang_cc1 -fms-extensions -std=c++11 -include-pch %t -DPCH -fsyntax-only -verify %s #ifdef PCH // expected-no-diagnostics @@ -15,5 +15,52 @@ bool default_construct_int = n::is_trivially_constructible::value; bool copy_construct_int = n::is_trivially_constructible::value; // The built-ins should still work too: -bool _is_pod_result = __is_pod(int); +bool _is_abstract_result = __is_abstract(int); +bool _is_arithmetic_result = __is_arithmetic(int); +bool _is_array_result = __is_array(int); +bool _is_base_of_result = __is_base_of(int, int); +bool _is_class_result = __is_class(int); +bool _is_complete_type_result = __is_complete_type(int); +bool _is_compound_result = __is_compound(int); +bool _is_const_result = __is_const(int); +bool _is_constructible_result = __is_constructible(int); +bool _is_convertible_result = __is_convertible(int, int); +bool _is_convertible_to_result = __is_convertible_to(int, int); +bool _is_destructible_result = __is_destructible(int); bool _is_empty_result = __is_empty(int); +bool _is_enum_result = __is_enum(int); +bool _is_floating_point_result = __is_floating_point(int); +bool _is_final_result = __is_final(int); +bool _is_function_result = __is_function(int); +bool _is_fundamental_result = __is_fundamental(int); +bool _is_integral_result = __is_integral(int); +bool _is_interface_class_result = __is_interface_class(int); +bool _is_literal_result = __is_literal(int); +bool _is_lvalue_expr_result = __is_lvalue_expr(0); +bool _is_lvalue_reference_result = __is_lvalue_reference(int); +bool _is_member_function_pointer_result = __is_member_function_pointer(int); +bool _is_member_object_pointer_result = __is_member_object_pointer(int); +bool _is_member_pointer_result = __is_member_pointer(int); +bool _is_nothrow_assignable_result = __is_nothrow_assignable(int, int); +bool _is_nothrow_constructible_result = __is_nothrow_constructible(int); +bool _is_nothrow_destructible_result = __is_nothrow_destructible(int); +bool _is_object_result = __is_object(int); +bool _is_pod_result = __is_pod(int); +bool _is_pointer_result = __is_pointer(int); +bool _is_polymorphic_result = __is_polymorphic(int); +bool _is_reference_result = __is_reference(int); +bool _is_rvalue_expr_result = __is_rvalue_expr(0); +bool _is_rvalue_reference_result = __is_rvalue_reference(int); +bool _is_same_result = __is_same(int, int); +bool _is_scalar_result = __is_scalar(int); +bool _is_sealed_result = __is_sealed(int); +bool _is_signed_result = __is_signed(int); +bool _is_standard_layout_result = __is_standard_layout(int); +bool _is_trivial_result = __is_trivial(int); +bool _is_trivially_assignable_result = __is_trivially_assignable(int, int); +bool _is_trivially_constructible_result = __is_trivially_constructible(int); +bool _is_trivially_copyable_result = __is_trivially_copyable(int); +bool _is_union_result = __is_union(int); +bool _is_unsigned_result = __is_unsigned(int); +bool _is_void_result = __is_void(int); +bool _is_volatile_result = __is_volatile(int); diff --git a/test/PCH/cxx-traits.h b/test/PCH/cxx-traits.h index 59ba513ef1..2132476818 100644 --- a/test/PCH/cxx-traits.h +++ b/test/PCH/cxx-traits.h @@ -17,4 +17,53 @@ struct is_trivially_constructible { static const bool value = __is_trivially_constructible(T, Args...); }; +struct __is_abstract {}; // expected-warning {{made available}} +struct __is_arithmetic {}; // expected-warning {{made available}} +struct __is_array {}; // expected-warning {{made available}} +struct __is_base_of {}; // expected-warning {{made available}} +struct __is_class {}; // expected-warning {{made available}} +struct __is_complete_type {}; // expected-warning {{made available}} +struct __is_compound {}; // expected-warning {{made available}} +struct __is_const {}; // expected-warning {{made available}} +struct __is_constructible {}; // expected-warning {{made available}} +struct __is_convertible {}; // expected-warning {{made available}} +struct __is_convertible_to {}; // expected-warning {{made available}} +struct __is_destructible {}; // expected-warning {{made available}} +struct __is_enum {}; // expected-warning {{made available}} +struct __is_floating_point {}; // expected-warning {{made available}} +struct __is_final {}; // expected-warning {{made available}} +struct __is_function {}; // expected-warning {{made available}} +struct __is_fundamental {}; // expected-warning {{made available}} +struct __is_integral {}; // expected-warning {{made available}} +struct __is_interface_class {}; // expected-warning {{made available}} +struct __is_literal {}; // expected-warning {{made available}} +struct __is_lvalue_expr {}; // expected-warning {{made available}} +struct __is_lvalue_reference {}; // expected-warning {{made available}} +struct __is_member_function_pointer {}; // expected-warning {{made available}} +struct __is_member_object_pointer {}; // expected-warning {{made available}} +struct __is_member_pointer {}; // expected-warning {{made available}} +struct __is_nothrow_assignable {}; // expected-warning {{made available}} +struct __is_nothrow_constructible {}; // expected-warning {{made available}} +struct __is_nothrow_destructible {}; // expected-warning {{made available}} +struct __is_object {}; // expected-warning {{made available}} +struct __is_pointer {}; // expected-warning {{made available}} +struct __is_polymorphic {}; // expected-warning {{made available}} +struct __is_reference {}; // expected-warning {{made available}} +struct __is_rvalue_expr {}; // expected-warning {{made available}} +struct __is_rvalue_reference {}; // expected-warning {{made available}} +struct __is_same {}; // expected-warning {{made available}} +struct __is_scalar {}; // expected-warning {{made available}} +struct __is_sealed {}; // expected-warning {{made available}} +struct __is_signed {}; // expected-warning {{made available}} +struct __is_standard_layout {}; // expected-warning {{made available}} +struct __is_trivial {}; // expected-warning {{made available}} +struct __is_trivially_assignable {}; // expected-warning {{made available}} +struct __is_trivially_constructible {}; // expected-warning {{made available}} +struct __is_trivially_copyable {}; // expected-warning {{made available}} +struct __is_union {}; // expected-warning {{made available}} +struct __is_unsigned {}; // expected-warning {{made available}} +struct __is_void {}; // expected-warning {{made available}} +struct __is_volatile {}; // expected-warning {{made available}} + + }