Browse Source

The parser now returns a ParserResult struct with diagnostic and library information.

pull/1/head
triton 13 years ago
parent
commit
9462ddbcfd
  1. 4
      src/Generator/Driver.cs
  2. 4
      src/Generator/Parser.cs
  3. 4
      src/Parser/Main.cpp
  4. 63
      src/Parser/Parser.cpp
  5. 20
      src/Parser/Parser.h

4
src/Generator/Driver.cs

@ -29,8 +29,8 @@ namespace Cxxi
transform.SetupHeaders(headers); transform.SetupHeaders(headers);
var parser = new Parser(options); var parser = new Parser(options);
parser.HeaderParsed += (file, success) => parser.HeaderParsed += (file, result) =>
Console.WriteLine(success ? " Parsed '" + file + "'." : Console.WriteLine(result.Success ? " Parsed '" + file + "'." :
" Could not parse '" + file + "'."); " Could not parse '" + file + "'.");
parser.ParseHeaders(headers); parser.ParseHeaders(headers);

4
src/Generator/Parser.cs

@ -20,7 +20,7 @@ namespace Cxxi
ParseHeader(header); ParseHeader(header);
} }
bool ParseHeader(string file) public ParserResult ParseHeader(string file)
{ {
var parserOptions = new ParserOptions var parserOptions = new ParserOptions
{ {
@ -38,6 +38,6 @@ namespace Cxxi
return result; return result;
} }
public Action<string, bool> HeaderParsed = delegate {}; public Action<string, ParserResult> HeaderParsed = delegate {};
} }
} }

4
src/Parser/Main.cpp

@ -12,9 +12,9 @@ public ref class ClangParser
{ {
public: public:
static bool Parse(ParserOptions^ Opts) static ParserResult^ Parse(ParserOptions^ Opts)
{ {
if (!Opts->FileName) return false; if (!Opts->FileName) return nullptr;
using namespace clix; using namespace clix;
std::string File = marshalString<E_UTF8>(Opts->FileName); std::string File = marshalString<E_UTF8>(Opts->FileName);

63
src/Parser/Parser.cpp

@ -1389,13 +1389,48 @@ struct ParseConsumer : public clang::ASTConsumer
virtual bool HandleTopLevelDecl(clang::DeclGroupRef) { return true; } virtual bool HandleTopLevelDecl(clang::DeclGroupRef) { return true; }
}; };
bool Parser::Parse(const std::string& File) struct Diagnostic
{ {
clang::SourceLocation Location;
llvm::SmallString<100> Message;
};
struct DiagnosticConsumer : public clang::DiagnosticConsumer
{
virtual ~DiagnosticConsumer() { }
virtual void HandleDiagnostic(clang::DiagnosticsEngine::Level Level,
const clang::Diagnostic& Info) override {
auto Diag = Diagnostic();
Diag.Location = Info.getLocation();
Info.FormatDiagnostic(Diag.Message);
Diagnostics.push_back(Diag);
}
virtual
DiagnosticConsumer* clone(clang::DiagnosticsEngine& Diags) const override {
return new DiagnosticConsumer();
}
std::vector<Diagnostic> Diagnostics;
};
ParserResult^ Parser::Parse(const std::string& File)
{
auto res = gcnew ParserResult();
res->Library = Lib;
if (File.empty()) if (File.empty())
return false; {
res->Success = false;
return res;
}
C->setASTConsumer(new ParseConsumer()); C->setASTConsumer(new ParseConsumer());
auto DiagClient = new DiagnosticConsumer();
C->getDiagnostics().setClient(DiagClient);
// Create a virtual file that includes the header. This gets rid of some // Create a virtual file that includes the header. This gets rid of some
// Clang warnings about parsing an header file as the main file. // Clang warnings about parsing an header file as the main file.
@ -1413,15 +1448,29 @@ bool Parser::Parse(const std::string& File)
/*SkipFunctionBodies=*/true); /*SkipFunctionBodies=*/true);
client->EndSourceFile(); client->EndSourceFile();
if(client->getNumErrors() != 0) // Convert the diagnostics to the managed types
for(auto& Diag : DiagClient->Diagnostics)
{ {
// We had some errors while parsing the file. using namespace clix;
// Report this...
return false; auto& Source = C->getSourceManager();
auto FileName = Source.getFilename(Diag.Location);
auto PDiag = ParserDiagnostic();
PDiag.FileName = marshalString<E_UTF8>(FileName.str());
PDiag.Message = marshalString<E_UTF8>(Diag.Message.str());
res->Diagnostics->Add(PDiag);
}
if(DiagClient->getNumErrors() != 0)
{
res->Success = false;
return res;
} }
AST = &C->getASTContext(); AST = &C->getASTContext();
WalkAST(); WalkAST();
return true; res->Success = true;
return res;
} }

20
src/Parser/Parser.h

@ -55,12 +55,30 @@ public ref struct ParserOptions
bool Verbose; bool Verbose;
}; };
public value struct ParserDiagnostic
{
System::String^ FileName;
System::String^ Message;
};
public ref struct ParserResult
{
ParserResult()
{
Diagnostics = gcnew List<ParserDiagnostic>();
}
bool Success;
Cxxi::Library^ Library;
List<ParserDiagnostic>^ Diagnostics;
};
struct Parser struct Parser
{ {
Parser(ParserOptions^ Opts); Parser(ParserOptions^ Opts);
void Setup(ParserOptions^ Opts); void Setup(ParserOptions^ Opts);
bool Parse(const std::string& File); ParserResult^ Parse(const std::string& File);
protected: protected:

Loading…
Cancel
Save