86 Commits

Author SHA1 Message Date
Kazu Hirata
c60ac50939 [clang-tools-extra] Use llvm::to_underlying (NFC) 2023-12-09 17:34:10 -08:00
Kazu Hirata
81e149aab9 Replace None with std::nullopt in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-05-12 18:33:26 -07:00
Kazu Hirata
caa99a01f5 Use llvm::popcount instead of llvm::countPopulation(NFC) 2023-01-22 12:48:51 -08:00
Martin Storsjö
d3da9067d1 [CMake] Allow setting the location of host tools with LLVM_NATIVE_TOOL_DIR
This avoids having to specify the location of all individual tools.
In current builds, one may want to specify LLVM_TABLEGEN, CLANG_TABLEGEN,
LLDB_TABLEGEN, LLVM_CONFIG_PATH, CLANG_PSEUDO_GEN and
CLANG_TIDY_CONFUSABLE_CHARS_GEN; specifying just the base directory
containing all of them is much more convenient.

Factorize the code for setting up use of a tool that is used during
the build (which either is newly built in the same build, or
built in a separate nested cmake build - when cross compiling or
when e.g. optimized tablegen is requested - or used from an existing
prebuilt binary).

Differential Revision: https://reviews.llvm.org/D131052
2023-01-18 23:56:15 +02:00
Joe Loser
a288d7f937 [llvm][ADT] Replace uses of makeMutableArrayRef with deduction guides
Similar to how `makeArrayRef` is deprecated in favor of deduction guides, do the
same for `makeMutableArrayRef`.

Once all of the places in-tree are using the deduction guides for
`MutableArrayRef`, we can mark `makeMutableArrayRef` as deprecated.

Differential Revision: https://reviews.llvm.org/D141814
2023-01-16 14:49:37 -07:00
serge-sans-paille
984b800a03
Move from llvm::makeArrayRef to ArrayRef deduction guides - last part
This is a follow-up to https://reviews.llvm.org/D140896, split into
several parts as it touches a lot of files.

Differential Revision: https://reviews.llvm.org/D141298
2023-01-10 11:47:43 +01:00
Kazu Hirata
f71ffd3b73 [clang-tools-extra] Use std::optional instead of llvm::Optional (NFC)
This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to clean up the "using" declarations, #include
"llvm/ADT/Optional.h", etc.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07 20:19:42 -08:00
Kazu Hirata
71f557355d [clang-tools-extra] Add #include <optional> (NFC)
This patch adds #include <optional> to those files containing
llvm::Optional<...> or Optional<...>.

