Browse Source

Added support for parsing native library symbols.

pull/1/head
triton 12 years ago
parent
commit
fe85a6590b
  1. 34
      src/Bridge/Library.cs
  2. 34
      src/Generator/Driver.cs
  3. 17
      src/Parser/Main.cpp
  4. 74
      src/Parser/Parser.cpp
  5. 8
      src/Parser/Parser.h
  6. 1
      src/Parser/Parser.lua

34
src/Bridge/Library.cs

@ -15,6 +15,24 @@ namespace Cxxi @@ -15,6 +15,24 @@ namespace Cxxi
Unavailable
}
public class NativeLibrary
{
public NativeLibrary(string file)
: this()
{
FileName = file;
}
public NativeLibrary()
{
Symbols = new List<string>();
}
public string FileName;
public IList<string> Symbols;
}
/// <summary>
/// A library contains all the modules.
/// </summary>
@ -23,12 +41,27 @@ namespace Cxxi @@ -23,12 +41,27 @@ namespace Cxxi
public string Name;
public string SharedLibrary;
public List<TranslationUnit> TranslationUnits;
public List<NativeLibrary> Libraries;
public Library(string name, string sharedLibrary)
{
Name = name;
SharedLibrary = sharedLibrary;
TranslationUnits = new List<TranslationUnit>();
Libraries = new List<NativeLibrary>();
}
public NativeLibrary FindOrCreateLibrary(string file)
{
var library = Libraries.Find(m => m.FileName.Equals(file));
if (library == null)
{
library = new NativeLibrary(file);
Libraries.Add(library);
}
return library;
}
/// Finds an existing module or creates a new one given a file path.
@ -85,7 +118,6 @@ namespace Cxxi @@ -85,7 +118,6 @@ namespace Cxxi
}
}
/// Finds an existing typedef in the library modules.
public IEnumerable<TypedefDecl> FindTypedef(string name)
{

34
src/Generator/Driver.cs

@ -48,11 +48,16 @@ namespace Cxxi @@ -48,11 +48,16 @@ namespace Cxxi
Options.IncludeDirs[i] = Path.GetFullPath(Options.IncludeDirs[i]);
}
for (var i = 0; i < Options.LibraryDirs.Count; i++)
{
Options.LibraryDirs[i] = Path.GetFullPath(Options.LibraryDirs[i]);
}
if (string.IsNullOrWhiteSpace(Options.OutputNamespace))
Options.OutputNamespace = Options.LibraryName;
}
private void OnHeaderParsed(string file, ParserResult result)
private void OnFileParsed(string file, ParserResult result)
{
switch (result.Kind)
{
@ -80,7 +85,7 @@ namespace Cxxi @@ -80,7 +85,7 @@ namespace Cxxi
Console.WriteLine("Parsing code...");
var parser = new Parser(Options);
parser.HeaderParsed += OnHeaderParsed;
parser.OnHeaderParsed += OnFileParsed;
if( !parser.ParseHeaders(Options.Headers) )
return false;
@ -90,6 +95,21 @@ namespace Cxxi @@ -90,6 +95,21 @@ namespace Cxxi
return true;
}
public bool ParseLibraries()
{
Console.WriteLine("Parsing libraries...");
var parser = new Parser(Options);
parser.OnLibraryParsed += OnFileParsed;
if (!parser.ParseLibraries(Options.Libraries))
return false;
Library = parser.Library;
return true;
}
public void ProcessCode()
{
if (Transform != null)
@ -161,7 +181,7 @@ namespace Cxxi @@ -161,7 +181,7 @@ namespace Cxxi
var driver = new Driver(options, library);
driver.Setup();
if (driver.ParseCode())
if (driver.ParseLibraries() && driver.ParseCode())
{
driver.ProcessCode();
driver.GenerateCode();
@ -183,6 +203,10 @@ namespace Cxxi @@ -183,6 +203,10 @@ namespace Cxxi
WriteOnlyWhenChanged = false;
GeneratePartialClasses = true;
// Library options
LibraryDirs = new List<string>();
Libraries = new List<string>();
var platform = Environment.OSVersion.Platform;
Abi = (platform == PlatformID.Unix || platform == PlatformID.MacOSX) ?
CppAbi.Itanium : CppAbi.Microsoft;
@ -213,6 +237,10 @@ namespace Cxxi @@ -213,6 +237,10 @@ namespace Cxxi
public LanguageGeneratorKind GeneratorKind;
public bool WriteOnlyWhenChanged;
// Library options
public List<string> LibraryDirs;
public List<string> Libraries;
public bool IsItaniumAbi { get { return Abi == CppAbi.Itanium; } }
public bool IsMicrosoftAbi { get { return Abi == CppAbi.Microsoft; } }
}

17
src/Parser/Main.cpp

@ -12,14 +12,25 @@ public ref class ClangParser @@ -12,14 +12,25 @@ public ref class ClangParser
{
public:
static ParserResult^ Parse(ParserOptions^ Opts)
static ParserResult^ ParseHeader(ParserOptions^ Opts)
{
if (!Opts->FileName) return nullptr;
using namespace clix;
std::string File = marshalString<E_UTF8>(Opts->FileName);
Parser p(Opts);
return p.Parse(File);
Parser parser(Opts);
return parser.ParseHeader(File);
}
static ParserResult^ ParseLibrary(ParserOptions^ Opts)
{
if (!Opts->FileName) return nullptr;
using namespace clix;
std::string File = marshalString<E_UTF8>(Opts->FileName);
Parser parser(Opts);
return parser.ParseLibrary(File);
}
};

74
src/Parser/Parser.cpp

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
#include "Interop.h"
#include <llvm/Support/Path.h>
#include <llvm/Object/Archive.h>
#include <clang/Basic/Version.h>
#include <clang/Config/config.h>
#include <clang/AST/ASTContext.h>
@ -27,9 +28,8 @@ @@ -27,9 +28,8 @@
//-----------------------------------//
Parser::Parser(ParserOptions^ Opts) : Lib(Opts->Library), Index(0)
Parser::Parser(ParserOptions^ Opts) : Lib(Opts->Library), Opts(Opts), Index(0)
{
Setup(Opts);
}
//-----------------------------------//
@ -68,7 +68,7 @@ static std::string GetClangBuiltinIncludeDir() @@ -68,7 +68,7 @@ static std::string GetClangBuiltinIncludeDir()
std::vector<std::string> GetWindowsSystemIncludeDirs();
#endif
void Parser::Setup(ParserOptions^ Opts)
void Parser::SetupHeader()
{
using namespace clang;
using namespace clix;
@ -1631,7 +1631,7 @@ struct DiagnosticConsumer : public clang::DiagnosticConsumer @@ -1631,7 +1631,7 @@ struct DiagnosticConsumer : public clang::DiagnosticConsumer
std::vector<Diagnostic> Diagnostics;
};
ParserResult^ Parser::Parse(const std::string& File)
ParserResult^ Parser::ParseHeader(const std::string& File)
{
auto res = gcnew ParserResult();
res->Library = Lib;
@ -1642,6 +1642,8 @@ ParserResult^ Parser::Parse(const std::string& File) @@ -1642,6 +1642,8 @@ ParserResult^ Parser::Parse(const std::string& File)
return res;
}
SetupHeader();
auto SC = new clang::SemaConsumer();
C->setASTConsumer(SC);
@ -1737,3 +1739,67 @@ ParserResult^ Parser::Parse(const std::string& File) @@ -1737,3 +1739,67 @@ ParserResult^ Parser::Parse(const std::string& File)
res->Kind = ParserResultKind::Success;
return res;
}
ParserResult^ Parser::ParseLibrary(const std::string& File)
{
using namespace clix;
auto res = gcnew ParserResult();
res->Library = Lib;
if (File.empty())
{
res->Kind = ParserResultKind::FileNotFound;
return res;
}
C.reset(new clang::CompilerInstance());
C->createFileManager();
auto &FM = C->getFileManager();
const clang::FileEntry* FileEntry = 0;
for each(System::String^ LibDir in Opts->LibraryDirs)
{
auto DirName = marshalString<E_UTF8>(LibDir);
llvm::sys::Path Path(DirName);
Path.appendComponent(File);
if (FileEntry = FM.getFile(Path.str()))
break;
}
if (!FileEntry)
{
res->Kind = ParserResultKind::FileNotFound;
return res;
}
auto Buffer = FM.getBufferForFile(FileEntry);
llvm::error_code Code;
llvm::object::Archive Archive(Buffer, Code);
if (Code)
{
res->Kind = ParserResultKind::Error;
return res;
}
auto LibName = marshalString<E_UTF8>(File);
auto NativeLib = Lib->FindOrCreateLibrary(LibName);
for(auto it = Archive.begin_symbols(); it != Archive.end_symbols(); ++it)
{
llvm::StringRef SymRef;
if (it->getName(SymRef))
continue;
System::String^ SymName = marshalString<E_UTF8>(SymRef);
NativeLib->Symbols->Add(SymName);
}
res->Kind = ParserResultKind::Success;
return res;
}

8
src/Parser/Parser.h

@ -38,11 +38,13 @@ public ref struct ParserOptions @@ -38,11 +38,13 @@ public ref struct ParserOptions
{
IncludeDirs = gcnew List<System::String^>();
Defines = gcnew List<System::String^>();
LibraryDirs = gcnew List<System::String^>();
}
// Include directories
List<System::String^>^ IncludeDirs;
List<System::String^>^ Defines;
List<System::String^>^ LibraryDirs;
// C/C++ header file name.
System::String^ FileName;
@ -96,8 +98,9 @@ struct Parser @@ -96,8 +98,9 @@ struct Parser
{
Parser(ParserOptions^ Opts);
void Setup(ParserOptions^ Opts);
ParserResult^ Parse(const std::string& File);
void SetupHeader();
ParserResult^ ParseHeader(const std::string& File);
ParserResult^ ParseLibrary(const std::string& File);
protected:
@ -137,6 +140,7 @@ protected: @@ -137,6 +140,7 @@ protected:
int Index;
gcroot<Cxxi::Library^> Lib;
gcroot<ParserOptions^> Opts;
llvm::OwningPtr<clang::CompilerInstance> C;
clang::ASTContext* AST;
};

1
src/Parser/Parser.lua

@ -58,6 +58,7 @@ project "Parser" @@ -58,6 +58,7 @@ project "Parser"
links
{
"LLVMSupport",
"LLVMObject",
"LLVMAsmParser",
"LLVMBitReader",
"LLVMBitWriter",

Loading…
Cancel
Save