[cfe-commits] r162937 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Lex/PPMacroExpansion.cpp lib/Parse/ParseExpr.cpp test/SemaCXX/libstdcxx_is_pod_hack.cpp
Douglas Gregor
dgregor at apple.com
Thu Aug 30 23:25:41 PDT 2012
Sent from my iPhone
On Aug 30, 2012, at 6:11 PM, Sean Silva <silvas at purdue.edu> wrote:
> +#define RTT_JOIN2(X) X
> [...]
> +#undef RTT_JOIN2
>
> Is this a leftover from a previous iteration of the change?
Yes. I'm AFK for a few days and won't be able to clean up my droppings.
> --Sean Silva
>
> On Thu, Aug 30, 2012 at 4:04 PM, Douglas Gregor <dgregor at apple.com> wrote:
>> Author: dgregor
>> Date: Thu Aug 30 15:04:43 2012
>> New Revision: 162937
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=162937&view=rev
>> Log:
>> 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.
>>
>> Modified:
>> cfe/trunk/include/clang/Parse/Parser.h
>> cfe/trunk/lib/Lex/PPMacroExpansion.cpp
>> cfe/trunk/lib/Parse/ParseExpr.cpp
>> cfe/trunk/test/SemaCXX/libstdcxx_is_pod_hack.cpp
>>
>> Modified: cfe/trunk/include/clang/Parse/Parser.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=162937&r1=162936&r2=162937&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Parse/Parser.h (original)
>> +++ cfe/trunk/include/clang/Parse/Parser.h Thu Aug 30 15:04:43 2012
>> @@ -164,6 +164,10 @@
>> mutable IdentifierInfo *Ident_final;
>> mutable IdentifierInfo *Ident_override;
>>
>> + // C++ type trait keywords that have can be reverted to identifiers and
>> + // still used as type traits.
>> + llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertableTypeTraits;
>> +
>> OwningPtr<PragmaHandler> AlignHandler;
>> OwningPtr<PragmaHandler> GCCVisibilityHandler;
>> OwningPtr<PragmaHandler> OptionsHandler;
>>
>> Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=162937&r1=162936&r2=162937&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
>> +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Aug 30 15:04:43 2012
>> @@ -719,22 +719,12 @@
>> // "struct __is_empty" parsing hack hasn't been needed in this
>> // translation unit. If it has, __is_empty reverts to a normal
>> // identifier and __has_feature(is_empty) evaluates false.
>> - .Case("is_empty",
>> - LangOpts.CPlusPlus &&
>> - PP.getIdentifierInfo("__is_empty")->getTokenID()
>> - != tok::identifier)
>> + .Case("is_empty", LangOpts.CPlusPlus)
>> .Case("is_enum", LangOpts.CPlusPlus)
>> .Case("is_final", LangOpts.CPlusPlus)
>> .Case("is_literal", LangOpts.CPlusPlus)
>> .Case("is_standard_layout", LangOpts.CPlusPlus)
>> - // __is_pod is available only if the horrible
>> - // "struct __is_pod" parsing hack hasn't been needed in this
>> - // translation unit. If it has, __is_pod reverts to a normal
>> - // identifier and __has_feature(is_pod) evaluates false.
>> - .Case("is_pod",
>> - LangOpts.CPlusPlus &&
>> - PP.getIdentifierInfo("__is_pod")->getTokenID()
>> - != tok::identifier)
>> + .Case("is_pod", LangOpts.CPlusPlus)
>> .Case("is_polymorphic", LangOpts.CPlusPlus)
>> .Case("is_trivial", LangOpts.CPlusPlus)
>> .Case("is_trivially_assignable", LangOpts.CPlusPlus)
>>
>> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=162937&r1=162936&r2=162937&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Thu Aug 30 15:04:43 2012
>> @@ -741,6 +741,55 @@
>> // 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 @@
>> // '.'.
>> 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()) ||
>>
>> Modified: cfe/trunk/test/SemaCXX/libstdcxx_is_pod_hack.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/libstdcxx_is_pod_hack.cpp?rev=162937&r1=162936&r2=162937&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/libstdcxx_is_pod_hack.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/libstdcxx_is_pod_hack.cpp Thu Aug 30 15:04:43 2012
>> @@ -8,6 +8,7 @@
>>
>> template<typename T>
>> struct __is_pod {
>> + __is_pod() {}
>> };
>>
>> __is_pod<int> ipi;
>> @@ -28,6 +29,13 @@
>>
>> bool check_signed = test_is_signed::__is_signed;
>>
>> -#if __has_feature(is_pod)
>> -# error __is_pod won't work now anyway
>> +template<bool B> struct must_be_true {};
>> +template<> struct must_be_true<false>;
>> +
>> +void foo() {
>> + bool b = __is_pod(int);
>> + must_be_true<__is_pod(int)> mbt;
>> +}
>> +#if !__has_feature(is_pod)
>> +# error __is_pod should still be available.
>> #endif
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list