I'll post a separate patch to actually replace llvm::Optional with
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07 20:02:20 -08:00
Kazu Hirata
2c675be9b2 [clang-tools-extra] Use std::optional instead of llvm::Optional (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-02 16:17:40 -08:00
Fangrui Song
b0de363024 [clang] Remove uses of ::testing::Matcher<const Optional<T> &>
Change a few functions (getCheckTraversalKind, some clang/Tooling/ API, etc)
from llvm::Optional to std::optional.
2022-12-14 06:42:35 +00:00
Kazu Hirata
7c2b77368f [clang-tools-extra] Use std::nullopt instead of None in comments (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04 17:40:28 -08:00
Kazu Hirata
059a23c0f0 [clang-tools-extra] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03 11:54:50 -08:00
Kazu Hirata
32aa35b504 Drop empty string literals from static_assert (NFC)
Identified with modernize-unary-static-assert.
2022-09-03 11:17:47 -07:00
Sam McCall
56c54cf66b [pseudo] Placeholder disambiguation strategy: always choose second
Mostly mechanics here. Interesting decisions:
 - apply disambiguation in-place instead of copying the forest
   debatable, but even the final tree size is significant
 - split decide/apply into different functions - this allows the hard part
   (decide) to be tested non-destructively and combined with HTML forest easily
 - add non-const accessors to forest to enable apply
 - unit tests but no lit tests: my plan is to test actual C++ disambiguation
   heuristics with lit, generic disambiguation mechanics without the C++ grammar

Differential Revision: https://reviews.llvm.org/D132487
2022-08-26 13:16:09 +02:00
Sam McCall
bd5cc6575b [pseudo] Start rules are _ := start-symbol EOF, improve recovery.
Previously we were calling glrRecover() ad-hoc at the end of input.
Two main problems with this:
 - glrRecover() on two separate code paths is inelegant
 - We may have to recover several times in succession (e.g. to exit from
   nested scopes), so we need a loop at end-of-file
Having an actual shift action for an EOF terminal allows us to handle
both concerns in the main shift/recover/reduce loop.

This revealed a recovery design bug where recovery could enter a loop by
repeatedly choosing the same parent to identically recover from.
Addressed this by allowing each node to be used as a recovery base once.

Differential Revision: https://reviews.llvm.org/D130550
2022-08-19 16:49:37 +02:00
Haojian Wu
e32799d1d6 [pseudo] NFC, remove redundant ; 2022-08-19 15:55:19 +02:00
Sam McCall
605035bf45 [pseudo] Changes omitted from previous commit 2022-08-19 15:15:37 +02:00
Sam McCall
2cc7463c85 [pseudo] Perform unconstrained reduction prior to recovery.
Our GLR uses lookahead: only perform reductions that might be consumed by the
shift immediately following. However when shift fails and so reduce is followed
by recovery instead, this restriction is incorrect and leads to missing heads.

In turn this means certain recovery strategies can't be made to work. e.g.
```
ns := NAMESPACE { namespace-body } [recover=Skip]
ns-body := namespace_opt
```
When `namespace { namespace {` is parsed, we can recover the inner `ns` (using
the `Skip` strategy to ignore the missing `}`). However this `namespace` will
not be reduced to a `namespace-body` as EOF is not in the follow-set, and so we
are unable to recover the outer `ns`.

This patch fixes this by tracking which heads were produced by constrained
reduce, and discarding and rebuilding them before performing recovery.

This is a prerequisite for the `Skip` strategy mentioned above, though there are
some other limitations we need to address too.

Reviewed By: hokein

Differential Revision: https://reviews.llvm.org/D130523
2022-08-19 15:07:36 +02:00
Kazu Hirata
2b43bd0bd9 Remove unused forward declarations (NFC) 2022-08-13 12:55:47 -07:00
Haojian Wu
bf0e219d04 [pseudo] Use C++17 variant to simplify the DirectiveTree::Chunk class, NFC.
Differential Revision: https://reviews.llvm.org/D131396
2022-08-11 14:27:38 +02:00
Haojian Wu
c2c5c39c40 [pseudo] Fix a suspicious usage of sizeof(this).
It should be `sizeof(*this)`.
2022-08-09 21:46:56 +02:00
Simon Pilgrim
d9e5462da6 [clang-pseudo] Forest.h - don't inherit from std::iterator
Now that we've updated to C++17 MSVC gives very verbose warnings about not creating classes that inherit from std::iterator - use llvm::iterator_facade_base instead

Fixes #57005
2022-08-09 10:18:53 +01:00
Haojian Wu
6f6c40a875 [pseudo] Eliminate the false :: nested-name-specifier ambiguity
The solution is to favor the longest possible nest-name-specifier, and
drop other alternatives by using the guard, per per C++ [basic.lookup.qual.general].

Motivated cases:

```
Foo::Foo() {};
// the constructor can be parsed as:
//  - Foo ::Foo(); // where the first Foo is return-type, and ::Foo is the function declarator
//  + Foo::Foo(); // where Foo::Foo is the function declarator
```

```
void test() {

// a very slow parsing case when there are many qualifers!
X::Y::Z;
// The statement can be parsed as:
//  - X ::Y::Z; // ::Y::Z is the declarator
//  - X::Y ::Z; // ::Z is the declarator
//  + X::Y::Z;  // a declaration without declarator (X::Y::Z is decl-specifier-seq)
//  + X::Y::Z;  // a qualifed-id expression
}
```

Differential Revision: https://reviews.llvm.org/D130511
2022-07-28 11:01:15 +02:00
Sam McCall
89f284bc23 [pseudo] Remove dead header
This was an earlier draft of Language.h that got committed accidentally
2022-07-27 09:05:59 +02:00
Sam McCall
6bdb15fe84 [pseudo] Reorganize CXX.h enums
- Place rules under rule::lhs::rhs__rhs__rhs
- Change mangling of keywords to ALL_CAPS (needed to turn keywords that appear
  alone on RHS into valid identifiers)
- Make enums implicitly convertible to underlying type (though still scoped,
  using alias tricks)

In principle this lets us exhaustively write a switch over all rules of a NT:
  switch ((rule::declarator)N->rule()) {
    case rule::declarator::noptr_declarator:
      ...
  }
In practice we don't do this anywhere yet as we're often switching over multiple
nonterminal kinds at once.

Differential Revision: https://reviews.llvm.org/D130414
2022-07-27 09:03:29 +02:00
Haojian Wu
2a88fb2ecb [pseudo] Eliminate the dangling-else syntax ambiguity.
- the grammar ambiguity is eliminated by a guard;
- modify the guard function signatures, now all parameters are folded in
  to a single object, avoid a long parameter list (as we will add more
  parameters in the near future);

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D130160
2022-07-22 09:13:09 +02:00
Sam McCall
3132e9cd7c [pseudo] Key guards by RuleID, add guards to literals (and 0).
After this, NUMERIC_CONSTANT and strings should parse only one way.

There are 8 types of literals, and 24 valid (literal, TokenKind) pairs.
This means adding 8 new named guards (or 24, if we want to assert the token).

It seems fairly clear to me at this point that the guard names are unneccesary
indirection: the guards are in fact coupled to the rule signature.

(Also add the zero guard I forgot in the previous patch.)

Differential Revision: https://reviews.llvm.org/D130066
2022-07-21 22:42:31 +02:00
Haojian Wu
2955192df8 [pseudo] Make sure we rebuild pseudo_gen tool. 2022-07-21 10:09:21 +02:00
Utkarsh Saxena
70914aa631 Use pseudo parser for folding ranges
This first version only uses bracket matching. We plan to extend this to
use DirectiveTree as well.

Also includes changes to Token to allow retrieving corresponding token
in token stream of original source file.

Differential Revision: https://reviews.llvm.org/D129648
2022-07-18 11:35:34 +02:00
Haojian Wu
76910d4a56 [pseudo] Share the underly payload when stripping comments for a token stream
`stripComments(cook(...))` is a common pattern being written.
Without this patch, this has a use-after-free issue (cook returns a temporary
TokenStream object which has its own payload, but the payload is not
shared with the one returned by stripComments).

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D125311
2022-07-15 15:20:48 +02:00
Haojian Wu
2315358906 [pseudo] Generate an enum type for identifying grammar rules.
The Rule enum type enables us to identify a grammar rule within C++'s
type system.

Differential Revision: https://reviews.llvm.org/D129359
2022-07-15 15:09:31 +02:00
Haojian Wu
cd3aa338c7 [pseudo] NFC, fix the header guard for Language.h 2022-07-07 14:42:26 +02:00
Sam McCall
7d8e2742d9 [pseudo] Define recovery strategy as grammar extension.
Differential Revision: https://reviews.llvm.org/D129158
2022-07-06 15:03:38 +02:00
Sam McCall
3121167488 [pseudo] Add error-recovery framework & brace-based recovery
The idea is:

- a parse failure is detected when all heads die when trying to shift the next token
- we can recover by choosing a nonterminal we're partway through parsing, and
  determining where it ends through nonlocal means (e.g. matching brackets)
- we can find candidates by walking up the stack from the (ex-)heads
- the token range is defined using heuristics attached to grammar rules
- the unparsed region is represented in the forest by an Opaque node

This patch has the core GLR functionality.
It does not allow recovery heuristics to be attached as extensions to
the grammar, but rather infers a brace-based heuristic.

Expected followups:

- make recovery heuristics grammar extensions (depends on D127448)
- add recovery to our grammar for bracketed constructs and sequence nodes
- change the structure of our augmented `_ := start` rules to eliminate some
  special-cases in glrParse.
- (if I can work out how): avoid some spurious recovery cases described in comments

(Previously mistakenly committed as a0f4c10ae227a62c2a63611e64eba83f0ff0f577)

Differential Revision: https://reviews.llvm.org/D128486
2022-07-05 20:49:41 +02:00
Haojian Wu
9ab67cc8bf [pseudo] Implement guard extension.
- Extend the GLR parser to allow conditional reduction based on the
  guard functions;
- Implement two simple guards (contextual-override/final) for cxx.bnf;
- layering: clangPseudoCXX depends on clangPseudo (as the guard function need
  to access the TokenStream);

Differential Revision: https://reviews.llvm.org/D127448
2022-07-05 15:55:15 +02:00
Sam McCall
9fbf1107cc [pseudo] Eliminate LRTable::Action. NFC
The last remaining uses are in tests/test builders.
Replace with a builder struct.

Differential Revision: https://reviews.llvm.org/D129093
2022-07-05 14:35:41 +02:00
Sam McCall
b37dafd5dc [pseudo] Store shift and goto actions in a compact structure with faster lookup.
The actions table is very compact but the binary search to find the
correct action is relatively expensive.
A hashtable is faster but pretty large (64 bits per value, plus empty
slots, and lookup is constant time but not trivial due to collisions).

The structure in this patch uses 1.25 bits per entry (whether present or absent)
plus the size of the values, and lookup is trivial.

The Shift table is 119KB = 27KB values + 92KB keys.
The Goto table is 86KB = 30KB values + 57KB keys.
(Goto has a smaller keyspace as #nonterminals < #terminals, and more entries).

This patch improves glrParse speed by 28%: 4.69 => 5.99 MB/s
Overall the table grows by 60%: 142 => 228KB.

By comparison, DenseMap<unsigned, StateID> is "only" 16% faster (5.43 MB/s),
and results in a 285% larger table (547 KB) vs the baseline.

Differential Revision: https://reviews.llvm.org/D128485
2022-07-04 19:40:04 +02:00
Haojian Wu
bbcd8e5271 [pseudo] NFC, polish the fix of c99827349927a44334f2b04139168efd0bc87cd3 2022-07-01 21:25:46 +02:00
Haojian Wu
c998273499 [pseudo] Fix an out-of-bound issue in getReduceRules. 2022-07-01 20:16:06 +02:00
Haojian Wu
fe66aebd75 [pseudo] Define a clangPseudoCLI library.
- define a common data structure Language which is a compiled result of the
  bnf grammar. It is defined in Language.h;
- creates a clangPseudoCLI lib which defines a grammar commandline flag and
  expose a function to get the Language. It supports --grammar=cxx,
  --grammmar=/path/to/file.bnf;
- use the clangPseudoCLI in clang-pseudo, fuzzer, and benchmark tools (
  simplify the code and use the prebuilt cxx grammar);

Split out from https://reviews.llvm.org/D127448.

Differential Revision: https://reviews.llvm.org/D128679
2022-07-01 08:31:34 +02:00
Sam McCall
9b6bb12b85 [pseudo] Add ForestNode descendants iterator, print ambiguous/opaque node stats.
Differential Revision: https://reviews.llvm.org/D128930
2022-06-30 21:20:55 +02:00
Haojian Wu
1ba7f5218c [pseudo] Update the cxx.bnf path in comments to reflect the new
location, NFC
2022-06-29 15:10:39 +02:00
Sam McCall
743971faaf Revert "[pseudo] Add error-recovery framework & brace-based recovery"
This reverts commit a0f4c10ae227a62c2a63611e64eba83f0ff0f577.
This commit hadn't been reviewed yet, and was unintentionally included
on another branch.
2022-06-28 21:11:09 +02:00
Sam McCall
a0f4c10ae2 [pseudo] Add error-recovery framework & brace-based recovery
The idea is:
 - a parse failure is detected when all heads die when trying to shift
   the next token
 - we can recover by choosing a nonterminal we're partway through parsing,
   and determining where it ends through nonlocal means (e.g. matching brackets)
 - we can find candidates by walking up the stack from the (ex-)heads
 - the token range is defined using heuristics attached to grammar rules
 - the unparsed region is represented in the forest by an Opaque node

This patch has the core GLR functionality.
It does not allow recovery heuristics to be attached as extensions to
the grammar, but rather infers a brace-based heuristic.

Expected followups:
 - make recovery heuristics grammar extensions (depends on D127448)
 - add recover to our grammar for bracketed constructs and sequence nodes
 - change the structure of our augmented `_ := start` rules to eliminate
   some special-cases in glrParse.
 - (if I can work out how): avoid some spurious recovery cases described
   in comments
 - grammar changes to eliminate the hard distinction between init-list
   and designated-init-list shown in the recovery-init-list.cpp testcase

Differential Revision: https://reviews.llvm.org/D128486
2022-06-28 21:08:43 +02:00
Sam McCall
3f028c02ba [pseudo] Grammar::parseBNF returns Grammar not unique_ptr. NFC 2022-06-28 16:34:21 +02:00
Sam McCall
241557fb06 [pseudo] Move cxx grammar into the cxx/ directory. NFC 2022-06-28 16:02:10 +02:00
Sam McCall
85eaecbe8e [pseudo] Check follow-sets instead of tying reduce actions to lookahead tokens.
Previously, the action table stores a reduce action for each lookahead
token it should allow. These tokens are the followSet(action.rule.target).

In practice, the follow sets are large, so we spend a bunch of time binary
searching around all these essentially-duplicates to check whether our lookahead
token is there.
However the number of reduces for a given state is very small, so we're
much better off linear scanning over them and performing a fast check for each.

D128318 was an attempt at this, storing a bitmap for each reduce.
However it's even more compact just to use the follow sets directly, as
there are fewer nonterminals than (state, rule) pairs. It's also faster.

This specialized approach means unbundling Reduce from other actions in
LRTable, so it's no longer useful to support it in Action. I suspect
Action will soon go away, as we store each kind of action separately.

This improves glrParse speed by 42% (3.30 -> 4.69 MB/s).
It also reduces LR table size by 59% (343 -> 142kB).

Differential Revision: https://reviews.llvm.org/D128472
2022-06-28 00:36:16 +02:00
Sam McCall
b70ee9d984 Reland "[pseudo] Track heads as GSS nodes, rather than as "pending actions"."
This reverts commit 2c80b5319870b57fbdbb6c9cef9c86c26c65371d.

Fixes LRTable::buildForTest to create states that are referenced but
have no actions.
2022-06-23 18:21:44 +02:00
Sam McCall
2c80b53198 Revert "[pseudo] Track heads as GSS nodes, rather than as "pending actions"."
This reverts commit e3ec054dfdf48f19cb6726cb3f4965b9ab320ed9.

Tests fail in asserts mode: https://lab.llvm.org/buildbot/#/builders/109/builds/41217
2022-06-23 18:16:38 +02:00
Sam McCall
e3ec054dfd [pseudo] Track heads as GSS nodes, rather than as "pending actions".
IMO this model is simpler to understand (borrowed from the LR0 patch D127357).
It also makes error recovery easier to implement, as we have a simple list of
head nodes lying around to recover from when needed.
(It's not quite as nice as LR0 in this respect though).

It's slightly slower (2.24 -> 2.12 MB/S on my machine = 5%) but nothing close
to as bad as LR0.
However
 - I think we'd have to eat a litle performance loss otherwise to implement
   error recovery.
 - this frees up some complexity budget for optimizations like fastpath push/pop
   (this + fastpath is already faster than head)
 - I haven't changed the data structure here and it's now pretty dumb, we can
   make it faster

Differential Revision: https://reviews.llvm.org/D128297
2022-06-23 17:26:42 +02:00