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/StringExtras.h"
11#include "llvm/ADT/StringRef.h"
12#include "llvm/Frontend/OpenMP/OMP.h"
13
14#include <cassert>
15#include <memory>
16
17namespace llvm::omp {
18DirectiveNameParser::DirectiveNameParser(SourceLanguage L) {
19 // Take every directive, get its name in every version, break the name up
20 // into whitespace-separated tokens, and insert each token.
21 for (Directive D : directives()) {
22 if (D == Directive::OMPD_unknown || !(getDirectiveLanguages(D) & L))
23 continue;
24 // Parse "ORDERED" as OMPD_ordered_standalone.
25 if (D == OMPD_ordered_blockassoc)
26 continue;
27 for (Version V : getOpenMPVersions())
28 insertName(Name: getOpenMPDirectiveName(D, V), D);
29 }
30}
31
32const DirectiveNameParser::State *
33DirectiveNameParser::consume(const State *Current, StringRef Tok) const {
34 if (!Current)
35 return Current;
36 assert(Current->isValid() && "Invalid input state");
37 if (const State *Next = Current->next(Tok))
38 return Next->isValid() ? Next : nullptr;
39 return nullptr;
40}
41
42SmallVector<StringRef> DirectiveNameParser::tokenize(StringRef Str) {
43 SmallVector<StringRef> Tokens;
44 SplitString(Source: Str, OutFragments&: Tokens);
45 return Tokens;
46}
47
48void DirectiveNameParser::insertName(StringRef Name, Directive D) {
49 State *Where = &InitialState;
50
51 for (StringRef Tok : tokenize(Str: Name))
52 Where = insertTransition(From: Where, Tok);
53
54 Where->Value = D;
55}
56
57DirectiveNameParser::State *
58DirectiveNameParser::insertTransition(State *From, StringRef Tok) {
59 assert(From && "Expecting state");
60 if (!From->Transition)
61 From->Transition = std::make_unique<State::TransitionMapTy>();
62 if (State *Next = From->next(Tok))
63 return Next;
64
65 auto [Where, DidIt] = From->Transition->try_emplace(Key: Tok, Args: State());
66 assert(DidIt && "Map insertion failed");
67 return &Where->second;
68}
69
70const DirectiveNameParser::State *
71DirectiveNameParser::State::next(StringRef Tok) const {
72 if (!Transition)
73 return nullptr;
74 auto F = Transition->find(Key: Tok);
75 return F != Transition->end() ? &F->second : nullptr;
76}
77
78DirectiveNameParser::State *DirectiveNameParser::State::next(StringRef Tok) {
79 if (!Transition)
80 return nullptr;
81 auto F = Transition->find(Key: Tok);
82 return F != Transition->end() ? &F->second : nullptr;
83}
84} // namespace llvm::omp
85