@@ -421,19 +421,41 @@ namespace {
421421
422422static Token *splitDefinitionFromTypedef (Token *tok, nonneg int *unnamedCount)
423423{
424- Token *tok1;
425424 std::string name;
426425 bool isConst = false ;
426+ Token *tok1 = tok->next ();
427427
428- if (tok->next ()->str () == " const" ) {
429- tok->deleteNext ();
428+ // skip const if present
429+ if (tok1->str () == " const" ) {
430+ tok1->deleteThis ();
430431 isConst = true ;
431432 }
432433
433- if (tok->strAt (2 ) == " {" ) { // unnamed
434- tok1 = tok->linkAt (2 );
434+ // skip "class|struct|union|enum"
435+ tok1 = tok1->next ();
436+
437+ const bool hasName = Token::Match (tok1, " %name%" );
438+
439+ // skip name
440+ if (hasName) {
441+ name = tok1->str ();
442+ tok1 = tok1->next ();
443+ }
444+
445+ // skip base classes if present
446+ if (tok1->str () == " :" ) {
447+ tok1 = tok1->next ();
448+ while (tok1 && tok1->str () != " {" )
449+ tok1 = tok1->next ();
450+ if (!tok1)
451+ return nullptr ;
452+ }
453+
454+ // skip to end
455+ tok1 = tok1->link ();
435456
436- if (tok1 && tok1->next ()) {
457+ if (!hasName) { // unnamed
458+ if (tok1->next ()) {
437459 // use typedef name if available
438460 if (Token::Match (tok1->next (), " %type%" ))
439461 name = tok1->next ()->str ();
@@ -442,23 +464,6 @@ static Token *splitDefinitionFromTypedef(Token *tok, nonneg int *unnamedCount)
442464 tok->next ()->insertToken (name);
443465 } else
444466 return nullptr ;
445- } else if (tok->strAt (3 ) == " :" ) {
446- tok1 = tok->tokAt (4 );
447- while (tok1 && tok1->str () != " {" )
448- tok1 = tok1->next ();
449- if (!tok1)
450- return nullptr ;
451-
452- tok1 = tok1->link ();
453-
454- name = tok->strAt (2 );
455- } else { // has a name
456- tok1 = tok->linkAt (3 );
457-
458- if (!tok1)
459- return nullptr ;
460-
461- name = tok->strAt (2 );
462467 }
463468
464469 tok1->insertToken (" ;" );
@@ -623,21 +628,11 @@ void Tokenizer::simplifyTypedef()
623628
624629 // pull struct, union, enum or class definition out of typedef
625630 // use typedef name for unnamed struct, union, enum or class
626- if (Token::Match (tok->next (), " const| struct|enum|union|class %type%| {" )) {
631+ if (Token::Match (tok->next (), " const| struct|enum|union|class %type%| {|: " )) {
627632 Token *tok1 = splitDefinitionFromTypedef (tok, &mUnnamedCount );
628633 if (!tok1)
629634 continue ;
630635 tok = tok1;
631- } else if (Token::Match (tok->next (), " const| struct|class %type% :" )) {
632- Token *tok1 = tok;
633- while (tok1 && tok1->str () != " ;" && tok1->str () != " {" )
634- tok1 = tok1->next ();
635- if (tok1 && tok1->str () == " {" ) {
636- tok1 = splitDefinitionFromTypedef (tok, &mUnnamedCount );
637- if (!tok1)
638- continue ;
639- tok = tok1;
640- }
641636 }
642637
643638 /* * @todo add support for union */
@@ -2003,25 +1998,31 @@ bool Tokenizer::simplifyUsing()
20031998 // Move struct defined in using out of using.
20041999 // using T = struct t { }; => struct t { }; using T = struct t;
20052000 // fixme: this doesn't handle attributes
2006- if (Token::Match (start, " struct|union|enum %name%| {" )) {
2007- if (start->strAt (1 ) != " {" ) {
2008- Token *structEnd = start->linkAt (2 );
2009- structEnd->insertToken (" ;" , " " );
2010- TokenList::copyTokens (structEnd->next (), tok, start->next ());
2011- usingStart = structEnd->tokAt (2 );
2012- nameToken = usingStart->next ();
2013- if (usingStart->strAt (2 ) == " =" )
2014- start = usingStart->tokAt (3 );
2015- else
2016- start = usingStart->linkAt (2 )->tokAt (3 );
2017- usingEnd = findSemicolon (start);
2018- tok->deleteThis ();
2019- tok->deleteThis ();
2020- tok->deleteThis ();
2021- tok = usingStart;
2022- } else {
2023- Token *structEnd = start->linkAt (1 );
2024- structEnd->insertToken (" ;" , " " );
2001+ if (Token::Match (start, " class|struct|union|enum %name%| {|:" )) {
2002+ Token *structEnd = start->tokAt (1 );
2003+ const bool hasName = Token::Match (structEnd, " %name%" );
2004+
2005+ // skip over name if present
2006+ if (hasName)
2007+ structEnd = structEnd->next ();
2008+
2009+ // skip over base class information
2010+ if (structEnd->str () == " :" ) {
2011+ structEnd = structEnd->next (); // skip over ":"
2012+ while (structEnd && structEnd->str () != " {" )
2013+ structEnd = structEnd->next ();
2014+ if (!structEnd)
2015+ continue ;
2016+ }
2017+
2018+ // use link to go to end
2019+ structEnd = structEnd->link ();
2020+
2021+ // add ';' after end of struct
2022+ structEnd->insertToken (" ;" , " " );
2023+
2024+ // add name for anonymous struct
2025+ if (!hasName) {
20252026 std::string newName;
20262027 if (structEnd->strAt (2 ) == " ;" )
20272028 newName = name;
@@ -2030,19 +2031,23 @@ bool Tokenizer::simplifyUsing()
20302031 TokenList::copyTokens (structEnd->next (), tok, start);
20312032 structEnd->tokAt (5 )->insertToken (newName, " " );
20322033 start->insertToken (newName, " " );
2034+ } else
2035+ TokenList::copyTokens (structEnd->next (), tok, start->next ());
20332036
2034- usingStart = structEnd->tokAt (2 );
2035- nameToken = usingStart->next ();
2036- if (usingStart->strAt (2 ) == " =" )
2037- start = usingStart->tokAt (3 );
2038- else
2039- start = usingStart->linkAt (2 )->tokAt (3 );
2040- usingEnd = findSemicolon (start);
2041- tok->deleteThis ();
2042- tok->deleteThis ();
2043- tok->deleteThis ();
2044- tok = usingStart;
2045- }
2037+ // add using after end of struct
2038+ usingStart = structEnd->tokAt (2 );
2039+ nameToken = usingStart->next ();
2040+ if (usingStart->strAt (2 ) == " =" )
2041+ start = usingStart->tokAt (3 );
2042+ else
2043+ start = usingStart->linkAt (2 )->tokAt (3 );
2044+ usingEnd = findSemicolon (start);
2045+
2046+ // delete original using before struct
2047+ tok->deleteThis ();
2048+ tok->deleteThis ();
2049+ tok->deleteThis ();
2050+ tok = usingStart;
20462051 }
20472052
20482053 // remove 'typename' and 'template'
@@ -2131,7 +2136,7 @@ bool Tokenizer::simplifyUsing()
21312136 if (Token::Match (type, " %type%" ))
21322137 type = type->next ();
21332138 } else if (Token::Match (type, " %type%" )) {
2134- while (Token::Match (type, " const|struct|union|enum %type%" ) ||
2139+ while (Token::Match (type, " const|class| struct|union|enum %type%" ) ||
21352140 (type->next () && type->next ()->isStandardType ()))
21362141 type = type->next ();
21372142
0 commit comments