diff --git a/src/dparse/ast.d b/src/dparse/ast.d index 35e287d7..be05a453 100644 --- a/src/dparse/ast.d +++ b/src/dparse/ast.d @@ -2932,6 +2932,14 @@ final class PrimaryExpression : ExpressionNode /** */ Arguments arguments; /** */ InterpolatedString interpolatedString; mixin OpEquals; + + IdType builtinType() inout @property @safe nothrow @nogc pure + { + if (type) + if (auto t2 = type.type2) + return t2.builtinType ? t2.builtinType : IdType.init; + return IdType.init; + } } /// @@ -4141,6 +4149,30 @@ unittest // issue #398: Support extern(C++, ) checkText(ns[2], `"baz"`); } +unittest // issue #526 +{ + import dparse.formatter, dparse.lexer, dparse.parser, dparse.rollback_allocator; + string src = q{enum E : int*[0] { a = int*[0].init }}; + final class Test : ASTVisitor + { + } + RollbackAllocator ra; + auto cf = LexerConfig("", StringBehavior.source); + auto ca = StringCache(16); + Module m = ParserConfig(getTokensForParser(src, cf, &ca), "", &ra).parseModule(); + auto t = new Test; + t.visit(m); + assert(m.declarations.length == 1); + auto ed = m.declarations[0].enumDeclaration; + assert(ed); + auto type = ed.type; + auto app = appender!string(); + auto formatter = new Formatter!(typeof(app))(app); + formatter.format(type); + assert(app[] == "int*[0]"); + assert(ed.type.typeSuffixes.length == 2); +} + unittest // Differentiate between no and empty DDOC comments, e.g. for DDOC unittests { import dparse.lexer, dparse.parser, dparse.rollback_allocator; diff --git a/src/dparse/parser.d b/src/dparse/parser.d index d2ba1c46..5dce6553 100644 --- a/src/dparse/parser.d +++ b/src/dparse/parser.d @@ -5848,9 +5848,9 @@ class Parser * $(GRAMMAR $(RULEDEF primaryExpression): * $(RULE identifierOrTemplateInstance) * | $(LITERAL '.') $(RULE identifierOrTemplateInstance) - * | $(RULE typeConstructor) $(LITERAL '$(LPAREN)') $(RULE basicType) $(LITERAL '$(RPAREN)') $(LITERAL '.') $(LITERAL Identifier) - * | $(RULE basicType) $(LITERAL '.') $(LITERAL Identifier) - * | $(RULE basicType) $(RULE arguments) + * | $(RULE typeConstructor) $(LITERAL '$(LPAREN)') $(RULE type) $(LITERAL '$(RPAREN)') $(LITERAL '.') $(LITERAL Identifier) + * | $(RULE builtinType) $(RULE typeSuffix)* $(LITERAL '.') $(LITERAL Identifier) + * | $(RULE builtinType) $(RULE typeSuffix)* $(RULE arguments) * | $(RULE typeofExpression) * | $(RULE typeidExpression) * | $(RULE vector) @@ -5923,18 +5923,19 @@ class Parser break; } foreach (B; BasicTypes) { case B: } - node.basicType = advance(); + { + node.type = parseType(); if (currentIs(tok!".")) { advance(); - const t = expect(tok!"identifier"); - if (t !is null) - node.primary = *t; + if (const ident = expect(tok!"identifier")) + node.primary = *ident; } else if (currentIs(tok!"(")) mixin(parseNodeQ!(`node.arguments`, `Arguments`)); else goto default; - break; + } + break; case tok!"function": case tok!"delegate": case tok!"{": diff --git a/test/pass_files/issue0526.d b/test/pass_files/issue0526.d new file mode 100644 index 00000000..28501f69 --- /dev/null +++ b/test/pass_files/issue0526.d @@ -0,0 +1 @@ +enum E : int*[0] { a = int*[0].init }