1//===- Utils.cpp - Common Utilities -----------------------------*- 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 "Utils.h"
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/TableGen/Error.h"
12#include "llvm/TableGen/Record.h"
13#include <algorithm>
14
15using namespace llvm;
16
17namespace {
18/// Sorting predicate to sort record pointers by their Name field, and break
19/// ties using record ID (which corresponds to creation/parse order).
20struct LessRecordFieldNameAndID {
21 bool operator()(const Record *Rec1, const Record *Rec2) const {
22 return std::tuple(Rec1->getValueAsString(FieldName: "Name"), Rec1->getID()) <
23 std::tuple(Rec2->getValueAsString(FieldName: "Name"), Rec2->getID());
24 }
25};
26} // End anonymous namespace
27
28/// Sort an array of Records on the "Name" field, and check for records with
29/// duplicate "Name" field. If duplicates are found, report a fatal error.
30void llvm::sortAndReportDuplicates(MutableArrayRef<const Record *> Records,
31 StringRef ObjectName) {
32 llvm::sort(C&: Records, Comp: LessRecordFieldNameAndID());
33
34 auto I = std::adjacent_find(first: Records.begin(), last: Records.end(),
35 binary_pred: [](const Record *Rec1, const Record *Rec2) {
36 return Rec1->getValueAsString(FieldName: "Name") ==
37 Rec2->getValueAsString(FieldName: "Name");
38 });
39 if (I == Records.end())
40 return;
41
42 // Found a duplicate name.
43 const Record *First = *I;
44 const Record *Second = *(I + 1);
45 StringRef Name = First->getValueAsString(FieldName: "Name");
46 PrintError(Rec: Second, Msg: ObjectName + " `" + Name + "` is already defined.");
47 PrintFatalNote(Rec: First, Msg: "Previous definition here.");
48}
49