summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-08-30 20:04:43 +0000
committerDouglas Gregor <dgregor@apple.com>2012-08-30 20:04:43 +0000
commit8bea83a866a799b10cff49cb46ac0a3b44c6eb03 (patch)
tree3ed31a59cec0a617e986024d632d6c5af37b5859 /clang/lib/Parse/ParseExpr.cpp
parentfdf98763ace73b27a3a3a4200bef04b86a0f7b4e (diff)
downloadbcm5719-llvm-8bea83a866a799b10cff49cb46ac0a3b44c6eb03.tar.gz
bcm5719-llvm-8bea83a866a799b10cff49cb46ac0a3b44c6eb03.zip
Extend the "__is_pod" hack, which demotes various type trait keywords
(__is_pod, __is_signed, etc.) to normal identifiers if they are encountered in certain places in the grammar where we know that prior versions of libstdc++ or libc++ use them, to still allow the use of these keywords as type traits. Fixes <rdar://problem/9836262> and PR10184. llvm-svn: 162937
Diffstat (limited to 'clang/lib/Parse/ParseExpr.cpp')
-rw-r--r--clang/lib/Parse/ParseExpr.cpp51
1 files changed, 50 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 8df08b81849..855861380da 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -741,6 +741,55 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// Avoid the unnecessary parse-time lookup in the common case
// where the syntax forbids a type.
const Token &Next = NextToken();
+
+ // If this identifier was reverted from a token ID, and the next token
+ // is a parenthesis, this is likely to be a use of a type trait. Check
+ // those tokens.
+ if (Next.is(tok::l_paren) &&
+ Tok.is(tok::identifier) &&
+ Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+ // Build up the mapping of revertable type traits, for future use.
+ if (RevertableTypeTraits.empty()) {
+#define RTT_JOIN2(X) X
+#define RTT_JOIN(X,Y) X##Y
+#define REVERTABLE_TYPE_TRAIT(Name) \
+ RevertableTypeTraits[PP.getIdentifierInfo(#Name)] \
+ = RTT_JOIN(tok::kw_,Name)
+
+ REVERTABLE_TYPE_TRAIT(__is_arithmetic);
+ REVERTABLE_TYPE_TRAIT(__is_convertible);
+ REVERTABLE_TYPE_TRAIT(__is_empty);
+ REVERTABLE_TYPE_TRAIT(__is_floating_point);
+ REVERTABLE_TYPE_TRAIT(__is_function);
+ REVERTABLE_TYPE_TRAIT(__is_fundamental);
+ REVERTABLE_TYPE_TRAIT(__is_integral);
+ REVERTABLE_TYPE_TRAIT(__is_member_function_pointer);
+ REVERTABLE_TYPE_TRAIT(__is_member_pointer);
+ REVERTABLE_TYPE_TRAIT(__is_pod);
+ REVERTABLE_TYPE_TRAIT(__is_pointer);
+ REVERTABLE_TYPE_TRAIT(__is_same);
+ REVERTABLE_TYPE_TRAIT(__is_scalar);
+ REVERTABLE_TYPE_TRAIT(__is_signed);
+ REVERTABLE_TYPE_TRAIT(__is_unsigned);
+ REVERTABLE_TYPE_TRAIT(__is_void);
+#undef REVERTABLE_TYPE_TRAIT
+#undef RTT_JOIN2
+#undef RTT_JOIN
+ }
+
+ // If we find that this is in fact the name of a type trait,
+ // update the token kind in place and parse again to treat it as
+ // the appropriate kind of type trait.
+ llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known
+ = RevertableTypeTraits.find(II);
+ if (Known != RevertableTypeTraits.end()) {
+ Tok.setKind(Known->second);
+ return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
+ NotCastExpr, isTypeCast);
+ }
+ }
+
if (Next.is(tok::coloncolon) ||
(!ColonIsSacred && Next.is(tok::colon)) ||
Next.is(tok::less) ||
@@ -758,7 +807,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// '.'.
IdentifierInfo &II = *Tok.getIdentifierInfo();
SourceLocation ILoc = ConsumeToken();
-
+
// Support 'Class.property' and 'super.property' notation.
if (getLangOpts().ObjC1 && Tok.is(tok::period) &&
(Actions.getTypeName(II, ILoc, getCurScope()) ||
OpenPOWER on IntegriCloud