diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 11c97cc9..02ff0032 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -71,15 +71,19 @@ namespace Cxxi Console.WriteLine(" {0}", diag.Message); } - public void ParseCode() + public bool ParseCode() { Console.WriteLine("Parsing code..."); var parser = new Parser(Options); parser.HeaderParsed += OnHeaderParsed; - parser.ParseHeaders(Options.Headers); + if( !parser.ParseHeaders(Options.Headers) ) + return false; + Library = parser.Library; + + return true; } public void ProcessCode() @@ -148,9 +152,12 @@ namespace Cxxi var driver = new Driver(options, library); driver.Setup(); - driver.ParseCode(); - driver.ProcessCode(); - driver.GenerateCode(); + + if (driver.ParseCode()) + { + driver.ProcessCode(); + driver.GenerateCode(); + } } } @@ -169,6 +176,9 @@ namespace Cxxi public bool Verbose = false; public bool ShowHelpText = false; public bool OutputDebug = false; + // When set to true - compiler errors are ignored and intermediate + // parsing results still can be used. + public bool IgnoreErrors = false; public bool OutputInteropIncludes = true; public bool GenerateLibraryNamespace; public string OutputNamespace; diff --git a/src/Generator/Parser.cs b/src/Generator/Parser.cs index 71cd1889..f014f4d4 100644 --- a/src/Generator/Parser.cs +++ b/src/Generator/Parser.cs @@ -14,10 +14,28 @@ namespace Cxxi Library = new Library(options.OutputNamespace, options.LibraryName); } - public void ParseHeaders(IEnumerable headers) - { - foreach (var header in headers) - ParseHeader(header); + public bool ParseHeaders(IEnumerable headers) + { + bool bHasErrors = false; + foreach (var header in headers) + { + var result = ParseHeader(header); + + // If we have some error, report to end-user. + if (!options.IgnoreErrors) + { + foreach (var diag in result.Diagnostics) + { + if (diag.Level == ParserDiagnosticLevel.Error || diag.Level == ParserDiagnosticLevel.Fatal) + { + Console.WriteLine(String.Format("{0}({1},{2}): error: {3}", diag.FileName, diag.lineNumber, diag.columnNumber, diag.Message)); + bHasErrors = true; + } + } + } //if + } + + return !bHasErrors; } public ParserResult ParseHeader(string file) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index ee0072b3..e34ca8ef 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -1638,6 +1638,21 @@ ParserResult^ Parser::Parse(const std::string& File) auto PDiag = ParserDiagnostic(); PDiag.FileName = marshalString(FileName.str()); PDiag.Message = marshalString(Diag.Message.str()); + PDiag.lineNumber = 0; + PDiag.columnNumber = 0; + + // + // Idea copied from CGDebugInfo::getLineNumber + // + if( !Diag.Location.isInvalid() ) + { + clang::PresumedLoc PLoc = Source.getPresumedLoc(Diag.Location); + if( PLoc.isValid() ) + { + PDiag.lineNumber = PLoc.getLine(); + PDiag.columnNumber = PLoc.getColumn(); + } + } switch( Diag.Level ) { diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index a6a9e2bf..478a74b8 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -69,6 +69,8 @@ public enum struct ParserDiagnosticLevel public value struct ParserDiagnostic { System::String^ FileName; + int lineNumber; + int columnNumber; System::String^ Message; ParserDiagnosticLevel Level; };