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>(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(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(Str, Tokens); 44 return Tokens; 45 } 46 47 void DirectiveNameParser::insertName(StringRef Name, Directive D) { 48 State *Where = &InitialState; 49 50 for (StringRef Tok : tokenize(Name)) 51 Where = insertTransition(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(Tok, 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(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(Tok); 81 return F != Transition->end() ? &F->second : nullptr; 82 } 83 } // namespace llvm::omp 84