aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-24 07:38:34 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-24 07:38:34 +0000
commit4ca8ac2e61c37ddadf37024af86f3e1019af8532 (patch)
treeeaded653632e9c6319917df7f2fa190fb5cf1751 /lib/Parse
parent59950d3aa54ca5066b1fb08a8c79ebfe10e0919b (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')
-rw-r--r--lib/Parse/ParseExpr.cpp3
-rw-r--r--lib/Parse/ParseExprCXX.cpp60
-rw-r--r--lib/Parse/ParseTentative.cpp1
3 files changed, 64 insertions, 0 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index fdf40e877c..62d1f494be 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1143,6 +1143,9 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw___is_trivially_assignable:
return ParseBinaryTypeTrait();
+ case tok::kw___is_trivially_constructible:
+ return ParseTypeTrait();
+
case tok::kw___array_rank:
case tok::kw___array_extent:
return ParseArrayTypeTrait();
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.
///
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 011c28aaf7..92ae770fa0 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -690,6 +690,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
case tok::kw___is_polymorphic:
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: