Commit d63fb848 authored by Dimitri van Heesch's avatar Dimitri van Heesch

Add support for writing and importing C++11 style enums to and from tag files

parent 0651fff2
......@@ -7187,10 +7187,12 @@ static void addEnumValuesToEnums(EntryNav *rootNav)
// them here and only add them to the enum
e->loadEntry(g_storage);
Entry *root = e->entry();
//printf("md->qualifiedName()=%s rootNav->name()=%s\n",
// md->qualifiedName().data(),rootNav->name().data());
//printf("md->qualifiedName()=%s rootNav->name()=%s tagInfo=%p\n",
// md->qualifiedName().data(),rootNav->name().data(),rootNav->tagInfo());
if (substitute(md->qualifiedName(),"::",".")== // TODO: add function to get canonical representation
substitute(rootNav->name(),"::",".")) // enum value scope matches that of the enum
substitute(rootNav->name(),"::",".") || // enum value scope matches that of the enum
rootNav->tagInfo() // be less strict for tag files as members can have incomplete scope
)
{
MemberDef *fmd=new MemberDef(
root->fileName,root->startLine,root->startColumn,
......
......@@ -3397,6 +3397,8 @@ void MemberDef::_writeTagData(const DefType compoundType)
{
unsigned typeMask = 1 << compoundType;
if ((m_impl->tagDataWritten) & typeMask) return; // member already written for this type
if (m_impl->mtype==MemberType_EnumValue && m_impl->enumScope &&
m_impl->enumScope->isStrong()) return; // enum value is part of enum
static bool generateTagFile = !Config_getString("GENERATE_TAGFILE").isEmpty();
// write tag file information of this member
if (generateTagFile && isLinkableInProject())
......@@ -3447,37 +3449,32 @@ void MemberDef::_writeTagData(const DefType compoundType)
Doxygen::tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
}
Doxygen::tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
writeDocAnchorsToTagFile();
Doxygen::tagFile << " </member>" << endl;
_addToSearchIndex();
}
MemberList *fmdl=m_impl->enumFields;
if (fmdl)
{
MemberListIterator mli(*fmdl);
MemberDef *fmd;
for (mli.toFirst();(fmd=mli.current());++mli)
if (isStrong())
{
if (!fmd->isReference())
MemberList *fmdl=m_impl->enumFields;
if (fmdl)
{
if (!Config_getString("GENERATE_TAGFILE").isEmpty())
MemberListIterator mli(*fmdl);
MemberDef *fmd;
for (mli.toFirst();(fmd=mli.current());++mli)
{
Doxygen::tagFile << " <member kind=\"enumvalue\">" << endl;
Doxygen::tagFile << " <name>" << convertToXML(fmd->name()) << "</name>" << endl;
Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
Doxygen::tagFile << " <anchor>" << convertToXML(fmd->anchor()) << "</anchor>" << endl;
QCString idStr = fmd->id();
if (!idStr.isEmpty())
if (!fmd->isReference())
{
Doxygen::tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
Doxygen::tagFile << " <enumvalue file=\"" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension);
Doxygen::tagFile << "\" anchor=\"" << convertToXML(fmd->anchor());
QCString idStr = fmd->id();
if (!idStr.isEmpty())
{
Doxygen::tagFile << "\" clangid=\"" << convertToXML(idStr);
}
Doxygen::tagFile << "\">" << convertToXML(fmd->name()) << "</enumvalue>" << endl;
}
Doxygen::tagFile << " <arglist>" << convertToXML(fmd->argsString()) << "</arglist>" << endl;
Doxygen::tagFile << " </member>" << endl;
fmd->m_impl->tagDataWritten |= typeMask;
fmd->_addToSearchIndex();
}
}
}
writeDocAnchorsToTagFile();
Doxygen::tagFile << " </member>" << endl;
_addToSearchIndex();
}
m_impl->tagDataWritten |= typeMask;
}
......
......@@ -61,11 +61,22 @@ class TagAnchorInfoList : public QList<TagAnchorInfo>
virtual ~TagAnchorInfoList() {}
};
/** Container for enum values that are scoped within an enum */
class TagEnumValueInfo
{
public:
QCString name;
QCString file;
QCString anchor;
QCString clangid;
};
/** Container for member specific info that can be read from a tagfile */
class TagMemberInfo
{
public:
TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE) {}
TagMemberInfo() : prot(Public), virt(Normal), isStatic(FALSE)
{ enumValues.setAutoDelete(TRUE); }
QCString type;
QCString name;
QCString anchorFile;
......@@ -77,6 +88,7 @@ class TagMemberInfo
Protection prot;
Specifier virt;
bool isStatic;
QList<TagEnumValueInfo> enumValues;
};
/** Container for class specific info that can be read from a tagfile */
......@@ -205,6 +217,7 @@ class TagFileParser : public QXmlDefaultHandler
InGroup,
InPage,
InMember,
InEnumValue,
InPackage,
InDir,
InTempArgList
......@@ -416,6 +429,36 @@ class TagFileParser : public QXmlDefaultHandler
}
}
void startEnumValue( const QXmlAttributes& attrib)
{
if (m_state==InMember)
{
m_curString = "";
m_curEnumValue = new TagEnumValueInfo;
m_curEnumValue->file = attrib.value("file").utf8();
m_curEnumValue->anchor = attrib.value("anchor").utf8();
m_curEnumValue->clangid = attrib.value("clangid").utf8();
m_stateStack.push(new State(m_state));
m_state = InEnumValue;
}
else
{
warn("Found enumvalue tag outside of member tag\n");
}
}
void endEnumValue()
{
m_curEnumValue->name = m_curString.stripWhiteSpace();
m_state = *m_stateStack.top();
m_stateStack.remove();
if (m_state==InMember)
{
m_curMember->enumValues.append(m_curEnumValue);
m_curEnumValue=0;
}
}
void endDocAnchor()
{
switch(m_state)
......@@ -745,6 +788,7 @@ class TagFileParser : public QXmlDefaultHandler
m_startElementHandlers.insert("compound", new StartElementHandler(this,&TagFileParser::startCompound));
m_startElementHandlers.insert("member", new StartElementHandler(this,&TagFileParser::startMember));
m_startElementHandlers.insert("enumvalue", new StartElementHandler(this,&TagFileParser::startEnumValue));
m_startElementHandlers.insert("name", new StartElementHandler(this,&TagFileParser::startStringValue));
m_startElementHandlers.insert("base", new StartElementHandler(this,&TagFileParser::startBase));
m_startElementHandlers.insert("filename", new StartElementHandler(this,&TagFileParser::startStringValue));
......@@ -768,6 +812,7 @@ class TagFileParser : public QXmlDefaultHandler
m_endElementHandlers.insert("compound", new EndElementHandler(this,&TagFileParser::endCompound));
m_endElementHandlers.insert("member", new EndElementHandler(this,&TagFileParser::endMember));
m_endElementHandlers.insert("enumvalue", new EndElementHandler(this,&TagFileParser::endEnumValue));
m_endElementHandlers.insert("name", new EndElementHandler(this,&TagFileParser::endName));
m_endElementHandlers.insert("base", new EndElementHandler(this,&TagFileParser::endBase));
m_endElementHandlers.insert("filename", new EndElementHandler(this,&TagFileParser::endFilename));
......@@ -853,6 +898,7 @@ class TagFileParser : public QXmlDefaultHandler
TagPageInfo *m_curPage;
TagDirInfo *m_curDir;
TagMemberInfo *m_curMember;
TagEnumValueInfo *m_curEnumValue;
TagIncludeInfo *m_curIncludes;
QCString m_curString;
QCString m_tagName;
......@@ -1102,6 +1148,26 @@ void TagFileParser::buildMemberList(Entry *ce,QList<TagMemberInfo> &members)
me->argList = new ArgumentList;
stringToArgumentList(me->args,me->argList);
}
if (tmi->enumValues.count()>0)
{
me->spec |= Entry::Strong;
QListIterator<TagEnumValueInfo> evii(tmi->enumValues);
TagEnumValueInfo *evi;
for (evii.toFirst();(evi=evii.current());++evii)
{
Entry *ev = new Entry;
ev->type = "@";
ev->name = evi->name;
ev->id = evi->clangid;
ev->section = Entry::VARIABLE_SEC;
TagInfo *ti = new TagInfo;
ti->tagName = m_tagName;
ti->anchor = evi->anchor;
ti->fileName = evi->file;
ev->tagInfo = ti;
me->addSubEntry(ev);
}
}
me->protection = tmi->prot;
me->virt = tmi->virt;
me->stat = tmi->isStatic;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment