r197496 - Simplify RevertibleTypeTraits as a form of contextual keyword
Nico Weber
thakis at chromium.org
Mon Sep 22 21:21:55 PDT 2014
Hi Alp,
this broke loading REVERTIBLE_TYPE_TRAITs from PCH files, PR21036. It
wasn't obvious to me how to fix this (ASTIdentifierLookupTrait::ReadData in
ASTReader.cpp would have to write to ContextualKeywords
when HasRevertedTokenIDToIdentifier is set from what I understand, but it's
not clear how to get to the Parser from there), so I reverted this in
r218292 for now.
Nico
On Tue, Dec 17, 2013 at 6:12 AM, Alp Toker <alp at nuanti.com> wrote:
> Author: alp
> Date: Tue Dec 17 08:12:30 2013
> New Revision: 197496
>
> URL: http://llvm.org/viewvc/llvm-project?rev=197496&view=rev
> Log:
> Simplify RevertibleTypeTraits as a form of contextual keyword
>
> Now that we emit diagnostics for keyword-as-identifier hacks
> (-Wkeyword-compat)
> we can go ahead and simplify some of the old revertible keyword support.
>
> This commit adds a TryIdentKeywordUpgrade() function to mirror the recently
> added TryKeywordIdentFallback() and uses it to replace the hard-coded list
> of
> REVERTIBLE_TYPE_TRAITs.
>
> Modified:
> cfe/trunk/include/clang/Parse/Parser.h
> cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> cfe/trunk/lib/Parse/ParseExpr.cpp
> cfe/trunk/lib/Parse/Parser.cpp
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=197496&r1=197495&r2=197496&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Tue Dec 17 08:12:30 2013
> @@ -136,9 +136,10 @@ class Parser : public CodeCompletionHand
> mutable IdentifierInfo *Ident_final;
> mutable IdentifierInfo *Ident_override;
>
> - // C++ type trait keywords that can be reverted to identifiers and
> still be
> - // used as type traits.
> - llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>
> RevertibleTypeTraits;
> + // Some token kinds such as C++ type traits can be reverted to
> identifiers and
> + // still get used as keywords depending on context.
> + llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>
> + ContextualKeywords;
>
> OwningPtr<PragmaHandler> AlignHandler;
> OwningPtr<PragmaHandler> GCCVisibilityHandler;
> @@ -574,6 +575,12 @@ private:
> /// otherwise emits a diagnostic and returns true.
> bool TryKeywordIdentFallback(bool DisableKeyword);
>
> + /// TryIdentKeywordUpgrade - Convert the current identifier token back
> to
> + /// its original kind and return true if it was disabled by
> + /// TryKeywordIdentFallback(), otherwise return false. Use this to
> + /// contextually enable keywords.
> + bool TryIdentKeywordUpgrade();
> +
> /// \brief Get the TemplateIdAnnotation from the token.
> TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
>
>
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=197496&r1=197495&r2=197496&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Dec 17 08:12:30 2013
> @@ -1180,31 +1180,17 @@ void Parser::ParseClassSpecifier(tok::To
> // C++11 attributes
> SourceLocation AttrFixitLoc = Tok.getLocation();
>
> - if (TagType == DeclSpec::TST_struct &&
> - !Tok.is(tok::identifier) &&
> - Tok.getIdentifierInfo() &&
> - (Tok.is(tok::kw___is_arithmetic) ||
> - Tok.is(tok::kw___is_convertible) ||
> - Tok.is(tok::kw___is_empty) ||
> - Tok.is(tok::kw___is_floating_point) ||
> - Tok.is(tok::kw___is_function) ||
> - Tok.is(tok::kw___is_fundamental) ||
> - Tok.is(tok::kw___is_integral) ||
> - Tok.is(tok::kw___is_member_function_pointer) ||
> - Tok.is(tok::kw___is_member_pointer) ||
> - Tok.is(tok::kw___is_pod) ||
> - Tok.is(tok::kw___is_pointer) ||
> - Tok.is(tok::kw___is_same) ||
> - Tok.is(tok::kw___is_scalar) ||
> - Tok.is(tok::kw___is_signed) ||
> - Tok.is(tok::kw___is_unsigned) ||
> - Tok.is(tok::kw___is_void)))
> - // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
> - // name of struct templates, but some are keywords in GCC >= 4.3
> - // and Clang. Therefore, when we see the token sequence "struct
> - // X", make X into a normal identifier rather than a keyword, to
> - // allow libstdc++ 4.2 and libc++ to work properly.
> - TryKeywordIdentFallback(true);
> + // GNU libstdc++ and libc++ use certain intrinsic names as the
> + // name of struct templates, but some are keywords in GCC >= 4.3
> + // MSVC and Clang. For compatibility, convert the token to an identifier
> + // and issue a warning diagnostic.
> + if (TagType == DeclSpec::TST_struct && !Tok.is(tok::identifier) &&
> + !Tok.isAnnotation()) {
> + const IdentifierInfo *II = Tok.getIdentifierInfo();
> + // We rarely end up here so the following check is efficient.
> + if (II && II->getName().startswith("__is_"))
> + TryKeywordIdentFallback(true);
> + }
>
> // Parse the (optional) nested-name-specifier.
> CXXScopeSpec &SS = DS.getTypeSpecScope();
>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=197496&r1=197495&r2=197496&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Dec 17 08:12:30 2013
> @@ -715,48 +715,11 @@ ExprResult Parser::ParseCastExpression(b
> // 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 revertible type traits, for future use.
> - if (RevertibleTypeTraits.empty()) {
> -#define RTT_JOIN(X,Y) X##Y
> -#define REVERTIBLE_TYPE_TRAIT(Name) \
> - RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \
> - = RTT_JOIN(tok::kw_,Name)
> -
> - REVERTIBLE_TYPE_TRAIT(__is_arithmetic);
> - REVERTIBLE_TYPE_TRAIT(__is_convertible);
> - REVERTIBLE_TYPE_TRAIT(__is_empty);
> - REVERTIBLE_TYPE_TRAIT(__is_floating_point);
> - REVERTIBLE_TYPE_TRAIT(__is_function);
> - REVERTIBLE_TYPE_TRAIT(__is_fundamental);
> - REVERTIBLE_TYPE_TRAIT(__is_integral);
> - REVERTIBLE_TYPE_TRAIT(__is_member_function_pointer);
> - REVERTIBLE_TYPE_TRAIT(__is_member_pointer);
> - REVERTIBLE_TYPE_TRAIT(__is_pod);
> - REVERTIBLE_TYPE_TRAIT(__is_pointer);
> - REVERTIBLE_TYPE_TRAIT(__is_same);
> - REVERTIBLE_TYPE_TRAIT(__is_scalar);
> - REVERTIBLE_TYPE_TRAIT(__is_signed);
> - REVERTIBLE_TYPE_TRAIT(__is_unsigned);
> - REVERTIBLE_TYPE_TRAIT(__is_void);
> -#undef REVERTIBLE_TYPE_TRAIT
> -#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
> - = RevertibleTypeTraits.find(II);
> - if (Known != RevertibleTypeTraits.end()) {
> - Tok.setKind(Known->second);
> - return ParseCastExpression(isUnaryExpression,
> isAddressOfOperand,
> - NotCastExpr, isTypeCast);
> - }
> - }
> + if (Next.is(tok::l_paren) && Tok.is(tok::identifier) &&
> + Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
> + TryIdentKeywordUpgrade())
> + return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
> + NotCastExpr, isTypeCast);
>
> if (Next.is(tok::coloncolon) ||
> (!ColonIsSacred && Next.is(tok::colon)) ||
>
> Modified: cfe/trunk/lib/Parse/Parser.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=197496&r1=197495&r2=197496&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/Parser.cpp (original)
> +++ cfe/trunk/lib/Parse/Parser.cpp Tue Dec 17 08:12:30 2013
> @@ -1517,16 +1517,34 @@ Parser::TryAnnotateName(bool IsAddressOf
> }
>
> bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
> - assert(Tok.isNot(tok::identifier));
> + assert(!Tok.is(tok::identifier) && !Tok.isAnnotation());
> Diag(Tok, diag::ext_keyword_as_ident)
> << PP.getSpelling(Tok)
> << DisableKeyword;
> - if (DisableKeyword)
> - Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
> + if (DisableKeyword) {
> + IdentifierInfo *II = Tok.getIdentifierInfo();
> + ContextualKeywords[II] = Tok.getKind();
> + II->RevertTokenIDToIdentifier();
> + }
> Tok.setKind(tok::identifier);
> return true;
> }
>
> +bool Parser::TryIdentKeywordUpgrade() {
> + assert(Tok.is(tok::identifier));
> + const IdentifierInfo *II = Tok.getIdentifierInfo();
> + assert(II->hasRevertedTokenIDToIdentifier());
> + // 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<const IdentifierInfo *, tok::TokenKind>::iterator
> Known =
> + ContextualKeywords.find(II);
> + if (Known == ContextualKeywords.end())
> + return false;
> + Tok.setKind(Known->second);
> + return true;
> +}
> +
> /// TryAnnotateTypeOrScopeToken - If the current token position is on a
> /// typename (possibly qualified in C++) or a C++ scope specifier not
> followed
> /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more
> tokens
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140922/84d3d2e2/attachment.html>
More information about the cfe-commits
mailing list