diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 63 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 62 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 170 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 30 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 6 |
5 files changed, 62 insertions, 269 deletions
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index abbc3d89aaa..7f9e98a904b 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1684,72 +1684,27 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { static const char *getTypeTraitName(UnaryTypeTrait UTT) { switch (UTT) { - case UTT_HasNothrowAssign: return "__has_nothrow_assign"; - case UTT_HasNothrowMoveAssign: return "__has_nothrow_move_assign"; - case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; - case UTT_HasNothrowCopy: return "__has_nothrow_copy"; - case UTT_HasTrivialAssign: return "__has_trivial_assign"; - case UTT_HasTrivialMoveAssign: return "__has_trivial_move_assign"; - case UTT_HasTrivialMoveConstructor: return "__has_trivial_move_constructor"; - case UTT_HasTrivialDefaultConstructor: return "__has_trivial_constructor"; - case UTT_HasTrivialCopy: return "__has_trivial_copy"; - case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; - case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; - case UTT_IsAbstract: return "__is_abstract"; - case UTT_IsArithmetic: return "__is_arithmetic"; - case UTT_IsArray: return "__is_array"; - case UTT_IsClass: return "__is_class"; - case UTT_IsCompleteType: return "__is_complete_type"; - case UTT_IsCompound: return "__is_compound"; - case UTT_IsConst: return "__is_const"; - case UTT_IsEmpty: return "__is_empty"; - case UTT_IsEnum: return "__is_enum"; - case UTT_IsFinal: return "__is_final"; - case UTT_IsFloatingPoint: return "__is_floating_point"; - case UTT_IsFunction: return "__is_function"; - case UTT_IsFundamental: return "__is_fundamental"; - case UTT_IsIntegral: return "__is_integral"; - case UTT_IsInterfaceClass: return "__is_interface_class"; - case UTT_IsLiteral: return "__is_literal"; - case UTT_IsLvalueReference: return "__is_lvalue_reference"; - case UTT_IsMemberFunctionPointer: return "__is_member_function_pointer"; - case UTT_IsMemberObjectPointer: return "__is_member_object_pointer"; - case UTT_IsMemberPointer: return "__is_member_pointer"; - case UTT_IsObject: return "__is_object"; - case UTT_IsPOD: return "__is_pod"; - case UTT_IsPointer: return "__is_pointer"; - case UTT_IsPolymorphic: return "__is_polymorphic"; - case UTT_IsReference: return "__is_reference"; - case UTT_IsRvalueReference: return "__is_rvalue_reference"; - case UTT_IsScalar: return "__is_scalar"; - case UTT_IsSealed: return "__is_sealed"; - case UTT_IsSigned: return "__is_signed"; - case UTT_IsStandardLayout: return "__is_standard_layout"; - case UTT_IsTrivial: return "__is_trivial"; - case UTT_IsTriviallyCopyable: return "__is_trivially_copyable"; - case UTT_IsUnion: return "__is_union"; - case UTT_IsUnsigned: return "__is_unsigned"; - case UTT_IsVoid: return "__is_void"; - case UTT_IsVolatile: return "__is_volatile"; +#define TYPE_TRAIT_1(Spelling, Name, Key) \ + case clang::UTT_##Name: return #Spelling; +#include "clang/Basic/TokenKinds.def" } llvm_unreachable("Type trait not covered by switch statement"); } static const char *getTypeTraitName(BinaryTypeTrait BTT) { switch (BTT) { - case BTT_IsBaseOf: return "__is_base_of"; - case BTT_IsConvertible: return "__is_convertible"; - case BTT_IsSame: return "__is_same"; - case BTT_TypeCompatible: return "__builtin_types_compatible_p"; - case BTT_IsConvertibleTo: return "__is_convertible_to"; - case BTT_IsTriviallyAssignable: return "__is_trivially_assignable"; +#define TYPE_TRAIT_2(Spelling, Name, Key) \ + case clang::BTT_##Name: return #Spelling; +#include "clang/Basic/TokenKinds.def" } llvm_unreachable("Binary type trait not covered by switch"); } static const char *getTypeTraitName(TypeTrait TT) { switch (TT) { - case clang::TT_IsTriviallyConstructible:return "__is_trivially_constructible"; +#define TYPE_TRAIT_N(Spelling, Name, Key) \ + case clang::TT_##Name: return #Spelling; +#include "clang/Basic/TokenKinds.def" } llvm_unreachable("Type trait not covered by switch"); } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index f9885905a98..8fb0660b347 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1168,65 +1168,9 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, return Result; } - case tok::kw___is_abstract: // [GNU] unary-type-trait - case tok::kw___is_class: - case tok::kw___is_empty: - case tok::kw___is_enum: - case tok::kw___is_interface_class: - case tok::kw___is_literal: - case tok::kw___is_arithmetic: - case tok::kw___is_integral: - case tok::kw___is_floating_point: - case tok::kw___is_complete_type: - case tok::kw___is_void: - case tok::kw___is_array: - case tok::kw___is_function: - case tok::kw___is_reference: - case tok::kw___is_lvalue_reference: - case tok::kw___is_rvalue_reference: - case tok::kw___is_fundamental: - case tok::kw___is_object: - case tok::kw___is_scalar: - case tok::kw___is_compound: - case tok::kw___is_pointer: - case tok::kw___is_member_object_pointer: - case tok::kw___is_member_function_pointer: - case tok::kw___is_member_pointer: - case tok::kw___is_const: - case tok::kw___is_volatile: - case tok::kw___is_standard_layout: - case tok::kw___is_signed: - case tok::kw___is_unsigned: - case tok::kw___is_literal_type: - case tok::kw___is_pod: - case tok::kw___is_polymorphic: - case tok::kw___is_trivial: - case tok::kw___is_trivially_copyable: - case tok::kw___is_union: - case tok::kw___is_final: - case tok::kw___is_sealed: - case tok::kw___has_trivial_constructor: - case tok::kw___has_trivial_move_constructor: - case tok::kw___has_trivial_copy: - case tok::kw___has_trivial_assign: - case tok::kw___has_trivial_move_assign: - case tok::kw___has_trivial_destructor: - case tok::kw___has_nothrow_assign: - case tok::kw___has_nothrow_move_assign: - case tok::kw___has_nothrow_copy: - case tok::kw___has_nothrow_constructor: - case tok::kw___has_virtual_destructor: - return ParseUnaryTypeTrait(); - - case tok::kw___builtin_types_compatible_p: - case tok::kw___is_base_of: - case tok::kw___is_same: - case tok::kw___is_convertible: - case tok::kw___is_convertible_to: - case tok::kw___is_trivially_assignable: - return ParseBinaryTypeTrait(); - - case tok::kw___is_trivially_constructible: +#define TYPE_TRAIT(N,Spelling,K) \ + case tok::kw_##Spelling: +#include "clang/Basic/TokenKinds.def" return ParseTypeTrait(); case tok::kw___array_rank: diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 3f6d36c8b8d..846995e0ceb 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2687,76 +2687,27 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { switch(kind) { default: llvm_unreachable("Not a known unary type trait."); - case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; - case tok::kw___has_nothrow_move_assign: return UTT_HasNothrowMoveAssign; - case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; - case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; - case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; - case tok::kw___has_trivial_move_assign: return UTT_HasTrivialMoveAssign; - case tok::kw___has_trivial_constructor: - return UTT_HasTrivialDefaultConstructor; - case tok::kw___has_trivial_move_constructor: - return UTT_HasTrivialMoveConstructor; - case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; - case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; - case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; - case tok::kw___is_abstract: return UTT_IsAbstract; - case tok::kw___is_arithmetic: return UTT_IsArithmetic; - case tok::kw___is_array: return UTT_IsArray; - case tok::kw___is_class: return UTT_IsClass; - case tok::kw___is_complete_type: return UTT_IsCompleteType; - case tok::kw___is_compound: return UTT_IsCompound; - case tok::kw___is_const: return UTT_IsConst; - case tok::kw___is_empty: return UTT_IsEmpty; - case tok::kw___is_enum: return UTT_IsEnum; - case tok::kw___is_final: return UTT_IsFinal; - case tok::kw___is_floating_point: return UTT_IsFloatingPoint; - case tok::kw___is_function: return UTT_IsFunction; - case tok::kw___is_fundamental: return UTT_IsFundamental; - case tok::kw___is_integral: return UTT_IsIntegral; - case tok::kw___is_interface_class: return UTT_IsInterfaceClass; - case tok::kw___is_lvalue_reference: return UTT_IsLvalueReference; - case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer; - case tok::kw___is_member_object_pointer: return UTT_IsMemberObjectPointer; - case tok::kw___is_member_pointer: return UTT_IsMemberPointer; - case tok::kw___is_object: return UTT_IsObject; - case tok::kw___is_literal: return UTT_IsLiteral; - case tok::kw___is_literal_type: return UTT_IsLiteral; - case tok::kw___is_pod: return UTT_IsPOD; - case tok::kw___is_pointer: return UTT_IsPointer; - case tok::kw___is_polymorphic: return UTT_IsPolymorphic; - case tok::kw___is_reference: return UTT_IsReference; - case tok::kw___is_rvalue_reference: return UTT_IsRvalueReference; - case tok::kw___is_scalar: return UTT_IsScalar; - case tok::kw___is_sealed: return UTT_IsSealed; - case tok::kw___is_signed: return UTT_IsSigned; - case tok::kw___is_standard_layout: return UTT_IsStandardLayout; - case tok::kw___is_trivial: return UTT_IsTrivial; - case tok::kw___is_trivially_copyable: return UTT_IsTriviallyCopyable; - case tok::kw___is_union: return UTT_IsUnion; - case tok::kw___is_unsigned: return UTT_IsUnsigned; - case tok::kw___is_void: return UTT_IsVoid; - case tok::kw___is_volatile: return UTT_IsVolatile; +#define TYPE_TRAIT_1(Spelling, Name, Key) \ + case tok::kw_ ## Spelling: return UTT_ ## Name; +#include "clang/Basic/TokenKinds.def" } } static BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) { switch(kind) { default: llvm_unreachable("Not a known binary type trait"); - case tok::kw___is_base_of: return BTT_IsBaseOf; - case tok::kw___is_convertible: return BTT_IsConvertible; - case tok::kw___is_same: return BTT_IsSame; - case tok::kw___builtin_types_compatible_p: return BTT_TypeCompatible; - case tok::kw___is_convertible_to: return BTT_IsConvertibleTo; - case tok::kw___is_trivially_assignable: return BTT_IsTriviallyAssignable; +#define TYPE_TRAIT_2(Spelling, Name, Key) \ + case tok::kw_ ## Spelling: return BTT_ ## Name; +#include "clang/Basic/TokenKinds.def" } } static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) { switch (kind) { default: llvm_unreachable("Not a known type trait"); - case tok::kw___is_trivially_constructible: - return TT_IsTriviallyConstructible; +#define TYPE_TRAIT_N(Spelling, Name, Key) \ + case tok::kw_ ## Spelling: return TT_ ## Name; +#include "clang/Basic/TokenKinds.def" } } @@ -2776,83 +2727,29 @@ static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) { } } -/// ParseUnaryTypeTrait - Parse the built-in unary type-trait -/// pseudo-functions that allow implementation of the TR1/C++0x type traits -/// templates. -/// -/// primary-expression: -/// [GNU] unary-type-trait '(' type-id ')' -/// -ExprResult Parser::ParseUnaryTypeTrait() { - UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); - SourceLocation Loc = ConsumeToken(); - - BalancedDelimiterTracker T(*this, tok::l_paren); - if (T.expectAndConsume(diag::err_expected_lparen)) - return ExprError(); - - // FIXME: Error reporting absolutely sucks! If the this fails to parse a type - // there will be cryptic errors about mismatched parentheses and missing - // specifiers. - TypeResult Ty = ParseTypeName(); - - T.consumeClose(); - - if (Ty.isInvalid()) - return ExprError(); - - return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), T.getCloseLocation()); -} - -/// ParseBinaryTypeTrait - Parse the built-in binary type-trait -/// pseudo-functions that allow implementation of the TR1/C++0x type traits -/// templates. -/// -/// primary-expression: -/// [GNU] binary-type-trait '(' type-id ',' type-id ')' -/// -ExprResult Parser::ParseBinaryTypeTrait() { - BinaryTypeTrait BTT = BinaryTypeTraitFromTokKind(Tok.getKind()); - SourceLocation Loc = ConsumeToken(); - - BalancedDelimiterTracker T(*this, tok::l_paren); - if (T.expectAndConsume(diag::err_expected_lparen)) - return ExprError(); - - TypeResult LhsTy = ParseTypeName(); - if (LhsTy.isInvalid()) { - SkipUntil(tok::r_paren, StopAtSemi); - return ExprError(); - } - - if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { - SkipUntil(tok::r_paren, StopAtSemi); - return ExprError(); - } - - TypeResult RhsTy = ParseTypeName(); - if (RhsTy.isInvalid()) { - SkipUntil(tok::r_paren, StopAtSemi); - return ExprError(); +static unsigned TypeTraitArity(tok::TokenKind kind) { + switch (kind) { + default: llvm_unreachable("Not a known type trait"); +#define TYPE_TRAIT(N,Spelling,K) case tok::kw_##Spelling: return N; +#include "clang/Basic/TokenKinds.def" } - - T.consumeClose(); - - return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), - T.getCloseLocation()); } /// \brief Parse the built-in type-trait pseudo-functions that allow /// implementation of the TR1/C++11 type traits templates. /// /// primary-expression: +/// unary-type-trait '(' type-id ')' +/// binary-type-trait '(' type-id ',' type-id ')' /// type-trait '(' type-id-seq ')' /// /// type-id-seq: /// type-id ...[opt] type-id-seq[opt] /// ExprResult Parser::ParseTypeTrait() { - TypeTrait Kind = TypeTraitFromTokKind(Tok.getKind()); + tok::TokenKind Kind = Tok.getKind(); + unsigned Arity = TypeTraitArity(Kind); + SourceLocation Loc = ConsumeToken(); BalancedDelimiterTracker Parens(*this, tok::l_paren); @@ -2890,8 +2787,33 @@ ExprResult Parser::ParseTypeTrait() { if (Parens.consumeClose()) return ExprError(); - - return Actions.ActOnTypeTrait(Kind, Loc, Args, Parens.getCloseLocation()); + + SourceLocation EndLoc = Parens.getCloseLocation(); + + if (Arity && Args.size() != Arity) { + Diag(EndLoc, diag::err_type_trait_arity) + << Arity << 0 << (Arity > 1) << (int)Args.size() << SourceRange(Loc); + return ExprError(); + } + + if (!Arity && Args.empty()) { + Diag(EndLoc, diag::err_type_trait_arity) + << 1 << 1 << 1 << (int)Args.size() << SourceRange(Loc); + return ExprError(); + } + + if (Arity == 1) + return Actions.ActOnUnaryTypeTrait(UnaryTypeTraitFromTokKind(Kind), Loc, + Args[0], EndLoc); + if (Arity == 2) + return Actions.ActOnBinaryTypeTrait(BinaryTypeTraitFromTokKind(Kind), Loc, + Args[0], Args[1], EndLoc); + if (!Arity) + return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, + EndLoc); + + llvm_unreachable("unhandled type trait rank"); + return ExprError(); } /// ParseArrayTypeTrait - Parse the built-in array type-trait diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index a1d6b13fdab..59118b0fd3f 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -935,7 +935,6 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { case tok::kw___alignof: case tok::kw___builtin_choose_expr: case tok::kw___builtin_offsetof: - case tok::kw___builtin_types_compatible_p: case tok::kw___builtin_va_arg: case tok::kw___imag: case tok::kw___real: @@ -943,33 +942,10 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { case tok::kw___FUNCDNAME__: case tok::kw_L__FUNCTION__: case tok::kw___PRETTY_FUNCTION__: - case tok::kw___has_nothrow_assign: - case tok::kw___has_nothrow_copy: - case tok::kw___has_nothrow_constructor: - case tok::kw___has_trivial_assign: - case tok::kw___has_trivial_copy: - case tok::kw___has_trivial_constructor: - case tok::kw___has_trivial_destructor: - case tok::kw___has_virtual_destructor: - case tok::kw___is_abstract: - case tok::kw___is_base_of: - case tok::kw___is_class: - case tok::kw___is_convertible_to: - case tok::kw___is_empty: - case tok::kw___is_enum: - case tok::kw___is_interface_class: - case tok::kw___is_final: - case tok::kw___is_literal: - case tok::kw___is_literal_type: - case tok::kw___is_pod: - case tok::kw___is_polymorphic: - case tok::kw___is_sealed: - case tok::kw___is_trivial: - case tok::kw___is_trivially_assignable: - case tok::kw___is_trivially_constructible: - case tok::kw___is_trivially_copyable: - case tok::kw___is_union: case tok::kw___uuidof: +#define TYPE_TRAIT(N,Spelling,K) \ + case tok::kw_##Spelling: +#include "clang/Basic/TokenKinds.def" return TPResult::True(); // Obviously starts a type-specifier-seq: diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 04871d367e8..2c9eb63f150 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3650,11 +3650,7 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, // variable t: // // T t(create<Args>()...); - if (Args.empty()) { - S.Diag(KWLoc, diag::err_type_trait_arity) - << 1 << 1 << 1 << (int)Args.size(); - return false; - } + assert(!Args.empty()); // Precondition: T and all types in the parameter pack Args shall be // complete types, (possibly cv-qualified) void, or arrays of |