[cfe-dev] [libClang] Determining whether enum is enum class

Alex L via cfe-dev cfe-dev at lists.llvm.org
Thu Jul 6 05:52:33 PDT 2017


I think this kind of addition is acceptable. Your implementation looks
correct.

You should send a patch to the cfe-commits mailing list with the change to
libClang that you are proposing. You can use Phabricator to send the patch
- http://llvm.org/docs/Phabricator.html . You might also find the developer
policy document helpful: http://llvm.org/docs/DeveloperPolicy.html . Don't
forget to include a test case with your patch!

I hope this was helpful,
Alex

On 6 July 2017 at 11:05, Sam Vanheer via cfe-dev <cfe-dev at lists.llvm.org>
wrote:

> I need to determine whether an enum is an enum class.
>
> I found this answer:
> https://stackoverflow.com/questions/26168121/how-do-you-dete
> ct-the-difference-between-an-enum-and-a-scoped-enum-using-libclan
>
> This isn't a suitable solution for code that exclusively uses the
> libClang API.
>
>
> I have come up with a solution that relies on parsing the source code
> surrounding the declaration:
>
> bool IsEnumEnumClass( const CXCursor& cursor )
> {
>      auto TU = clang_getTranslationUnit( cursor );
>
>      CXToken* pTokens = nullptr;
>      unsigned int uiNumTokens = 0;
>
>      clang_tokenize( TU, clang_getCursorExtent( cursor ), &pTokens,
> &uiNumTokens );
>
>      bool bEncounteredEnumKeyword = false;
>
>      bool bIsStronglyScoped = false;
>
>      //Check the declaration until we find an "enum" keyword. If it's
> followed by "class", it's strongly scoped.
>      //Possible input: typedef enum class {} Foo; (typedef is apparently
> ignored, but can't hurt to account for it)
>      for( decltype( uiNumTokens ) uiToken = 0; uiToken < uiNumTokens;
> ++uiToken )
>      {
>          auto spelling = clang::ToStdString( clang_getTokenSpelling( TU,
> pTokens[ uiToken ] ) );
>
>          if( spelling == "enum" )
>          {
>              bEncounteredEnumKeyword = true;
>          }
>          else if( bEncounteredEnumKeyword )
>          {
>              if( spelling == "class" )
>              {
>                  bIsStronglyScoped = true;
>              }
>
>              //No "class" keyword encountered, so it's a weakly scoped
> enum.
>              break;
>          }
>      }
>
>      clang_disposeTokens( TU, pTokens, uiNumTokens );
>
>      return bIsStronglyScoped;
> }
>
>
> clang::ToStdString converts a CXString to std::string.
>
>
> This solution works, but isn't very pretty and may not work properly in
> all cases.
>
> I suppose a new function int clang_isScopedEnum( CXCursor C ) would be
> helpful here, implemented as:
>
> int clang_Cursor_isScopedEnum( CXCursor C )
> {
>      if( clang_getCursorKind( C ) != CXCursor_EnumDecl )
>          return 0;
>
>      if( const EnumDecl *TD = dyn_cast_or_null<EnumDecl>( getCursorDecl(
> C ) ) )
>      {
>          return TD->isScoped();
>      }
>
>      return 0;
> }
>
> I have no experience implementing new features in libClang, and i'd
> rather not break anything. Can anyone assist with such an
> implementation, if it is acceptable?
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170706/569756ab/attachment.html>


More information about the cfe-dev mailing list