diff options
Diffstat (limited to 'clang/lib/Parse/ParseExprCXX.cpp')
| -rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 170 |
1 files changed, 46 insertions, 124 deletions
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 |

