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