tblgen -gen-clang-diags-options: Output OptionTable entries in lexicographic
[oota-llvm.git] / utils / TableGen / ClangDiagnosticsEmitter.cpp
index a3f27ba75f2b36bcc15dfb6fa9696d49de925ad8..cb65cea31a2b4b97ee7f6164816cfcb617df5f83 100644 (file)
@@ -14,6 +14,7 @@
 #include "ClangDiagnosticsEmitter.h"
 #include "Record.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Streams.h"
 #include "llvm/ADT/VectorExtras.h"
 #include "llvm/ADT/DenseSet.h"
@@ -123,8 +124,24 @@ void ClangDiagsDefsEmitter::run(std::ostream &OS) {
 // Warning Group Tables generation.
 //===----------------------------------------------------------------------===//
 
+static const std::string &getOptName(const Record *R) {
+  const RecordVal *V = findRecordVal(*R, "Name");
+  assert(V && "Options must have a 'Name' value.");
+  const StringInit* SV = dynamic_cast<const StringInit*>(V->getValue());
+  assert(SV && "'Name' entry must be a string.");
+  return SV->getValue();
+}  
+
+namespace {
+struct VISIBILITY_HIDDEN CompareOptName {  
+  bool operator()(const Record* A, const Record* B) {
+    return getOptName(A) < getOptName(B);    
+  }
+};
+}
+
 typedef std::set<const Record*> DiagnosticSet;
-typedef std::map<const Record*, DiagnosticSet> OptionMap;
+typedef std::map<const Record*, DiagnosticSet, CompareOptName> OptionMap;
 typedef llvm::DenseSet<const ListInit*> VisitedLists;
 
 static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited, const Init* X);
@@ -186,11 +203,6 @@ void ClangOptionsEmitter::run(std::ostream &OS) {
   
   // Iterate through the OptionMap and emit the declarations.
   for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) {    
-//    const RecordVal *V = findRecordVal(*I->first, "Name");
-//    assert(V && "Options must have a 'Name' value.");
-//    const StringInit* SV = dynamic_cast<const StringInit*>(V->getValue());
-//    assert(SV && "'Name' entry must be a string.");
-    
     // Output the option.
     OS << "static const diag::kind " << I->first->getName() << "[] = { ";
     
@@ -206,4 +218,18 @@ void ClangOptionsEmitter::run(std::ostream &OS) {
     }
     OS << " };\n";
   }
+    
+  // Now emit the OptionTable table.
+  OS << "\nstatic const WarningOption OptionTable[] = {";
+  bool first = true;
+  for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) {
+    if (first)
+      first = false;
+    else
+      OS << ',';
+    
+    OS << "\n  {\"" << getOptName(I->first)
+       << "\", DIAGS(" << I->first->getName() << ")}";
+  }
+  OS << "\n};\n";
 }