diff options
Diffstat (limited to 'src/scanner.l')
-rw-r--r-- | src/scanner.l | 691 |
1 files changed, 291 insertions, 400 deletions
diff --git a/src/scanner.l b/src/scanner.l index 07d5c71..957c1e4 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -22,6 +22,11 @@ /* * includes */ + +#include <algorithm> +#include <vector> +#include <utility> + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -86,11 +91,11 @@ static int roundCount = 0 ; static int curlyCount = 0 ; static int squareCount = 0 ; static int padCount = 0 ; +static std::unique_ptr<Entry> current; static Entry* current_root = 0 ; static Entry* global_root = 0 ; -static Entry* current = 0 ; static Entry* previous = 0 ; -static Entry* tempEntry = 0 ; +static std::unique_ptr<Entry> tempEntry; static Entry* firstTypedefEntry = 0 ; static Entry* memspecEntry = 0 ; static int yyLineNr = 1 ; @@ -194,6 +199,8 @@ static int g_column; static int g_fencedSize=0; static bool g_nestedComment=0; +static std::vector< std::pair<Entry*,std::unique_ptr<Entry> > > g_outerScopeEntries; + static const char *stateToString(int state); //----------------------------------------------------------------------------- @@ -205,6 +212,7 @@ static const char *stateToString(int state); static void initParser() { + g_outerScopeEntries.clear(); sectionLabel.resize(0); sectionTitle.resize(0); baseName.resize(0); @@ -228,7 +236,6 @@ static void initParser() sliceOpt=Config_getBool(OPTIMIZE_OUTPUT_SLICE); previous = 0; firstTypedefEntry = 0; - tempEntry = 0; memspecEntry =0; } @@ -244,54 +251,13 @@ static void initEntry() current->stat = gstat; current->lang = language; //printf("*** initEntry() language=%d\n",language); - //if (!autoGroupStack.isEmpty()) - //{ - // //printf("Appending group %s\n",autoGroupStack.top()->groupname.data()); - // current->groups->append(new Grouping(*autoGroupStack.top())); - //} - Doxygen::docGroup.initGroupInfo(current); + Doxygen::docGroup.initGroupInfo(current.get()); isTypedef=FALSE; } //----------------------------------------------------------------------------- -///// remove any automatic grouping and add new one (if given) -//static void setCurrentGroup( QCString *newgroup, Grouping::GroupPri_t pri ) -//{ -// /* remove auto group name from current entry and discard it */ -// Grouping *g = current->groups->first(); -// int i=0; -// while (g) -// { -// if (g->pri <= Grouping::GROUPING_AUTO_DEF) -// { -// current->groups->remove(i); -// i--; -// } -// g=current->groups->next(); -// i++; -// } -// -// /* use new group name instead? */ -// if ( newgroup ) -// { -// current->groups->append(new Grouping(*newgroup, pri)); -// } -//} -// -//static int newMemberGroupId() -//{ -// static int curGroupId=0; -// return curGroupId++; -//} -// -// forward declarations -//static void startGroupInDoc(); -//static void endGroup(); - -//----------------------------------------------------------------------------- - static void lineCount() { static int tabSize = Config_getInt(TAB_SIZE); @@ -329,7 +295,7 @@ static inline int computeIndent(const char *s,int startIndent) return col; } -static void addType( Entry* current ) +static void addType() { uint tl=current->type.length(); if( tl>0 && !current->name.isEmpty() && current->type.at(tl-1)!='.') @@ -345,7 +311,7 @@ static void addType( Entry* current ) } current->type += current->args ; current->args.resize(0) ; - current->argList->clear(); + current->argList.clear(); } @@ -365,7 +331,7 @@ static QCString stripQuotes(const char *s) static void startCommentBlock(bool); static void handleCommentBlock(const QCString &doc,bool brief); -static void handleParametersCommentBlocks(ArgumentList *al); +static void handleParametersCommentBlocks(ArgumentList &al); //----------------------------------------------------------------- @@ -411,28 +377,10 @@ static void prependScope() { //printf("--- prependScope %s to %s\n",current_root->name.data(),current->name.data()); current->name.prepend(current_root->name+"::"); - if (current_root->tArgLists) + //printf("prependScope #=%d #current=%d\n",current_root->tArgLists->count(),current->tArgLists->count()); + for (const ArgumentList &srcAl : current_root->tArgLists) { - if (current->tArgLists==0) - { - current->tArgLists = new QList<ArgumentList>; - current->tArgLists->setAutoDelete(TRUE); - } - //printf("prependScope #=%d #current=%d\n",current_root->tArgLists->count(),current->tArgLists->count()); - QListIterator<ArgumentList> talsi(*current_root->tArgLists); - ArgumentList *srcAl=0; - for (talsi.toLast();(srcAl=talsi.current());--talsi) - { - ArgumentList *dstAl = new ArgumentList; - QListIterator<Argument> tali(*srcAl); - Argument *a; - for (;(a=tali.current());++tali) - { - dstAl->append(new Argument(*a)); - //printf("appending argument %s %s\n",a->type.data(),a->name.data()); - } - current->tArgLists->insert(0,dstAl); - } + current->tArgLists.insert(current->tArgLists.begin(),srcAl); } } } @@ -443,14 +391,12 @@ static void prependScope() static bool checkForKnRstyleC() { if (((QCString)yyFileName).right(2).lower()!=".c") return FALSE; // must be a C file - if (!current->argList) return FALSE; // must have arguments - ArgumentListIterator ali(*current->argList); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) + if (current->argList.empty()) return FALSE; // must have arguments + for (const Argument &a : current->argList) { // in K&R style argument do not have a type, but doxygen expects a type // so it will think the argument has no name - if (a->type.isEmpty() || !a->name.isEmpty()) return FALSE; + if (a.type.isEmpty() || !a.name.isEmpty()) return FALSE; } return TRUE; } @@ -538,30 +484,27 @@ static void splitKnRArg(QCString &oldStyleArgPtr,QCString &oldStyleArgName) static void addKnRArgInfo(const QCString &type,const QCString &name, const QCString &brief,const QCString &docs) { - if (current->argList==0) return; - ArgumentListIterator ali(*current->argList); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) + for (Argument &a : current->argList) { - if (a->type==name) + if (a.type==name) { - a->type=type.stripWhiteSpace(); - if (a->type.left(9)=="register ") // strip keyword + a.type=type.stripWhiteSpace(); + if (a.type.left(9)=="register ") // strip keyword { - a->type=a->type.mid(9); + a.type=a.type.mid(9); } - a->name=name.stripWhiteSpace(); + a.name=name.stripWhiteSpace(); if (!brief.isEmpty() && !docs.isEmpty()) { - a->docs=brief+"\n\n"+docs; + a.docs=brief+"\n\n"+docs; } else if (!brief.isEmpty()) { - a->docs=brief; + a.docs=brief; } else { - a->docs=docs; + a.docs=docs; } } } @@ -570,17 +513,14 @@ static void addKnRArgInfo(const QCString &type,const QCString &name, //----------------------------------------------------------------------------- -void fixArgumentListForJavaScript(ArgumentList *al) +void fixArgumentListForJavaScript(ArgumentList &al) { - if (al==0) return; - ArgumentListIterator ali(*al); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) + for (Argument &a : al) { - if (!a->type.isEmpty() && a->name.isEmpty()) + if (!a.type.isEmpty() && a.name.isEmpty()) { // a->type is actually the (typeless) parameter name, so move it - a->name=a->type; - a->type.resize(0); + a.name=a.type; + a.type.resize(0); } } } @@ -744,6 +684,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) %x GCopyCurly %x SkipUnionSwitch %x Specialization +%x SpecializationSingleQuote +%x SpecializationDoubleQuote %x FuncPtrInit %x FuncFunc %x FuncFuncEnd @@ -895,7 +837,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } @@ -904,7 +846,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } @@ -914,7 +856,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } @@ -924,7 +866,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount(); } @@ -934,7 +876,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount(); } @@ -944,7 +886,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount(); } <FindMembers>{B}*("public"|"methods"|"__published"){BN}*":"{BN}* { @@ -953,7 +895,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } <FindMembers>{B}*"internal"{BN}*":"{BN}* { // for now treat C++/CLI's internal as package... @@ -964,7 +906,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } else @@ -978,7 +920,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } <FindMembers>{B}*"private"{BN}*":"{BN}* { @@ -987,7 +929,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } <FindMembers>{B}*"event"{BN}+ { @@ -1027,7 +969,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <CliPropertyType>{ID} { - addType( current ); + addType(); current->name = yytext; } <CliPropertyType>"[" { // C++/CLI indexed property @@ -1049,7 +991,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <CliPropertyType>{B}* { } <CliPropertyType>. { - addType( current ); + addType(); current->type += yytext; } <CliPropertyIndex>"]" { @@ -1078,7 +1020,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } <FindMembers>{B}*"@protected"{BN}+ { @@ -1087,7 +1029,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } <FindMembers>{B}*"@public"{BN}+ { @@ -1096,7 +1038,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); lineCount() ; } <FindMembers>[\-+]{BN}* { @@ -1121,7 +1063,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0); current->name.resize(0); current->args.resize(0); - current->argList->clear(); + current->argList.clear(); BEGIN( ObjCMethod ); } } @@ -1141,8 +1083,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <ObjCMethod>":"{B}* { // start of parameter list current->name += ':'; - Argument *a = new Argument; - current->argList->append(a); + Argument a; + current->argList.push_back(a); BEGIN( ObjCParams ); } <ObjCReturnType>[^)]* { // TODO: check if nested braches are possible. @@ -1162,26 +1104,26 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->name += keyw+":"; } - if (current->argList->getLast()->type.isEmpty()) + if (current->argList.back().type.isEmpty()) { - current->argList->getLast()->type="id"; + current->argList.back().type="id"; } - Argument *a = new Argument; - a->attrib=(QCString)"["+keyw+"]"; - current->argList->append(a); + Argument a; + a.attrib=(QCString)"["+keyw+"]"; + current->argList.push_back(a); } <ObjCParams>{ID}{BN}* { // name of parameter lineCount(); - current->argList->getLast()->name=QCString(yytext).stripWhiteSpace(); + current->argList.back().name=QCString(yytext).stripWhiteSpace(); } <ObjCParams>","{BN}*"..." { // name of parameter lineCount(); // do we want the comma as part of the name? //current->name += ","; - Argument *a = new Argument; - a->attrib="[,]"; - a->type="..."; - current->argList->append(a); + Argument a; + a.attrib="[,]"; + a.type="..."; + current->argList.push_back(a); } /* <ObjCParams>":" { @@ -1190,12 +1132,12 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) */ <ObjCParams>"(" { roundCount=0; - current->argList->getLast()->type.resize(0); + current->argList.back().type.resize(0); BEGIN( ObjCParamType ); } <ObjCParamType>"(" { roundCount++; - current->argList->getLast()->type+=yytext; + current->argList.back().type+=yytext; } <ObjCParamType>")"/{B}* { if (roundCount<=0) @@ -1204,18 +1146,22 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - current->argList->getLast()->type+=yytext; + current->argList.back().type+=yytext; roundCount--; } } <ObjCParamType>[^()]* { - current->argList->getLast()->type+=QCString(yytext).stripWhiteSpace(); + current->argList.back().type+=QCString(yytext).stripWhiteSpace(); } <ObjCMethod,ObjCParams>";" { // end of method declaration - if (current->argList->getLast() && current->argList->getLast()->type.isEmpty()) + if (!current->argList.empty() && current->argList.back().type.isEmpty()) { - current->argList->getLast()->type="id"; + current->argList.back().type="id"; } + if (current->argList.empty()) // method without parameters + { + current->argList.noParameters = TRUE; + } current->args = argListToString(current->argList); //printf("argList=%s\n",current->args.data()); unput(';'); @@ -1226,10 +1172,14 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //printf("Type=%s Name=%s args=%s\n", // current->type.data(),current->name.data(),argListToString(current->argList).data() // ); - if (current->argList->getLast() && current->argList->getLast()->type.isEmpty()) + if (!current->argList.empty() && current->argList.back().type.isEmpty()) { - current->argList->getLast()->type="id"; + current->argList.back().type="id"; } + if (current->argList.empty()) // method without parameters + { + current->argList.noParameters = TRUE; + } current->args = argListToString(current->argList); unput('{'); BEGIN( Function ); @@ -1371,9 +1321,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(); } <PackageName>";" { - current_root->addSubEntry(current); - current_root = current ; - current = new Entry ; + Entry *tmp = current.get(); + current_root->moveToSubEntryAndRefresh(current); + current_root = tmp; initEntry(); BEGIN(FindMembers); } @@ -1509,7 +1459,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1528,7 +1478,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1547,7 +1497,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1560,7 +1510,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Service | // preserve UNO IDL [optional] or published (current->spec & (Entry::Optional|Entry::Published)); - addType( current ) ; + addType(); current->type += " service " ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1569,7 +1519,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // TODO is addType right? just copy/pasted { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1581,7 +1531,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->section = Entry::CLASS_SEC; current->spec = Entry::Singleton | (current->spec & Entry::Published); // preserve - addType( current ) ; + addType(); current->type += " singleton " ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1590,7 +1540,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // TODO is addType right? just copy/pasted { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1603,7 +1553,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Interface | // preserve UNO IDL [optional], published, Slice local (current->spec & (Entry::Optional|Entry::Published|Entry::Local)); - addType( current ) ; + addType(); current->type += " interface" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1613,7 +1563,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType( current ) ; + addType(); current->name = QCString(yytext).stripWhiteSpace(); } } @@ -1624,7 +1574,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; current->protection = protection = Public ; - addType( current ) ; + addType(); current->type += " implementation" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1642,7 +1592,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) insideObjC = TRUE; } current->protection = protection = Public ; - addType( current ) ; + addType(); current->type += " interface" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1658,7 +1608,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) language = current->lang = SrcLangExt_ObjC; insideObjC = TRUE; current->protection = protection = Public ; - addType( current ) ; + addType(); current->type += " protocol" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1673,7 +1623,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Exception | (current->spec & Entry::Published) | (current->spec & Entry::Local); - addType( current ) ; + addType(); current->type += " exception" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1690,7 +1640,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) bool isConst=decl.find("const")!=-1; bool isVolatile=decl.find("volatile")!=-1; current->section = Entry::CLASS_SEC; - addType( current ) ; + addType(); uint64 spec = current->spec; if (insidePHP && current->spec&Entry::Abstract) { @@ -1728,7 +1678,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Value; - addType( current ) ; + addType(); current->type += " value class" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1743,7 +1693,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Ref; - addType( current ) ; + addType(); current->type += " ref class" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1758,7 +1708,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Interface; - addType( current ) ; + addType(); current->type += " interface class" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1773,7 +1723,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; - addType( current ) ; + addType(); current->type += " coclass" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1784,7 +1734,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType(current); + addType(); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); @@ -1805,7 +1755,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) (current->spec & Entry::Local); // bug 582676: can be a struct nested in an interface so keep insideObjC state //current->objc = insideObjC = FALSE; - addType( current ) ; + addType(); if (isConst) { current->type += " const"; @@ -1828,7 +1778,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Value; - addType( current ) ; + addType(); current->type += " value struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1843,7 +1793,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Ref; - addType( current ) ; + addType(); current->type += " ref struct" ; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1858,7 +1808,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) isTypedef=FALSE; current->section = Entry::CLASS_SEC; current->spec = Entry::Struct | Entry::Interface; - addType( current ) ; + addType(); current->type += " interface struct"; current->fileName = yyFileName; current->startLine = yyLineNr; @@ -1878,7 +1828,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->spec = Entry::Union; // bug 582676: can be a struct nested in an interface so keep insideObjC state //current->objc = insideObjC = FALSE; - addType( current ) ; + addType(); if (isConst) { current->type += " const"; @@ -1910,7 +1860,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->section = Entry::ENUM_SEC ; } - addType( current ) ; + addType(); current->type += " enum"; if (isStrongEnum) { @@ -1951,15 +1901,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers>("template"|"generic")({BN}*)"<"/[>]? { // generic is a C++/CLI extension lineCount(); - if (current->tArgLists==0) - { - current->tArgLists = new QList<ArgumentList>; - current->tArgLists->setAutoDelete(TRUE); - } - ArgumentList *al = new ArgumentList; + ArgumentList al; //current->spec |= (yytext[0]=='g') ? Entry::Generic : Entry::Template; - current->tArgLists->append(al); - currentArgumentList = al; + current->tArgLists.push_back(al); + currentArgumentList = ¤t->tArgLists.back(); templateStr="<"; fullArgString = templateStr; copyArgString = &templateStr; @@ -2001,14 +1946,12 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name=removeRedundantWhiteSpace(substitute(yytext,"\\","::")); //printf("PHP: adding use relation: %s\n",current->name.data()); current->fileName = yyFileName; - // add a using declaraton + // add a using declaration current->section=Entry::USINGDECL_SEC; - current_root->addSubEntry(current); - current = new Entry(*current); + current_root->copyToSubEntry(current); // also add it as a using directive current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); aliasName.resize(0); } @@ -2043,8 +1986,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name=removeRedundantWhiteSpace(substitute(scope.left(scope.length()-1),".","::")); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(Using); } @@ -2062,9 +2004,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //printf("import name = %s -> %s\n",yytext,current->name.data()); current->section=Entry::USINGDECL_SEC; } - current_root->addSubEntry(current); - previous = current; - current = new Entry ; + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(Using); } @@ -2081,9 +2022,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->fileName = yyFileName; current->section=Entry::USINGDECL_SEC; current->startLine = yyLineNr; - current_root->addSubEntry(current); - previous = current; - current = new Entry ; + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); + initEntry(); if (insideCS) /* Hack: in C# a using declaration and directive have the same syntax, so we also add it as a using directive here @@ -2094,10 +2035,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->startLine = yyLineNr; current->startColumn = yyColNr; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); + initEntry(); } - initEntry(); BEGIN(Using); } <Using>"=" { // C++11 style template alias? @@ -2156,22 +2096,21 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <UsingDirective>{SCOPENAME} { current->name=removeRedundantWhiteSpace(yytext); current->fileName = yyFileName; current->section=Entry::USINGDIR_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(Using); } <Using>";" { BEGIN(FindMembers); } <FindMembers>{SCOPENAME}{BN}*"<>" { // guided template decl QCString n=yytext; - addType( current ); + addType(); current->name=n.left(n.length()-2); } <FindMembers>{SCOPENAME}{BN}*/"<" { // Note: this could be a return type! roundCount=0; sharpCount=0; lineCount(); - addType( current ); + addType(); current->name=yytext; current->name=current->name.stripWhiteSpace(); //current->scopeSpec.resize(0); @@ -2437,7 +2376,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else if (insideCS && qstrcmp(yytext,"this")==0) { // C# indexer - addType( current ) ; + addType(); current->name="this"; BEGIN(CSIndexer); } @@ -2469,7 +2408,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { if (YY_START==FindMembers) { - addType( current ) ; + addType(); } bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS; if (javaLike && qstrcmp(yytext,"public")==0) @@ -2704,8 +2643,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::DEFINE_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(lastDefineContext); } @@ -2722,8 +2660,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->initializer = init; current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -2758,7 +2695,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <FindMembers>[\^%] { // ^ and % are C++/CLI extensions if (insideCli) { - addType( current ); + addType(); current->name = yytext ; } else @@ -2768,9 +2705,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers>[*&]+ { current->name += yytext ; - addType( current ); + addType(); } -<FindMembers,MemberSpec,Function,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { +<FindMembers,MemberSpec,Function,NextSemi,EnumBaseType,BitFields,ReadInitializer,OldStyleArgs,DefinePHPEnd>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { if (current->bodyLine==-1) { current->bodyLine=yyLineNr; @@ -2870,7 +2807,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { // link open command to the current entry - Doxygen::docGroup.open(current,yyFileName,yyLineNr); + Doxygen::docGroup.open(current.get(),yyFileName,yyLineNr); } //current = tmp; initEntry(); @@ -2914,7 +2851,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FindMembers,FindFields,ReadInitializer>"//"([!/]){B}*{CMD}"}".*|"/*"([!*]){B}*{CMD}"}"[^*]*"*/" { bool insideEnum = YY_START==FindFields || (YY_START==ReadInitializer && lastInitializerContext==FindFields); // see bug746226 - Doxygen::docGroup.close(current,yyFileName,yyLineNr,insideEnum); + Doxygen::docGroup.close(current.get(),yyFileName,yyLineNr,insideEnum); } <FindMembers>"=" { // in PHP code this could also be due to "<?=" current->bodyLine = yyLineNr; @@ -2965,8 +2902,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -3468,7 +3404,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { if (current->type.isEmpty()) // anonymous padding field, e.g. "int :7;" { - addType(current); + addType(); current->name.sprintf("__pad%d__",padCount++); } BEGIN(BitFields); @@ -3499,7 +3435,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->type.prepend("typedef "); } - bool needNewCurrent=FALSE; + bool stat = current->stat; if (!current->name.isEmpty() && current->section!=Entry::ENUM_SEC) { current->type=current->type.simplifyWhiteSpace(); @@ -3513,17 +3449,11 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->fileName = yyFileName; current->startLine = yyBegLineNr; current->startColumn = yyBegColNr; - current_root->addSubEntry( current ) ; - needNewCurrent=TRUE; + current_root->moveToSubEntryAndRefresh( current ) ; + initEntry(); } if ( *yytext == ',') { - bool stat = current->stat; - if (needNewCurrent) - { - current = new Entry(*current); - initEntry(); - } current->stat = stat; // the static attribute holds for all variables current->name.resize(0); current->args.resize(0); @@ -3539,14 +3469,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { mtype = Method; virt = Normal; - if (needNewCurrent) - { - current = new Entry ; - } - else if (current->groups) - { - current->groups->clear(); - } + current->groups.clear(); initEntry(); } } @@ -3764,8 +3687,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args += ")"; current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN( FindMembers ); } @@ -3794,7 +3716,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN( SkipString ); } <SkipSquare>[^\n\[\]\"]+ -<FindMembers>"<" { addType( current ) ; +<FindMembers>"<" { addType(); current->type += yytext ; BEGIN( Sharp ) ; } @@ -3847,8 +3769,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); } @@ -3880,17 +3801,17 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name = current->name.stripWhiteSpace(); current->section = Entry::VARIABLE_SEC; // add to the scope of the enum - current_root->addSubEntry(current); if (!insideCS && !insideJava && !(current_root->spec&Entry::Strong)) // for C# and Java 1.5+ enum values always have to be explicitly qualified, // same for C++11 style enums (enum class Name {}) { - current = new Entry(*current); // add to the scope surrounding the enum (copy!) - current_root->parent()->addSubEntry(current); + // we cannot during it directly as that would invalidate the iterator in parseCompounds. + //printf("*** adding outer scope entry for %s\n",current->name.data()); + g_outerScopeEntries.emplace_back(current_root->parent(), std::make_unique<Entry>(*current)); } - current = new Entry ; + current_root->moveToSubEntryAndRefresh(current); initEntry(); } else // probably a redundant , @@ -3985,13 +3906,13 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { current->endBodyLine = yyLineNr; - Entry * original_root = current_root; // save root this namespace is in + Entry * original_root = current_root; // save root this namespace is in if (current->section == Entry::NAMESPACE_SEC && current->type == "namespace") { int split_point; while ((split_point = current->name.find("::")) != -1) { - Entry *new_current = new Entry(*current); + std::unique_ptr<Entry> new_current = std::make_unique<Entry>(*current); current->program = ""; new_current->doc = ""; new_current->docLine = 0; @@ -4003,9 +3924,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name = current->name.left(split_point); if (!current_root->name.isEmpty()) current->name.prepend(current_root->name+"::"); - current_root->addSubEntry(current); - current_root = current; - current = new_current; + Entry *tmp = current.get(); + current_root->moveToSubEntryAndKeep(current); + current_root = tmp; + current.swap(new_current); } } QCString &cn = current->name; @@ -4040,17 +3962,16 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - current_root->addSubEntry( current ) ; - memspecEntry = current; - current = new Entry(*current); - if (current->section==Entry::NAMESPACE_SEC || + memspecEntry = current.get(); + current_root->copyToSubEntry( current ) ; + if (current->section==Entry::NAMESPACE_SEC || (current->spec==Entry::Interface) || insideJava || insidePHP || insideCS || insideD || insideJS || insideSlice ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon - current->reset(); - current_root = original_root; // restore scope from before namespace descent + current->reset(); + current_root = original_root; // restore scope from before namespace descent initEntry(); memspecEntry = 0; BEGIN( FindMembers ) ; @@ -4105,12 +4026,11 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); //printf("Adding compound %s %s %s\n",current->type.data(),current->name.data(),current->args.data()); - current_root->addSubEntry( current ) ; if (!firstTypedefEntry) { - firstTypedefEntry = current; + firstTypedefEntry = current.get(); } - current = new Entry; + current_root->moveToSubEntryAndRefresh( current ) ; initEntry(); isTypedef=TRUE; // to undo reset by initEntry() BEGIN(MemberSpecSkip); @@ -4124,9 +4044,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // add compound definition to the tree current->args = current->args.simplifyWhiteSpace(); current->type = current->type.simplifyWhiteSpace(); - current_root->addSubEntry( current ) ; - memspecEntry = current; - current = new Entry(*current); + memspecEntry = current.get(); + current_root->moveToSubEntryAndRefresh( current ) ; initEntry(); unput(';'); BEGIN( MemberSpec ) ; @@ -4166,7 +4085,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <MemberSpec>"(" { // function with struct return type - addType(current); + addType(); current->name = msName; current->spec = 0; unput('('); @@ -4179,7 +4098,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // anonymous compound. If so we insert a // special 'anonymous' variable. //Entry *p=current_root; - Entry *p=current; + const Entry *p=current.get(); while (p) { // only look for class scopes, not namespace scopes @@ -4197,7 +4116,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } //p=p->parent; - if (p==current) p=current_root; else p=p->parent(); + if (p==current.get()) p=current_root; else p=p->parent(); } } //printf("msName=%s current->name=%s\n",msName.data(),current->name.data()); @@ -4218,7 +4137,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // case 2: create a typedef field { - Entry *varEntry=new Entry; + std::unique_ptr<Entry> varEntry=std::make_unique<Entry>(); varEntry->lang = language; varEntry->protection = current->protection ; varEntry->mtype = current->mtype; @@ -4252,28 +4171,13 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) varEntry->brief = current->brief.copy(); varEntry->mGrpId = current->mGrpId; varEntry->initializer = current->initializer; - - // deep copy group list - QListIterator<Grouping> gli(*current->groups); - Grouping *g; - for (;(g=gli.current());++gli) - { - varEntry->groups->append(new Grouping(*g)); - } - if (current->sli) // copy special list items - { - QListIterator<ListItemInfo> li(*current->sli); - ListItemInfo *lii; - for (li.toFirst();(lii=li.current());++li) - { - varEntry->addSpecialListItem(lii->type,lii->itemId); - } - } + varEntry->groups = current->groups; + varEntry->sli = current->sli; //printf("Add: type='%s',name='%s',args='%s' brief=%s doc=%s\n", // varEntry->type.data(),varEntry->name.data(), // varEntry->args.data(),varEntry->brief.data(),varEntry->doc.data()); - current_root->addSubEntry(varEntry); + current_root->moveToSubEntryAndKeep(varEntry); } } if (*yytext==';') // end of a struct/class ... @@ -4327,8 +4231,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount() ; } <ReadBodyIntf>"@end"/[^a-z_A-Z0-9] { // end of Objective C block - current_root->addSubEntry( current ) ; - current=new Entry; + current_root->moveToSubEntryAndRefresh( current ) ; initEntry(); language = current->lang = SrcLangExt_Cpp; // see bug746361 insideObjC=FALSE; @@ -4346,7 +4249,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { current->bodyLine = yyLineNr; lineCount(); - addType(current); + addType(); funcPtrType=yytext; roundCount=0; //current->type += yytext; @@ -4491,7 +4394,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <GetCallType>{BN}*{ID}{BN}*"*" { lineCount(); - addType(current); + addType(); funcPtrType="("; funcPtrType+=yytext; roundCount=0; @@ -4506,7 +4409,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) fullArgString=current->args.copy(); copyArgString=¤t->args; BEGIN( ReadFuncArgType ) ; - //printf(">>> Read function arguments current->argList->count()=%d\n",current->argList->count()); + //printf(">>> Read function arguments current->argList.size()=%d\n",current->argList.size()); } } /* @@ -4719,8 +4622,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <ReadTempArgs>">" { *copyArgString+=*yytext; fullArgString+=*yytext; - //printf("end template list %s\n",copyArgString->data()); - stringToArgumentList(fullArgString,currentArgumentList); + //printf("end template list '%s'\n",copyArgString->data()); + stringToArgumentList(fullArgString,*currentArgumentList); BEGIN( currentArgumentContext ); } <CopyArgRound>"(" { @@ -4872,12 +4775,12 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <FuncQual>{BN}*"const"{BN}* { // const member function lineCount() ; current->args += " const "; - current->argList->constSpecifier=TRUE; + current->argList.constSpecifier=TRUE; } <FuncQual>{BN}*"volatile"{BN}* { // volatile member function lineCount() ; current->args += " volatile "; - current->argList->volatileSpecifier=TRUE; + current->argList.volatileSpecifier=TRUE; } <FuncQual>{BN}*"noexcept"{BN}* { // noexcept qualifier lineCount() ; @@ -4895,25 +4798,25 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FuncQual>{BN}*"&" { current->args += " &"; - current->argList->refQualifier=RefQualifierLValue; + current->argList.refQualifier=RefQualifierLValue; } <FuncQual>{BN}*"&&" { current->args += " &&"; - current->argList->refQualifier=RefQualifierRValue; + current->argList.refQualifier=RefQualifierRValue; } <FuncQual,TrailingReturn>{BN}*"="{BN}*"0"{BN}* { // pure virtual member function lineCount() ; current->args += " = 0"; current->virt = Pure; - current->argList->pureSpecifier=TRUE; + current->argList.pureSpecifier=TRUE; BEGIN(FuncQual); } <FuncQual,TrailingReturn>{BN}*"="{BN}*"delete"{BN}* { // C++11 explicitly delete member lineCount(); current->args += " = delete"; current->spec |= Entry::Delete; - current->argList->isDeleted=TRUE; + current->argList.isDeleted=TRUE; BEGIN(FuncQual); } <FuncQual,TrailingReturn>{BN}*"="{BN}*"default"{BN}* { // C++11 explicitly defaulted constructor/assignment operator @@ -4924,7 +4827,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <FuncQual>{BN}*"->"{BN}* { lineCount(); - current->argList->trailingReturnType = " -> "; + current->argList.trailingReturnType = " -> "; current->args += " -> "; BEGIN(TrailingReturn); } @@ -4933,12 +4836,12 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN(FuncQual); } <TrailingReturn>. { - current->argList->trailingReturnType+=yytext; + current->argList.trailingReturnType+=yytext; current->args+=yytext; } <TrailingReturn>\n { lineCount(); - current->argList->trailingReturnType+=yytext; + current->argList.trailingReturnType+=yytext; current->args+=' '; } <FuncRound,FuncFunc>{BN}*","{BN}* { @@ -5024,9 +4927,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (insideCS && qstrcmp(yytext,"where")==0) { // type constraint for a method - delete current->typeConstr; - current->typeConstr = new ArgumentList; - current->typeConstr->append(new Argument); + current->typeConstr.clear(); + current->typeConstr.push_back(Argument()); lastCSConstraint = YY_START; BEGIN( CSConstraintName ); } @@ -5063,6 +4965,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <OldStyleArgs>{ID} { current->args += yytext; } <OldStyleArgs>"{" { + if (current->argList.empty()) + { + current->argList.noParameters=TRUE; + } current->args = argListToString(current->argList); unput('{'); BEGIN(FuncQual); @@ -5223,9 +5129,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { findAndRemoveWord(current->type,"function"); } - previous = current; - current_root->addSubEntry(current); - current = new Entry ; + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); initEntry(); // Objective C 2.0: Required/Optional section if (previous->spec & (Entry::Optional | Entry::Required)) @@ -5298,16 +5203,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - if (current->sli && previous) // copy special list items + if (!current->sli.empty() && previous) // copy special list items { - QListIterator<ListItemInfo> li(*current->sli); - ListItemInfo *lii; - for (li.toFirst();(lii=li.current());++li) - { - previous->addSpecialListItem(lii->type,lii->itemId); - } - delete current->sli; - current->sli = 0; + previous->sli = current->sli; + current->sli.clear(); } if (previous) previous->endBodyLine=yyLineNr; BEGIN( lastCurlyContext ) ; @@ -5323,9 +5222,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { current->endBodyLine=yyLineNr; - - tempEntry = current; // temporarily switch to the previous entry - current = previous; + // take previous out of current_root and move it into current + current.swap(tempEntry); // remember current + current_root->moveFromSubEntry(previous,current); previous = 0; docBlockContext = SkipCurlyEndDoc; @@ -5368,8 +5267,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //addToBody("}"); if (tempEntry) // we can only switch back to current if no new item was created { - current = tempEntry; - tempEntry = 0; + tempEntry.swap(current); + tempEntry.reset(); } BEGIN( lastCurlyContext ); } @@ -5495,7 +5394,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0) ; current->name.resize(0) ; current->args.resize(0) ; - current->argList->clear(); + current->argList.clear(); BEGIN( FindMembers ) ; } <Bases>";" { @@ -5512,12 +5411,12 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // there can be only one base class here if (!baseName.isEmpty()) { - current->extends->append( - new BaseInfo(baseName,Public,Normal)); + current->extends.push_back( + BaseInfo(baseName,Public,Normal)); baseName.resize(0); } - current_root->addSubEntry( current ) ; - current = new Entry; + current_root->moveToSubEntryAndRefresh( current ) ; + initEntry(); } else { @@ -5525,7 +5424,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->type.resize(0) ; current->name.resize(0) ; current->args.resize(0) ; - current->argList->clear(); + current->argList.clear(); } BEGIN( FindMembers ) ; } @@ -5554,16 +5453,11 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } <CSGeneric>"<" { - if (current->tArgLists==0) - { - current->tArgLists = new QList<ArgumentList>; - current->tArgLists->setAutoDelete(TRUE); - } - ArgumentList *al = new ArgumentList; + ArgumentList al; // check bug 612858 before enabling the next line //current->spec |= Entry::Template; - current->tArgLists->append(al); - currentArgumentList = al; + current->tArgLists.push_back(al); + currentArgumentList = ¤t->tArgLists.back(); templateStr="<"; current->name += "<"; fullArgString = templateStr; @@ -5601,7 +5495,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name += yytext; } <CompoundName>{SCOPENAME}{BN}*";" { // forward declaration - if (current->tArgLists && current->tArgLists->count()>0) + if (!current->tArgLists.empty()) { // found a forward template declaration, this has // a purpose of its own @@ -5615,8 +5509,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) prependScope(); } current->spec|=Entry::ForwardDecl; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); } else if (insideIDL && (((current_root->spec & (Entry::Interface | @@ -5637,8 +5530,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) : Entry::INCLUDED_SERVICE_SEC; // current->section = Entry::MEMBERDOC_SEC; current->spec &= ~(Entry::Interface|Entry::Service); // FIXME: horrible: Interface == Gettable, so need to clear it - actually we're mixing values from different enums in this case... granted only Optional and Interface are actually valid in this context but urgh... - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); } unput(';'); @@ -5722,7 +5614,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - addType(current); + addType(); current->name = yytext; current->name = current->name.stripWhiteSpace(); lineCount(); @@ -5777,9 +5669,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else if (insideCS && qstrcmp(yytext,"where")==0) // C# type constraint { - delete current->typeConstr; - current->typeConstr = new ArgumentList; - current->typeConstr->append(new Argument); + current->typeConstr.clear(); + current->typeConstr.push_back(Argument()); lastCSConstraint = YY_START; BEGIN( CSConstraintName ); } @@ -5839,7 +5730,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) BEGIN( CopyArgComment ); } <CSConstraintType,CSConstraintName>"#" { // artificially inserted token to signal end of comment block - current->typeConstr->getLast()->docs = fullArgString; + current->typeConstr.back().docs = fullArgString; } <CSConstraintType>"{" { // end of type constraint reached // parse documentation of the constraints @@ -5857,24 +5748,24 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <CSConstraintName>{ID} { // parameter name - current->typeConstr->getLast()->name=yytext; + current->typeConstr.back().name=yytext; } <CSConstraintType>"where" { // another constraint for a different param - current->typeConstr->append(new Argument); + current->typeConstr.push_back(Argument()); BEGIN( CSConstraintName ); } <CSConstraintType>({ID}".")*{ID}("<"{ID}">")?("()")? { - if (current->typeConstr->getLast()->type.isEmpty()) + if (current->typeConstr.back().type.isEmpty()) // first type constraint for this parameter { - current->typeConstr->getLast()->type=yytext; + current->typeConstr.back().type=yytext; } else // new type constraint for same parameter { - QCString name = current->typeConstr->getLast()->name; - current->typeConstr->append(new Argument); - current->typeConstr->getLast()->name=name; - current->typeConstr->getLast()->type=yytext; + QCString name = current->typeConstr.back().name; + current->typeConstr.push_back(Argument()); + current->typeConstr.back().name=name; + current->typeConstr.back().type=yytext; } } <CSConstraintName,CSConstraintType>\n { @@ -6056,9 +5947,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (insideCS && baseScope.stripWhiteSpace()=="where") { // type constraint for a class - delete current->typeConstr; - current->typeConstr = new ArgumentList; - current->typeConstr->append(new Argument); + current->typeConstr.clear(); + current->typeConstr.push_back(Argument()); lastCSConstraint = YY_START; BEGIN( CSConstraintName ); } @@ -6165,6 +6055,19 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <Specialization>"typename"{BN}+ { lineCount(); } <Specialization>"(" { *specName += *yytext; roundCount++; } <Specialization>")" { *specName += *yytext; roundCount--; } + +<Specialization>"\\\\" { *specName += *yytext;} +<Specialization>"\\'" { *specName += *yytext;} +<Specialization>"\\\"" { *specName += *yytext;} +<Specialization>"'" { *specName += *yytext;BEGIN(SpecializationSingleQuote);} +<Specialization>"\"" { *specName += *yytext;BEGIN(SpecializationDoubleQuote);} +<SpecializationSingleQuote,SpecializationDoubleQuote>"\\\\" { *specName += *yytext;} +<SpecializationSingleQuote>"\\'" { *specName += *yytext;} +<SpecializationSingleQuote>"'" { *specName += *yytext; BEGIN(Specialization);} +<SpecializationDoubleQuote>"\\\"" { *specName += *yytext;} +<SpecializationDoubleQuote>"\"" { *specName += *yytext; BEGIN(Specialization);} +<SpecializationSingleQuote,SpecializationDoubleQuote>. { *specName += *yytext;} + <Specialization>. { *specName += *yytext; } @@ -6188,8 +6091,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->name = removeRedundantWhiteSpace(current->name); if (!baseName.isEmpty()) { - current->extends->append( - new BaseInfo(baseName,baseProt,baseVirt) + current->extends.push_back( + BaseInfo(baseName,baseProt,baseVirt) ); } if ((current->spec & (Entry::Interface|Entry::Struct)) || @@ -6230,8 +6133,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) current->startColumn = yyColNr; current->name = removeRedundantWhiteSpace(current->name); if (!baseName.isEmpty()) - current->extends->append( - new BaseInfo(baseName,baseProt,baseVirt) + current->extends.push_back( + BaseInfo(baseName,baseProt,baseVirt) ); curlyCount=0; if (insideObjC) @@ -6466,7 +6369,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //current->type.resize(0); //current->name.resize(0); //current->args.resize(0); - //current->argList->clear(); + //current->argList.clear(); //curlyCount=0; //BEGIN( SkipCurlyBlock ); @@ -6546,8 +6449,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <SliceSequenceName>";" { current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -6577,8 +6479,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) <SliceDictionaryName>";" { current->section = Entry::VARIABLE_SEC; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); initEntry(); BEGIN(FindMembers); } @@ -6871,16 +6772,16 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } <PrototypeQual>{B}*"const"{B}* { current->args += " const "; - current->argList->constSpecifier=TRUE; + current->argList.constSpecifier=TRUE; } <PrototypeQual>{B}*"volatile"{B}* { current->args += " volatile "; - current->argList->volatileSpecifier=TRUE; + current->argList.volatileSpecifier=TRUE; } <PrototypeQual>{B}*"="{B}*"0"{B}* { current->args += " = 0"; current->virt = Pure; - current->argList->pureSpecifier=TRUE; + current->argList.pureSpecifier=TRUE; } <PrototypeQual>"throw"{B}*"(" { current->exception = "throw("; @@ -7009,11 +6910,15 @@ static void newEntry() // already added to current_root, so we should not add it again // (see bug723314) { - current_root->addSubEntry(current); + previous = current.get(); + current_root->moveToSubEntryAndRefresh(current); + } + else + { + previous = current.get(); + tempEntry.swap(current); + tempEntry.reset(); } - tempEntry = 0; - previous = current; - current = new Entry ; initEntry(); } @@ -7025,7 +6930,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) int lineNr = brief ? current->briefLine : current->docLine; // line of block start // fill in inbodyFile && inbodyLine the first time, see bug 633891 - Entry *docEntry = docBlockInBody && previous ? previous : current; + Entry *docEntry = docBlockInBody && previous ? previous : current.get(); if (docBlockInBody && docEntry && docEntry->inbodyLine==-1) { docEntry->inbodyFile = yyFileName; @@ -7037,7 +6942,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) QCString processedDoc = preprocessCommentBlock(stripIndentation(doc),yyFileName,lineNr); while (parseCommentBlock( g_thisParser, - docBlockInBody && previous ? previous : current, + docBlockInBody && previous ? previous : current.get(), processedDoc, // text yyFileName, // file lineNr, // line of block start @@ -7071,17 +6976,15 @@ static void handleCommentBlock(const QCString &doc,bool brief) } } -static void handleParametersCommentBlocks(ArgumentList *al) +static void handleParametersCommentBlocks(ArgumentList &al) { //printf(">>>>>>> handleParametersCommentBlocks()\n"); - ArgumentListIterator ali(*al); - Argument *a; - for (ali.toFirst();(a=ali.current());++ali) + for (Argument &a : al) { //printf(" Param %s docs=%s\n",a->name.data(),a->docs.data()); - if (!a->docs.isEmpty()) + if (!a.docs.isEmpty()) { - if (!a->name && a->type == "...") a->name= "..."; + if (!a.name && a.type == "...") a.name= "..."; int position=0; bool needsEntry; @@ -7097,8 +7000,8 @@ static void handleParametersCommentBlocks(ArgumentList *al) //printf("handleParametersCommentBlock [%s]\n",doc.data()); while (parseCommentBlock( g_thisParser, - current, - a->docs, // text + current.get(), + a.docs, // text yyFileName, // file current->docLine, // line of block start FALSE, @@ -7117,7 +7020,7 @@ static void handleParametersCommentBlocks(ArgumentList *al) { newEntry(); } - a->docs = current->doc; + a.docs = current->doc; // restore context current->doc = orgDoc; @@ -7131,12 +7034,10 @@ static void handleParametersCommentBlocks(ArgumentList *al) //---------------------------------------------------------------------------- -static void parseCompounds(Entry *rt) +static void parseCompounds(const std::unique_ptr<Entry> &rt) { //printf("parseCompounds(%s)\n",rt->name.data()); - EntryListIterator eli(*rt->children()); - Entry *ce; - for (;(ce=eli.current());++eli) + for (const auto &ce : rt->children()) { if (!ce->program.isEmpty()) { @@ -7153,29 +7054,22 @@ static void parseCompounds(Entry *rt) BEGIN( FindFields ) ; else BEGIN( FindMembers ) ; - current_root = ce ; + current_root = ce.get() ; yyFileName = ce->fileName; //setContext(); yyLineNr = ce->startLine ; yyColNr = ce->startColumn ; insideObjC = ce->lang==SrcLangExt_ObjC; //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC); - //current->reset(); - if (current) delete current; - current = new Entry; + current = std::make_unique<Entry>(); gstat = FALSE; initEntry(); // deep copy group list from parent (see bug 727732) static bool autoGroupNested = Config_getBool(GROUP_NESTED_COMPOUNDS); - if (autoGroupNested && rt->groups && ce->section!=Entry::ENUM_SEC && !(ce->spec&Entry::Enum)) + if (autoGroupNested && ce->section!=Entry::ENUM_SEC && !(ce->spec&Entry::Enum)) { - QListIterator<Grouping> gli(*rt->groups); - Grouping *g; - for (;(g=gli.current());++gli) - { - ce->groups->append(new Grouping(*g)); - } + ce->groups = rt->groups; } int ni=ce->name.findRev("::"); if (ni==-1) ni=0; else ni+=2; @@ -7229,15 +7123,15 @@ static void parseCompounds(Entry *rt) //memberGroupId = DOX_NOGROUP; //memberGroupRelates.resize(0); //memberGroupInside.resize(0); - Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,ce->name); + QCString name = ce->name; + Doxygen::docGroup.enterCompound(yyFileName,yyLineNr,name); scannerYYlex() ; g_lexInit=TRUE; //forceEndGroup(); - Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,ce->name); + Doxygen::docGroup.leaveCompound(yyFileName,yyLineNr,name); - delete current; current=0; ce->program.resize(0); @@ -7254,7 +7148,7 @@ static void parseCompounds(Entry *rt) static void parseMain(const char *fileName, const char *fileBuf, - Entry *rt, + const std::unique_ptr<Entry> &rt, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { @@ -7270,8 +7164,8 @@ static void parseMain(const char *fileName, mtype = Method; gstat = FALSE; virt = Normal; - current_root = rt; - global_root = rt; + current_root = rt.get(); + global_root = rt.get(); inputFile.setName(fileName); if (inputFile.open(IO_ReadOnly)) { @@ -7293,18 +7187,17 @@ static void parseMain(const char *fileName, rt->lang = language; msg("Parsing file %s...\n",yyFileName.data()); - current_root = rt ; + current_root = rt.get() ; initParser(); Doxygen::docGroup.enterFile(yyFileName,yyLineNr); - current = new Entry; + current = std::make_unique<Entry>(); //printf("current=%p current_root=%p\n",current,current_root); int sec=guessSection(yyFileName); if (sec) { current->name = yyFileName; current->section = sec; - current_root->addSubEntry(current); - current = new Entry; + current_root->moveToSubEntryAndRefresh(current); } current->reset(); initEntry(); @@ -7329,18 +7222,7 @@ static void parseMain(const char *fileName, //forceEndGroup(); Doxygen::docGroup.leaveFile(yyFileName,yyLineNr); - //if (depthIf>0) - //{ - // warn(yyFileName,yyLineNr,"Documentation block ended in the middle of a conditional section!"); - //} - rt->program.resize(0); - if (rt->children()->contains(current)==0) - // it could be that current is already added as a child to rt, so we - // only delete it if this is not the case. See bug 635317. - { - delete current; current=0; - } parseCompounds(rt); @@ -7348,6 +7230,14 @@ static void parseMain(const char *fileName, anonNSCount++; + // add additional entries that were created during processing + for (auto &kv: g_outerScopeEntries) + { + //printf(">>> adding '%s' to scope '%s'\n",kv.second->name.data(),kv.first->name.data()); + kv.first->moveToSubEntryAndKeep(kv.second); + } + g_outerScopeEntries.clear(); + } } @@ -7396,6 +7286,7 @@ static void parsePrototype(const QCString &text) inputString = orgInputString; inputPosition = orgInputPosition; + //printf("**** parsePrototype end\n"); } @@ -7438,7 +7329,7 @@ void CLanguageScanner::finishTranslationUnit() void CLanguageScanner::parseInput(const char *fileName, const char *fileBuf, - Entry *root, + const std::unique_ptr<Entry> &root, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { |