
In "get<lang>DirectiveName(Kind, Version)", return the spelling that corresponds to Version, and in "get<lang>DirectiveKindAndVersions(Name)" return the pair {Kind, VersionRange}, where VersionRange contains the minimum and the maximum versions that allow "Name" as a spelling. This applies to clauses as well. In general it applies to classes that have spellings (defined via TableGen class "Spelling"). Given a Kind and a Version, getting the corresponding spelling requires a runtime search (which can fail in a general case). To avoid generating the search function inline, a small additional component of llvm/Frontent was added: LLVMFrontendDirective. The corresponding header file also defines C++ classes "Spelling" and "VersionRange", which are used in TableGen/DirectiveEmitter as well. For background information see https://discourse.llvm.org/t/rfc-alternative-spellings-of-openmp-directives/85507
39 lines
1.3 KiB
C++
39 lines
1.3 KiB
C++
//===-------------------------------------------------------------- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Frontend/Directive/Spelling.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/MathExtras.h"
|
|
|
|
#include <cassert>
|
|
|
|
using namespace llvm;
|
|
|
|
static bool Contains(directive::VersionRange V, int P) {
|
|
return V.Min <= P && P <= V.Max;
|
|
}
|
|
|
|
llvm::StringRef llvm::directive::FindName(
|
|
llvm::iterator_range<const directive::Spelling *> Range, unsigned Version) {
|
|
assert(llvm::isInt<8 * sizeof(int)>(Version) && "Version value out of range");
|
|
|
|
int V = Version;
|
|
// Do a linear search to find the first Spelling that contains Version.
|
|
// The condition "contains(S, Version)" does not partition the list of
|
|
// spellings, so std::[lower|upper]_bound cannot be used.
|
|
// In practice the list of spellings is expected to be very short, so
|
|
// linear search seems appropriate. In general, an interval tree may be
|
|
// a better choice, but in this case it may be an overkill.
|
|
for (auto &S : Range) {
|
|
if (Contains(S.Versions, V))
|
|
return S.Name;
|
|
}
|
|
return StringRef();
|
|
}
|