<div dir="ltr">I think this kind of addition is acceptable. Your implementation looks correct. <div><br></div><div>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 - <a href="http://llvm.org/docs/Phabricator.html" target="_blank">http://llvm.org/docs/<wbr>Phabricator.html</a> . You might also find the developer policy document helpful: <a href="http://llvm.org/docs/DeveloperPolicy.html">http://llvm.org/docs/DeveloperPolicy.html</a> . Don't forget to include a test case with your patch!<div><div><br></div><div>I hope this was helpful,</div><div>Alex</div><div><div class="gmail_extra"><br><div class="gmail_quote">On 6 July 2017 at 11:05, Sam Vanheer via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">I need to determine whether an enum is an enum class.<br>
<br>
I found this answer:<br>
<a href="https://stackoverflow.com/questions/26168121/how-do-you-detect-the-difference-between-an-enum-and-a-scoped-enum-using-libclan" rel="noreferrer" target="_blank">https://stackoverflow.com/ques<wbr>tions/26168121/how-do-you-dete<wbr>ct-the-difference-between-an-<wbr>enum-and-a-scoped-enum-using-<wbr>libclan</a><br>
<br>
This isn't a suitable solution for code that exclusively uses the<br>
libClang API.<br>
<br>
<br>
I have come up with a solution that relies on parsing the source code<br>
surrounding the declaration:<br>
<br>
bool IsEnumEnumClass( const CXCursor& cursor )<br>
{<br>
auto TU = clang_getTranslationUnit( cursor );<br>
<br>
CXToken* pTokens = nullptr;<br>
unsigned int uiNumTokens = 0;<br>
<br>
clang_tokenize( TU, clang_getCursorExtent( cursor ), &pTokens,<br>
&uiNumTokens );<br>
<br>
bool bEncounteredEnumKeyword = false;<br>
<br>
bool bIsStronglyScoped = false;<br>
<br>
//Check the declaration until we find an "enum" keyword. If it's<br>
followed by "class", it's strongly scoped.<br>
//Possible input: typedef enum class {} Foo; (typedef is apparently<br>
ignored, but can't hurt to account for it)<br>
for( decltype( uiNumTokens ) uiToken = 0; uiToken < uiNumTokens;<br>
++uiToken )<br>
{<br>
auto spelling = clang::ToStdString( clang_getTokenSpelling( TU,<br>
pTokens[ uiToken ] ) );<br>
<br>
if( spelling == "enum" )<br>
{<br>
bEncounteredEnumKeyword = true;<br>
}<br>
else if( bEncounteredEnumKeyword )<br>
{<br>
if( spelling == "class" )<br>
{<br>
bIsStronglyScoped = true;<br>
}<br>
<br>
//No "class" keyword encountered, so it's a weakly scoped enum.<br>
break;<br>
}<br>
}<br>
<br>
clang_disposeTokens( TU, pTokens, uiNumTokens );<br>
<br>
return bIsStronglyScoped;<br>
}<br>
<br>
<br>
clang::ToStdString converts a CXString to std::string.<br>
<br>
<br>
This solution works, but isn't very pretty and may not work properly in<br>
all cases.<br>
<br>
I suppose a new function int clang_isScopedEnum( CXCursor C ) would be<br>
helpful here, implemented as:<br>
<br>
int clang_Cursor_isScopedEnum( CXCursor C )<br>
{<br>
if( clang_getCursorKind( C ) != CXCursor_EnumDecl )<br>
return 0;<br>
<br>
if( const EnumDecl *TD = dyn_cast_or_null<EnumDecl>( getCursorDecl(<br>
C ) ) )<br>
{<br>
return TD->isScoped();<br>
}<br>
<br>
return 0;<br>
}<br>
<br>
I have no experience implementing new features in libClang, and i'd<br>
rather not break anything. Can anyone assist with such an<br>
implementation, if it is acceptable?<br>
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</blockquote></div><br></div></div></div></div></div>