This is an archive of the discontinued LLVM Phabricator instance.

[pseudo] Eliminate multiple-specified-types ambiguities in the grammar.
Changes PlannedPublic

Authored by sammccall on Jul 20 2022, 12:36 AM.

Details

Reviewers
hokein
Summary

Motivating case: foo bar; is not a declaration of nothing with foo and bar
both types.

This is a common and critical ambiguity, and I expect eliminating it in the
grammar is more efficient than using guards (without caching).

Diff Detail

Event Timeline

sammccall created this revision.Jul 20 2022, 12:36 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 20 2022, 12:36 AM
sammccall requested review of this revision.Jul 20 2022, 12:36 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 20 2022, 12:36 AM

I'm not sure that eliminating this in the grammar is the right technique vs guards, appreciate your thoughts.

On clangd/AST.cpp, this reduces ambiguities from 1748->1400 (20%).

sammccall planned changes to this revision.Jul 20 2022, 2:07 AM

As discussed offline:

We agree on the goal of disallowing duplicate types in decl-specifier-seq, but the grammar changes are too intrusive if a guard-based approach can work instead.
The concern with guards on seq nodes is duplicate work (a tree walk at every level).
Since ForestNodes are immutable and reasonable in number we can introduce fairly cheap caching, e.g. of whether a decl-specifier[-seq] contains an exclusive type definition. This is a reusable building block for guards etc, so we should build it into the contract.

The other idea I was playing with of guarding simple-declaration := decl-specifier-seq /*no declarators*/ ; by requiring the decl-specifier-seq to declare a type (disallow "declaration declares nothing") is inferior as a) the code is technically legal, b) it doesn't address std::string x; misparsing as Type{std} Type{::string} Declarator{x};.