mirror of
https://github.com/RPCSX/llvm.git
synced 2025-03-04 02:47:25 +00:00
Add another Clang TableGen-backend (-gen-clang-diags-options) for emitting
declarations for controlling groups of warnings. Currently this transforms: def UnusedMacrosDiags : Option<"unused-macros", [pp_macro_not_used]>; into: static const diag::kind UnusedMacrosDiags[] = { diag::pp_macro_not_used }; git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67239 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d4771828ca
commit
8b9d027701
@ -16,8 +16,16 @@
|
|||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/Streams.h"
|
#include "llvm/Support/Streams.h"
|
||||||
#include "llvm/ADT/VectorExtras.h"
|
#include "llvm/ADT/VectorExtras.h"
|
||||||
|
#include "llvm/ADT/DenseSet.h"
|
||||||
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Generic routines for all Clang TableGen backens.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
typedef std::vector<Record*> RecordVector;
|
typedef std::vector<Record*> RecordVector;
|
||||||
typedef std::vector<Record*> SuperClassVector;
|
typedef std::vector<Record*> SuperClassVector;
|
||||||
typedef std::vector<RecordVal> RecordValVector;
|
typedef std::vector<RecordVal> RecordValVector;
|
||||||
@ -54,6 +62,10 @@ static void EmitAllCaps(std::ostream& OS, const std::string &s) {
|
|||||||
OS << char(toupper(*I));
|
OS << char(toupper(*I));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Warning Tables (.inc file) generation.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void ProcessDiag(std::ostream& OS, const Record* DiagClass,
|
static void ProcessDiag(std::ostream& OS, const Record* DiagClass,
|
||||||
const Record& R) {
|
const Record& R) {
|
||||||
|
|
||||||
@ -106,3 +118,92 @@ void ClangDiagsDefsEmitter::run(std::ostream &OS) {
|
|||||||
ProcessDiag(OS, DiagClass, **I);
|
ProcessDiag(OS, DiagClass, **I);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Warning Group Tables generation.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
typedef std::set<const Record*> DiagnosticSet;
|
||||||
|
typedef std::map<const Record*, DiagnosticSet> OptionMap;
|
||||||
|
typedef llvm::DenseSet<const ListInit*> VisitedLists;
|
||||||
|
|
||||||
|
static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited, const Init* X);
|
||||||
|
|
||||||
|
static void BuildGroup(DiagnosticSet &DS, VisitedLists &Visited,
|
||||||
|
const ListInit* LV) {
|
||||||
|
|
||||||
|
// Simple hack to prevent including a list multiple times. This may be useful
|
||||||
|
// if one declares an Option by including a bunch of other Options that
|
||||||
|
// include other Options, etc.
|
||||||
|
if (Visited.count(LV))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Visited.insert(LV);
|
||||||
|
|
||||||
|
// Iterate through the list and grab all DiagnosticControlled.
|
||||||
|
for (ListInit::const_iterator I = LV->begin(), E = LV->end(); I!=E; ++I)
|
||||||
|
BuildGroup(DS, Visited, *I);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited,
|
||||||
|
const Record *Def) {
|
||||||
|
|
||||||
|
// If an Option includes another Option, inline the Diagnostics of the
|
||||||
|
// included Option.
|
||||||
|
if (Def->isSubClassOf("Option")) {
|
||||||
|
if (const RecordVal* V = findRecordVal(*Def, "Members"))
|
||||||
|
if (const ListInit* LV = dynamic_cast<const ListInit*>(V->getValue()))
|
||||||
|
BuildGroup(DS, Visited, LV);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Def->isSubClassOf("DiagnosticControlled"))
|
||||||
|
DS.insert(Def);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited,
|
||||||
|
const Init* X) {
|
||||||
|
|
||||||
|
if (const DefInit *D = dynamic_cast<const DefInit*>(X))
|
||||||
|
BuildGroup(DS, Visited, D->getDef());
|
||||||
|
|
||||||
|
// We may have some other cases here in the future.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ClangOptionsEmitter::run(std::ostream &OS) {
|
||||||
|
// Build up a map from options to controlled diagnostics.
|
||||||
|
OptionMap OM;
|
||||||
|
|
||||||
|
const RecordVector &Opts = Records.getAllDerivedDefinitions("Option");
|
||||||
|
for (RecordVector::const_iterator I=Opts.begin(), E=Opts.end(); I!=E; ++I)
|
||||||
|
if (const RecordVal* V = findRecordVal(**I, "Members"))
|
||||||
|
if (const ListInit* LV = dynamic_cast<const ListInit*>(V->getValue())) {
|
||||||
|
VisitedLists Visited;
|
||||||
|
BuildGroup(OM[*I], Visited, LV);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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() << "[] = { ";
|
||||||
|
|
||||||
|
DiagnosticSet &DS = I->second;
|
||||||
|
bool first = true;
|
||||||
|
for (DiagnosticSet::iterator I2 = DS.begin(), E2 = DS.end(); I2!=E2; ++I2) {
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
OS << ", ";
|
||||||
|
|
||||||
|
OS << "diag::" << (*I2)->getName();
|
||||||
|
}
|
||||||
|
OS << " };\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -32,6 +32,15 @@ public:
|
|||||||
void run(std::ostream &OS);
|
void run(std::ostream &OS);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ClangOptionsEmitter : public TableGenBackend {
|
||||||
|
RecordKeeper &Records;
|
||||||
|
public:
|
||||||
|
explicit ClangOptionsEmitter(RecordKeeper &R) : Records(R) {}
|
||||||
|
|
||||||
|
void run(std::ostream &OS);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,6 +48,7 @@ enum ActionType {
|
|||||||
GenInstrEnums, GenInstrs, GenAsmWriter,
|
GenInstrEnums, GenInstrs, GenAsmWriter,
|
||||||
GenCallingConv,
|
GenCallingConv,
|
||||||
GenClangDiagsDefs,
|
GenClangDiagsDefs,
|
||||||
|
GenClangDiagsOptions,
|
||||||
GenDAGISel,
|
GenDAGISel,
|
||||||
GenFastISel,
|
GenFastISel,
|
||||||
GenSubtarget,
|
GenSubtarget,
|
||||||
@ -90,6 +91,8 @@ namespace {
|
|||||||
"Generate target intrinsic information"),
|
"Generate target intrinsic information"),
|
||||||
clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
|
clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
|
||||||
"Generate Clang diagnostics definitions"),
|
"Generate Clang diagnostics definitions"),
|
||||||
|
clEnumValN(GenClangDiagsOptions, "gen-clang-diags-options",
|
||||||
|
"Generate options for Clang diagnostics"),
|
||||||
clEnumValN(GenLLVMCConf, "gen-llvmc",
|
clEnumValN(GenLLVMCConf, "gen-llvmc",
|
||||||
"Generate LLVMC configuration library"),
|
"Generate LLVMC configuration library"),
|
||||||
clEnumValN(PrintEnums, "print-enums",
|
clEnumValN(PrintEnums, "print-enums",
|
||||||
@ -209,6 +212,9 @@ int main(int argc, char **argv) {
|
|||||||
case GenClangDiagsDefs:
|
case GenClangDiagsDefs:
|
||||||
ClangDiagsDefsEmitter(Records, ClangComponent).run(*Out);
|
ClangDiagsDefsEmitter(Records, ClangComponent).run(*Out);
|
||||||
break;
|
break;
|
||||||
|
case GenClangDiagsOptions:
|
||||||
|
ClangOptionsEmitter(Records).run(*Out);
|
||||||
|
break;
|
||||||
case GenDAGISel:
|
case GenDAGISel:
|
||||||
DAGISelEmitter(Records).run(*Out);
|
DAGISelEmitter(Records).run(*Out);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user