Skip to content

Commit 8ec892c

Browse files
committed
Parser: support trailing declarators after class/struct body (} *ptr;)
1 parent f82ef48 commit 8ec892c

1 file changed

Lines changed: 25 additions & 8 deletions

File tree

src/java/Parser.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)