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 15 using namespace llvm; 16 17 namespace { 18 /// Sorting predicate to sort record pointers by their Name field, and break 19 /// ties using record ID (which corresponds to creation/parse order). 20 struct LessRecordFieldNameAndID { 21 bool operator()(const Record *Rec1, const Record *Rec2) const { 22 return std::tuple(Rec1->getValueAsString("Name"), Rec1->getID()) < 23 std::tuple(Rec2->getValueAsString("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. 30 void llvm::sortAndReportDuplicates(MutableArrayRef<const Record *> Records, 31 StringRef ObjectName) { 32 llvm::sort(Records, LessRecordFieldNameAndID()); 33 34 auto I = std::adjacent_find(Records.begin(), Records.end(), 35 [](const Record *Rec1, const Record *Rec2) { 36 return Rec1->getValueAsString("Name") == 37 Rec2->getValueAsString("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("Name"); 46 PrintError(Second, ObjectName + " `" + Name + "` is already defined."); 47 PrintFatalNote(First, "Previous definition here."); 48 } 49