diff --git a/generator/codefactory.cpp b/generator/codefactory.cpp index c61ea1c..3924de5 100644 --- a/generator/codefactory.cpp +++ b/generator/codefactory.cpp @@ -36,6 +36,7 @@ CodeFactory::CodeFactory( , m_clangOptions(clangOptions) , m_os(os) , m_compilerInstance(nullptr) + , m_errorResilient(true) { } diff --git a/generator/codefactory.h b/generator/codefactory.h index db9de4c..386a749 100644 --- a/generator/codefactory.h +++ b/generator/codefactory.h @@ -40,6 +40,8 @@ public: bool run(); clang::CompilerInstance *compilerInstance(); void setCompilerInstance(clang::CompilerInstance *compilerInstance); + bool isErrorResilient() const; + void setErrorResilient(bool errorResilient); private: struct ToolInvocation; @@ -55,6 +57,7 @@ private: std::vector> m_generators; std::unique_ptr m_toolInvocation; clang::CompilerInstance *m_compilerInstance; + bool m_errorResilient; }; /*! @@ -129,6 +132,22 @@ inline void CodeFactory::setCompilerInstance(clang::CompilerInstance *compilerIn m_compilerInstance = compilerInstance; } +/*! + * \brief Returns whether most errors will be turned into warnings (by default false). + */ +inline bool CodeFactory::isErrorResilient() const +{ + return m_errorResilient; +} + +/*! + * \brief Sets whether most errors will be turned into warnings (by default false). + */ +inline void CodeFactory::setErrorResilient(bool errorResilient) +{ + m_errorResilient = errorResilient; +} + } // namespace ReflectiveRapidJSON #endif // REFLECTIVE_RAPIDJSON_CODE_FACTORY_H diff --git a/generator/consumer.cpp b/generator/consumer.cpp index f2f5bd7..9cf2512 100644 --- a/generator/consumer.cpp +++ b/generator/consumer.cpp @@ -61,18 +61,20 @@ void DiagConsumer::finish() */ void DiagConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level diagLevel, const clang::Diagnostic &info) { - const auto diagId = info.getID(); - const auto category = info.getDiags()->getDiagnosticIDs()->getCategoryNumberForDiag(diagId); - bool shouldReset = false; - if (diagLevel >= clang::DiagnosticsEngine::Error) { - if (category == 2 /* 2 means "Semantic Issue" */) { - if (!m_realErrorCount) { - shouldReset = true; + if (m_errorResilient) { + const auto diagId = info.getID(); + const auto category = info.getDiags()->getDiagnosticIDs()->getCategoryNumberForDiag(diagId); + + if (diagLevel >= clang::DiagnosticsEngine::Error) { + if (category == 2 /* 2 means "Semantic Issue" */) { + if (!m_realErrorCount) { + shouldReset = true; + } + diagLevel = clang::DiagnosticsEngine::Warning; + } else { + ++m_realErrorCount; } - diagLevel = clang::DiagnosticsEngine::Warning; - } else { - ++m_realErrorCount; } } diff --git a/generator/consumer.h b/generator/consumer.h index 4a14978..4d832a2 100644 --- a/generator/consumer.h +++ b/generator/consumer.h @@ -50,7 +50,7 @@ inline Consumer::Consumer(CodeFactory &factory, clang::CompilerInstance &compile */ class DiagConsumer : public clang::DiagnosticConsumer { public: - DiagConsumer(std::unique_ptr Previous); + DiagConsumer(std::unique_ptr previous, bool errorResilient); unsigned int realErrorCount() const; void BeginSourceFile(const clang::LangOptions &langOpts, const clang::Preprocessor *pp = nullptr) override; @@ -62,11 +62,13 @@ public: private: std::unique_ptr m_proxy; unsigned int m_realErrorCount; + bool m_errorResilient; }; -inline DiagConsumer::DiagConsumer(std::unique_ptr Previous) - : m_proxy(std::move(Previous)) +inline DiagConsumer::DiagConsumer(std::unique_ptr previous, bool errorResilient) + : m_proxy(std::move(previous)) , m_realErrorCount(0) + , m_errorResilient(errorResilient) { } diff --git a/generator/main.cpp b/generator/main.cpp index b1dbdcd..8e4f94a 100644 --- a/generator/main.cpp +++ b/generator/main.cpp @@ -42,9 +42,10 @@ int main(int argc, char *argv[]) generatorsArg.setCombinable(true); ConfigValueArgument clangOptionsArg("clang-opt", '\0', "specifies arguments/options to be passed to Clang", { "option" }); clangOptionsArg.setRequiredValueCount(Argument::varValueCount); + ConfigValueArgument errorResilientArg("error-resilient", '\0', "turns most errors into warnings"); HelpArgument helpArg(parser); NoColorArgument noColorArg; - generateArg.setSubArguments({ &inputFileArg, &outputFileArg, &generatorsArg, &clangOptionsArg }); + generateArg.setSubArguments({ &inputFileArg, &outputFileArg, &generatorsArg, &clangOptionsArg, &errorResilientArg }); JsonSerializationCodeGenerator::Options jsonOptions; jsonOptions.appendTo(&generateArg); parser.setMainArguments({ &generateArg, &noColorArg, &helpArg }); @@ -83,9 +84,10 @@ int main(int argc, char *argv[]) // instantiate the code factory and add generators to it CodeFactory factory(parser.executable(), inputFileArg.values(0), clangOptions, *os); + factory.setErrorResilient(errorResilientArg.isPresent()); // add specified generators if the --generator argument is present; otherwise add default generators if (generatorsArg.isPresent()) { - // define mapping of generator names to generator constructions (add new generators here!) + // define mapping of generator names to generator constructors (add new generators here!) // clang-format off const std::unordered_map> generatorsByName{ { "json", factory.bindGenerator(jsonOptions) }