Add a new driver mode to dump compiler feature and extension options.
Add the ability to dump compiler option-related information to a JSON file via the -compiler-options-dump option. Specifically, it dumps the features/extensions lists -- however, this output could be extended to other information should it be useful. In order to support features and extensions, I moved them into a .def file so that we could build the various lists we care about from them without a significant increase in maintenance burden.
llvm-svn: 333653
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 5941643..b5396dd 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1396,6 +1396,8 @@
Opts.ProgramAction = frontend::ASTPrint; break;
case OPT_ast_view:
Opts.ProgramAction = frontend::ASTView; break;
+ case OPT_compiler_options_dump:
+ Opts.ProgramAction = frontend::DumpCompilerOptions; break;
case OPT_dump_raw_tokens:
Opts.ProgramAction = frontend::DumpRawTokens; break;
case OPT_dump_tokens:
@@ -2788,6 +2790,7 @@
case frontend::MigrateSource:
return false;
+ case frontend::DumpCompilerOptions:
case frontend::DumpRawTokens:
case frontend::DumpTokens:
case frontend::InitOnly:
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 13f0537..602fee1 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -756,3 +756,51 @@
llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
}
}
+
+void DumpCompilerOptionsAction::ExecuteAction() {
+ CompilerInstance &CI = getCompilerInstance();
+ std::unique_ptr<raw_ostream> OSP =
+ CI.createDefaultOutputFile(false, getCurrentFile());
+ if (!OSP)
+ return;
+
+ raw_ostream &OS = *OSP;
+ const Preprocessor &PP = CI.getPreprocessor();
+ const LangOptions &LangOpts = PP.getLangOpts();
+
+ // FIXME: Rather than manually format the JSON (which is awkward due to
+ // needing to remove trailing commas), this should make use of a JSON library.
+ // FIXME: Instead of printing enums as an integral value and specifying the
+ // type as a separate field, use introspection to print the enumerator.
+
+ OS << "{\n";
+ OS << "\n\"features\" : [\n";
+ {
+ llvm::SmallString<128> Str;
+#define FEATURE(Name, Predicate) \
+ ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
+ .toVector(Str);
+#include "clang/Basic/Features.def"
+#undef FEATURE
+ // Remove the newline and comma from the last entry to ensure this remains
+ // valid JSON.
+ OS << Str.substr(0, Str.size() - 2);
+ }
+ OS << "\n],\n";
+
+ OS << "\n\"extensions\" : [\n";
+ {
+ llvm::SmallString<128> Str;
+#define EXTENSION(Name, Predicate) \
+ ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
+ .toVector(Str);
+#include "clang/Basic/Features.def"
+#undef EXTENSION
+ // Remove the newline and comma from the last entry to ensure this remains
+ // valid JSON.
+ OS << Str.substr(0, Str.size() - 2);
+ }
+ OS << "\n]\n";
+
+ OS << "}";
+}