diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-24 07:38:34 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-24 07:38:34 +0000 |
commit | 4ca8ac2e61c37ddadf37024af86f3e1019af8532 (patch) | |
tree | eaded653632e9c6319917df7f2fa190fb5cf1751 /lib/Parse/ParseExprCXX.cpp | |
parent | 59950d3aa54ca5066b1fb08a8c79ebfe10e0919b (diff) |
Implement a new type trait __is_trivially_constructible(T, Args...)
that provides the behavior of the C++11 library trait
std::is_trivially_constructible<T, Args...>, which can't be
implemented purely as a library.
Since __is_trivially_constructible can have zero or more arguments, I
needed to add Yet Another Type Trait Expression Class, this one
handling arbitrary arguments. The next step will be to migrate
UnaryTypeTrait and BinaryTypeTrait over to this new, more general
TypeTrait class.
Fixes the Clang side of <rdar://problem/10895483> / PR12038.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151352 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 19bc22020c..d8663077fd 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -2458,6 +2458,14 @@ static BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) { } } +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; + } +} + static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) { switch(kind) { default: llvm_unreachable("Not a known binary type trait"); @@ -2540,6 +2548,58 @@ ExprResult Parser::ParseBinaryTypeTrait() { T.getCloseLocation()); } +/// \brief Parse the built-in type-trait pseudo-functions that allow +/// implementation of the TR1/C++11 type traits templates. +/// +/// primary-expression: +/// type-trait '(' type-id-seq ')' +/// +/// type-id-seq: +/// type-id ...[opt] type-id-seq[opt] +/// +ExprResult Parser::ParseTypeTrait() { + TypeTrait Kind = TypeTraitFromTokKind(Tok.getKind()); + SourceLocation Loc = ConsumeToken(); + + BalancedDelimiterTracker Parens(*this, tok::l_paren); + if (Parens.expectAndConsume(diag::err_expected_lparen)) + return ExprError(); + + llvm::SmallVector<ParsedType, 2> Args; + do { + // Parse the next type. + TypeResult Ty = ParseTypeName(); + if (Ty.isInvalid()) { + Parens.skipToEnd(); + return ExprError(); + } + + // Parse the ellipsis, if present. + if (Tok.is(tok::ellipsis)) { + Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken()); + if (Ty.isInvalid()) { + Parens.skipToEnd(); + return ExprError(); + } + } + + // Add this type to the list of arguments. + Args.push_back(Ty.get()); + + if (Tok.is(tok::comma)) { + ConsumeToken(); + continue; + } + + break; + } while (true); + + if (Parens.consumeClose()) + return ExprError(); + + return Actions.ActOnTypeTrait(Kind, Loc, Args, Parens.getCloseLocation()); +} + /// ParseArrayTypeTrait - Parse the built-in array type-trait /// pseudo-functions. /// |