1//===- OptEmitter.cpp - Helper for emitting options -------------*- C++ -*-===//
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 "OptEmitter.h"
10#include "llvm/ADT/Twine.h"
11#include "llvm/Support/OptionStrCmp.h"
12#include "llvm/TableGen/Error.h"
13#include "llvm/TableGen/Record.h"
14
15// Returns true if A is ordered before B.
16bool llvm::IsOptionRecordsLess(const Record *A, const Record *B) {
17 if (A == B)
18 return false;
19
20 // Sentinel options precede all others and are only ordered by precedence.
21 const Record *AKind = A->getValueAsDef(FieldName: "Kind");
22 const Record *BKind = B->getValueAsDef(FieldName: "Kind");
23
24 bool ASent = AKind->getValueAsBit(FieldName: "Sentinel");
25 bool BSent = BKind->getValueAsBit(FieldName: "Sentinel");
26 if (ASent != BSent)
27 return ASent;
28
29 std::vector<StringRef> APrefixes = A->getValueAsListOfStrings(FieldName: "Prefixes");
30 std::vector<StringRef> BPrefixes = B->getValueAsListOfStrings(FieldName: "Prefixes");
31
32 // Compare options by name, unless they are sentinels.
33 if (!ASent) {
34 if (int Cmp = StrCmpOptionName(A: A->getValueAsString(FieldName: "Name"),
35 B: B->getValueAsString(FieldName: "Name")))
36 return Cmp < 0;
37
38 if (int Cmp = StrCmpOptionPrefixes(APrefixes, BPrefixes))
39 return Cmp < 0;
40 }
41
42 // Then by the kind precedence;
43 int APrec = AKind->getValueAsInt(FieldName: "Precedence");
44 int BPrec = BKind->getValueAsInt(FieldName: "Precedence");
45 if (APrec == BPrec && APrefixes == BPrefixes) {
46 PrintError(ErrorLoc: A->getLoc(), Msg: Twine("Option is equivalent to"));
47 PrintError(ErrorLoc: B->getLoc(), Msg: Twine("Other defined here"));
48 PrintFatalError(Msg: "Equivalent Options found.");
49 }
50 return APrec < BPrec;
51}
52