1 | //===- DirectiveNameParser.cpp --------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Frontend/OpenMP/DirectiveNameParser.h" |
10 | #include "llvm/ADT/Sequence.h" |
11 | #include "llvm/ADT/StringExtras.h" |
12 | #include "llvm/ADT/StringRef.h" |
13 | #include "llvm/Frontend/OpenMP/OMP.h" |
14 | |
15 | #include <cassert> |
16 | #include <memory> |
17 | |
18 | namespace llvm::omp { |
19 | DirectiveNameParser::DirectiveNameParser(SourceLanguage L) { |
20 | // Take every directive, get its name in every version, break the name up |
21 | // into whitespace-separated tokens, and insert each token. |
22 | for (size_t I : llvm::seq<size_t>(Size: Directive_enumSize)) { |
23 | auto D = static_cast<Directive>(I); |
24 | if (D == Directive::OMPD_unknown || !(getDirectiveLanguages(D) & L)) |
25 | continue; |
26 | for (unsigned Ver : getOpenMPVersions()) |
27 | insertName(Name: getOpenMPDirectiveName(D, Ver), D); |
28 | } |
29 | } |
30 | |
31 | const DirectiveNameParser::State * |
32 | DirectiveNameParser::consume(const State *Current, StringRef Tok) const { |
33 | if (!Current) |
34 | return Current; |
35 | assert(Current->isValid() && "Invalid input state" ); |
36 | if (const State *Next = Current->next(Tok)) |
37 | return Next->isValid() ? Next : nullptr; |
38 | return nullptr; |
39 | } |
40 | |
41 | SmallVector<StringRef> DirectiveNameParser::tokenize(StringRef Str) { |
42 | SmallVector<StringRef> Tokens; |
43 | SplitString(Source: Str, OutFragments&: Tokens); |
44 | return Tokens; |
45 | } |
46 | |
47 | void DirectiveNameParser::insertName(StringRef Name, Directive D) { |
48 | State *Where = &InitialState; |
49 | |
50 | for (StringRef Tok : tokenize(Str: Name)) |
51 | Where = insertTransition(From: Where, Tok); |
52 | |
53 | Where->Value = D; |
54 | } |
55 | |
56 | DirectiveNameParser::State * |
57 | DirectiveNameParser::insertTransition(State *From, StringRef Tok) { |
58 | assert(From && "Expecting state" ); |
59 | if (!From->Transition) |
60 | From->Transition = std::make_unique<State::TransitionMapTy>(); |
61 | if (State *Next = From->next(Tok)) |
62 | return Next; |
63 | |
64 | auto [Where, DidIt] = From->Transition->try_emplace(Key: Tok, Args: State()); |
65 | assert(DidIt && "Map insertion failed" ); |
66 | return &Where->second; |
67 | } |
68 | |
69 | const DirectiveNameParser::State * |
70 | DirectiveNameParser::State::next(StringRef Tok) const { |
71 | if (!Transition) |
72 | return nullptr; |
73 | auto F = Transition->find(Key: Tok); |
74 | return F != Transition->end() ? &F->second : nullptr; |
75 | } |
76 | |
77 | DirectiveNameParser::State *DirectiveNameParser::State::next(StringRef Tok) { |
78 | if (!Transition) |
79 | return nullptr; |
80 | auto F = Transition->find(Key: Tok); |
81 | return F != Transition->end() ? &F->second : nullptr; |
82 | } |
83 | } // namespace llvm::omp |
84 | |