@@ -424,7 +424,7 @@ private List<TopLevelItem> parseTopLevelItem(List<CppLexerToken> leadingComments
424424 && !tokens .get (pos + 1 ).isKeyword ("class" ) && !tokens .get (pos + 1 ).isKeyword ("struct" )) {
425425 return parseFunctionOrVariable (leadingComments , templateParams , true );
426426 }
427- return List . of ( parseTypeDef (leadingComments , templateParams ) );
427+ return parseTypeDef (leadingComments , templateParams );
428428 }
429429 if (checkKeyword ("enum" )) {
430430 return List .of (parseEnumDecl (leadingComments ));
@@ -775,7 +775,7 @@ private String parseTemplateParamName() {
775775 * necessary by any semantic pass; if member visibility ever matters,
776776 * this is the place to start tracking it).
777777 */
778- private TypeDef parseTypeDef (List <CppLexerToken > leadingComments , List <String > templateParams ) {
778+ private List < TopLevelItem > parseTypeDef (List <CppLexerToken > leadingComments , List <String > templateParams ) {
779779 CppLexerToken start = peek ();
780780 String kind = checkKeyword ("class" ) ? "class" : "struct" ;
781781 advance ();
@@ -830,8 +830,8 @@ else if (checkOp(">>")) {
830830 // Also handles "template<typename T = int> class Container;" with default args.
831831 if (checkPunct (";" )) {
832832 advance ();
833- return new TypeDef (kind , name , templateParams , List .of (), List .of (),
834- start .line (), start .col (), leadingComments );
833+ return List . of ( new TypeDef (kind , name , templateParams , List .of (), List .of (),
834+ start .line (), start .col (), leadingComments )) ;
835835 }
836836
837837 List <String > baseClasses = new ArrayList <>();
@@ -862,7 +862,24 @@ else if (checkOp(">>")) {
862862 // hard-requiring strict C++ grammar here.
863863 matchPunct (";" );
864864
865- return new TypeDef (kind , name , templateParams , baseClasses , members , start .line (), start .col (), leadingComments );
865+ TypeDef typeDef = new TypeDef (kind , name , templateParams , baseClasses , members , start .line (), start .col (), leadingComments );
866+ // Trailing declarator: "class Foo { ... } *ptr;" or "} instance;"
867+ if (!matchPunct (";" ) && !isAtEnd () && !checkPunct ("}" )) {
868+ int ptrDepth = 0 ;
869+ while (matchOp ("*" ) || matchPunct ("*" )) ptrDepth ++;
870+ if (peek ().type () == CppLexerTokenType .IDENTIFIER ) {
871+ CppLexerToken varTok = advance ();
872+ Expr init = null ;
873+ if (matchPunct ("=" )) init = parseExpr ();
874+ expectPunct (";" );
875+ TypeRef varType = new NamedType (name , List .of (), ptrDepth , false , false , false );
876+ VariableDecl varDecl = new VariableDecl (varType , varTok .text (), List .of (), init ,
877+ false , false , varTok .line (), varTok .col (), List .of ());
878+ return List .of (typeDef , varDecl );
879+ }
880+ matchPunct (";" );
881+ }
882+ return List .of (typeDef );
866883 }
867884
868885 /** "public BaseName" / "private BaseName" / "protected BaseName" / bare "BaseName". */
@@ -981,7 +998,7 @@ private List<TopLevelItem> parseClassMember(List<CppLexerToken> leadingComments,
981998 && tokens .get (pos + 2 ).type () == CppLexerTokenType .IDENTIFIER ) {
982999 return parseFunctionOrVariable (leadingComments , templateParams , false );
9831000 }
984- return List . of ( parseTypeDef (leadingComments , templateParams ) );
1001+ return parseTypeDef (leadingComments , templateParams );
9851002 }
9861003 if (checkKeyword ("enum" )) {
9871004 return List .of (parseEnumDecl (leadingComments ));
@@ -3693,7 +3710,7 @@ private List<Statement> parseStatementOrMultiDecl(List<CppLexerToken> leadingCom
36933710 new Identifier ("" , sk .line (), sk .col (), List .of ()),
36943711 sk .line (), sk .col (), leadingComments ));
36953712 }
3696- TypeDef td = parseTypeDef (leadingComments , List .of ());
3713+ List < TopLevelItem > _tdItems = parseTypeDef (leadingComments , List .of ()); TypeDef td = ( TypeDef ) _tdItems . get ( 0 );
36973714 matchPunct (";" );
36983715 // Emit struct as verbatim text via CodeGen
36993716 String structCode = processing .mode .cpp .CodeGen .generateNode (td , 0 ).stripTrailing ();
@@ -3802,7 +3819,7 @@ private Statement parseStatement(List<CppLexerToken> leadingComments) {
38023819 && pos + 1 < tokens .size ()
38033820 && (tokens .get (pos + 1 ).type () == CppLexerTokenType .IDENTIFIER
38043821 || tokens .get (pos + 1 ).isPunct ("{" ))) {
3805- TypeDef td = parseTypeDef (leadingComments , List .of ());
3822+ List < TopLevelItem > _tdItems = parseTypeDef (leadingComments , List .of ()); TypeDef td = ( TypeDef ) _tdItems . get ( 0 );
38063823 matchPunct (";" );
38073824 return new ExprStatement (new Identifier ("" , td .line (), td .col (), List .of ()), td .line (), td .col (), leadingComments );
38083825 }
0 commit comments