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
18namespace llvm::omp {
19DirectiveNameParser::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
31const DirectiveNameParser::State *
32DirectiveNameParser::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
41SmallVector<StringRef> DirectiveNameParser::tokenize(StringRef Str) {
42 SmallVector<StringRef> Tokens;
43 SplitString(Source: Str, OutFragments&: Tokens);
44 return Tokens;
45}
46
47void 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
56DirectiveNameParser::State *
57DirectiveNameParser::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
69const DirectiveNameParser::State *
70DirectiveNameParser::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
77DirectiveNameParser::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