1 //===- OptEmitter.cpp - Helper for emitting options.----------- -----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "OptEmitter.h"
10 #include "llvm/ADT/Twine.h"
11 #include "llvm/TableGen/Error.h"
12 #include "llvm/TableGen/Record.h"
18 // Ordering on Info. The logic should match with the consumer-side function in
19 // llvm/Option/OptTable.h.
20 // FIXME: Make this take StringRefs instead of null terminated strings to
22 static int StrCmpOptionName(const char *A
, const char *B
) {
23 const char *X
= A
, *Y
= B
;
24 char a
= tolower(*A
), b
= tolower(*B
);
33 if (a
== '\0') // A is a prefix of B.
35 if (b
== '\0') // B is a prefix of A.
38 // Otherwise lexicographic.
39 return (a
< b
) ? -1 : 1;
42 int CompareOptionRecords(Record
*const *Av
, Record
*const *Bv
) {
43 const Record
*A
= *Av
;
44 const Record
*B
= *Bv
;
46 // Sentinel options precede all others and are only ordered by precedence.
47 bool ASent
= A
->getValueAsDef("Kind")->getValueAsBit("Sentinel");
48 bool BSent
= B
->getValueAsDef("Kind")->getValueAsBit("Sentinel");
50 return ASent
? -1 : 1;
52 // Compare options by name, unless they are sentinels.
54 if (int Cmp
= StrCmpOptionName(A
->getValueAsString("Name").str().c_str(),
55 B
->getValueAsString("Name").str().c_str()))
59 std::vector
<StringRef
> APrefixes
= A
->getValueAsListOfStrings("Prefixes");
60 std::vector
<StringRef
> BPrefixes
= B
->getValueAsListOfStrings("Prefixes");
62 for (std::vector
<StringRef
>::const_iterator APre
= APrefixes
.begin(),
63 AEPre
= APrefixes
.end(),
64 BPre
= BPrefixes
.begin(),
65 BEPre
= BPrefixes
.end();
66 APre
!= AEPre
&& BPre
!= BEPre
; ++APre
, ++BPre
) {
67 if (int Cmp
= StrCmpOptionName(APre
->str().c_str(), BPre
->str().c_str()))
72 // Then by the kind precedence;
73 int APrec
= A
->getValueAsDef("Kind")->getValueAsInt("Precedence");
74 int BPrec
= B
->getValueAsDef("Kind")->getValueAsInt("Precedence");
75 if (APrec
== BPrec
&& A
->getValueAsListOfStrings("Prefixes") ==
76 B
->getValueAsListOfStrings("Prefixes")) {
77 PrintError(A
->getLoc(), Twine("Option is equivalent to"));
78 PrintError(B
->getLoc(), Twine("Other defined here"));
79 PrintFatalError("Equivalent Options found.");
81 return APrec
< BPrec
? -1 : 1;