[cfe-dev] [libClang] Determining whether enum is enum class
Sam Vanheer via cfe-dev
cfe-dev at lists.llvm.org
Thu Jul 6 03:05:47 PDT 2017
I need to determine whether an enum is an enum class.
I found this answer:
https://stackoverflow.com/questions/26168121/how-do-you-detect-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?
More information about the cfe-dev
mailing list