diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-08-30 20:04:43 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-08-30 20:04:43 +0000 |
commit | 8bea83a866a799b10cff49cb46ac0a3b44c6eb03 (patch) | |
tree | 3ed31a59cec0a617e986024d632d6c5af37b5859 /clang/lib/Parse/ParseExpr.cpp | |
parent | fdf98763ace73b27a3a3a4200bef04b86a0f7b4e (diff) | |
download | bcm5719-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.cpp | 51 |
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()) || |