From dc84c9b765f0ba9504d248b9ecf2eb17ded82ed9 Mon Sep 17 00:00:00 2001
From: Dimitar Dobrev <dpldobrev@protonmail.com>
Date: Wed, 1 Jun 2016 14:45:49 +0300
Subject: [PATCH] Added an option to parse all headers at once - much faster.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
---
 src/Core/Parser/Parser.cs                     | 35 ++++++--
 src/CppParser/Bindings/CLI/CppParser.cpp      | 33 ++++++-
 src/CppParser/Bindings/CLI/CppParser.h        | 13 ++-
 .../i686-apple-darwin12.4.0/CppParser.cs      | 87 ++++++++++++++-----
 .../CSharp/i686-pc-win32-msvc/CppParser.cs    | 87 ++++++++++++++-----
 .../x86_64-apple-darwin12.4.0/CppParser.cs    | 87 ++++++++++++++-----
 .../CSharp/x86_64-linux-gnu/CppParser.cs      | 87 ++++++++++++++-----
 .../CSharp/x86_64-pc-win32-msvc/CppParser.cs  | 87 ++++++++++++++-----
 src/CppParser/CppParser.cpp                   |  3 +-
 src/CppParser/CppParser.h                     |  5 +-
 src/CppParser/Parser.cpp                      | 33 ++++---
 src/CppParser/Parser.h                        |  2 +-
 src/Generator/Driver.cs                       | 33 ++++---
 .../Generators/CSharp/CSharpTypePrinter.cs    |  5 +-
 src/Generator/Options.cs                      |  6 ++
 src/Generator/Passes/CleanUnitPass.cs         |  5 +-
 16 files changed, 460 insertions(+), 148 deletions(-)

diff --git a/src/Core/Parser/Parser.cs b/src/Core/Parser/Parser.cs
index 456ba681..2a39b59a 100644
--- a/src/Core/Parser/Parser.cs
+++ b/src/Core/Parser/Parser.cs
@@ -18,7 +18,7 @@ namespace CppSharp
         /// <summary>
         /// Fired when source files are parsed.
         /// </summary>
-        public Action<SourceFile, ParserResult> SourceParsed = delegate {};
+        public Action<IList<SourceFile>, ParserResult> SourcesParsed = delegate {};
 
         /// <summary>
         /// Fired when library files are parsed.
@@ -50,28 +50,45 @@ namespace CppSharp
         /// <summary>
         /// Parses a C++ source file to a translation unit.
         /// </summary>
-        public ParserResult ParseSourceFile(SourceFile file)
+        private ParserResult ParseSourceFile(SourceFile file)
         {
             var options = file.Options;
             options.ASTContext = ASTContext;
-            options.FileName = file.Path;
+            options.addSourceFiles(file.Path);
 
             var result = Parser.ClangParser.ParseHeader(options);
-            SourceParsed(file, result);
+            SourcesParsed(new[] { file }, result);
 
             return result;
         }
 
+        /// <summary>
+        /// Parses C++ source files to a translation unit.
+        /// </summary>
+        private void ParseSourceFiles(IList<SourceFile> files)
+        {
+            var options = files[0].Options;
+            options.ASTContext = ASTContext;
+
+            foreach (var file in files)
+                options.addSourceFiles(file.Path);
+            using (var result = Parser.ClangParser.ParseHeader(options))
+                SourcesParsed(files, result);
+        }
+
         /// <summary>
         /// Parses the project source files.
         /// </summary>
-        public void ParseProject(Project project)
+        public void ParseProject(Project project, bool unityBuild)
         {
             // TODO: Search for cached AST trees on disk
             // TODO: Do multi-threaded parsing of source files
-            
-            foreach (var parserResult in project.Sources.Select(s => ParseSourceFile(s)).ToList())
-                parserResult.Dispose();
+
+            if (unityBuild)
+                ParseSourceFiles(project.Sources);
+            else
+                foreach (var parserResult in project.Sources.Select(s => ParseSourceFile(s)).ToList())
+                    parserResult.Dispose();
         }
 
         /// <summary>
@@ -79,7 +96,7 @@ namespace CppSharp
         /// </summary>
         public ParserResult ParseLibrary(string file, ParserOptions options)
         {
-            options.FileName = file;
+            options.LibraryFile = file;
 
             var result = Parser.ClangParser.ParseLibrary(options);
             LibraryParsed(file, result);
diff --git a/src/CppParser/Bindings/CLI/CppParser.cpp b/src/CppParser/Bindings/CLI/CppParser.cpp
index 532a5593..89791f2e 100644
--- a/src/CppParser/Bindings/CLI/CppParser.cpp
+++ b/src/CppParser/Bindings/CLI/CppParser.cpp
@@ -46,6 +46,25 @@ void CppSharp::Parser::ParserOptions::clearArguments()
     ((::CppSharp::CppParser::ParserOptions*)NativePtr)->clearArguments();
 }
 
+System::String^ CppSharp::Parser::ParserOptions::getSourceFiles(unsigned int i)
+{
+    auto __ret = ((::CppSharp::CppParser::ParserOptions*)NativePtr)->getSourceFiles(i);
+    if (__ret == nullptr) return nullptr;
+    return (__ret == 0 ? nullptr : clix::marshalString<clix::E_UTF8>(__ret));
+}
+
+void CppSharp::Parser::ParserOptions::addSourceFiles(System::String^ s)
+{
+    auto _arg0 = clix::marshalString<clix::E_UTF8>(s);
+    auto arg0 = _arg0.c_str();
+    ((::CppSharp::CppParser::ParserOptions*)NativePtr)->addSourceFiles(arg0);
+}
+
+void CppSharp::Parser::ParserOptions::clearSourceFiles()
+{
+    ((::CppSharp::CppParser::ParserOptions*)NativePtr)->clearSourceFiles();
+}
+
 System::String^ CppSharp::Parser::ParserOptions::getIncludeDirs(unsigned int i)
 {
     auto __ret = ((::CppSharp::CppParser::ParserOptions*)NativePtr)->getIncludeDirs(i);
@@ -166,18 +185,24 @@ unsigned int CppSharp::Parser::ParserOptions::ArgumentsCount::get()
     return __ret;
 }
 
-System::String^ CppSharp::Parser::ParserOptions::FileName::get()
+System::String^ CppSharp::Parser::ParserOptions::LibraryFile::get()
 {
-    auto __ret = ((::CppSharp::CppParser::ParserOptions*)NativePtr)->getFileName();
+    auto __ret = ((::CppSharp::CppParser::ParserOptions*)NativePtr)->getLibraryFile();
     if (__ret == nullptr) return nullptr;
     return (__ret == 0 ? nullptr : clix::marshalString<clix::E_UTF8>(__ret));
 }
 
-void CppSharp::Parser::ParserOptions::FileName::set(System::String^ s)
+void CppSharp::Parser::ParserOptions::LibraryFile::set(System::String^ s)
 {
     auto _arg0 = clix::marshalString<clix::E_UTF8>(s);
     auto arg0 = _arg0.c_str();
-    ((::CppSharp::CppParser::ParserOptions*)NativePtr)->setFileName(arg0);
+    ((::CppSharp::CppParser::ParserOptions*)NativePtr)->setLibraryFile(arg0);
+}
+
+unsigned int CppSharp::Parser::ParserOptions::SourceFilesCount::get()
+{
+    auto __ret = ((::CppSharp::CppParser::ParserOptions*)NativePtr)->getSourceFilesCount();
+    return __ret;
 }
 
 unsigned int CppSharp::Parser::ParserOptions::IncludeDirsCount::get()
diff --git a/src/CppParser/Bindings/CLI/CppParser.h b/src/CppParser/Bindings/CLI/CppParser.h
index 02aae067..ab469927 100644
--- a/src/CppParser/Bindings/CLI/CppParser.h
+++ b/src/CppParser/Bindings/CLI/CppParser.h
@@ -89,12 +89,17 @@ namespace CppSharp
                 unsigned int get();
             }
 
-            property System::String^ FileName
+            property System::String^ LibraryFile
             {
                 System::String^ get();
                 void set(System::String^);
             }
 
+            property unsigned int SourceFilesCount
+            {
+                unsigned int get();
+            }
+
             property unsigned int IncludeDirsCount
             {
                 unsigned int get();
@@ -186,6 +191,12 @@ namespace CppSharp
 
             void clearArguments();
 
+            System::String^ getSourceFiles(unsigned int i);
+
+            void addSourceFiles(System::String^ s);
+
+            void clearSourceFiles();
+
             System::String^ getIncludeDirs(unsigned int i);
 
             void addIncludeDirs(System::String^ s);
diff --git a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppParser.cs b/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppParser.cs
index 03e7768f..a98395d9 100644
--- a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppParser.cs
@@ -49,34 +49,34 @@ namespace CppSharp
 
         public unsafe partial class ParserOptions : IDisposable
         {
-            [StructLayout(LayoutKind.Explicit, Size = 120)]
+            [StructLayout(LayoutKind.Explicit, Size = 132)]
             public partial struct Internal
             {
-                [FieldOffset(84)]
+                [FieldOffset(96)]
                 public global::System.IntPtr ASTContext;
 
-                [FieldOffset(88)]
+                [FieldOffset(100)]
                 public int ToolSetToUse;
 
-                [FieldOffset(104)]
+                [FieldOffset(116)]
                 public CppSharp.Parser.AST.CppAbi Abi;
 
-                [FieldOffset(108)]
+                [FieldOffset(120)]
                 public byte NoStandardIncludes;
 
-                [FieldOffset(109)]
+                [FieldOffset(121)]
                 public byte NoBuiltinIncludes;
 
-                [FieldOffset(110)]
+                [FieldOffset(122)]
                 public byte MicrosoftMode;
 
-                [FieldOffset(111)]
+                [FieldOffset(123)]
                 public byte Verbose;
 
-                [FieldOffset(112)]
+                [FieldOffset(124)]
                 public CppSharp.Parser.LanguageVersion LanguageVersion;
 
-                [FieldOffset(116)]
+                [FieldOffset(128)]
                 public global::System.IntPtr TargetInfo;
 
                 [SuppressUnmanagedCodeSecurity]
@@ -109,6 +109,21 @@ namespace CppSharp
                     EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14clearArgumentsEv")]
                 internal static extern void clearArguments_0(global::System.IntPtr instance);
 
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getSourceFilesEj")]
+                internal static extern global::System.IntPtr getSourceFiles_0(global::System.IntPtr instance, uint i);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14addSourceFilesEPKc")]
+                internal static extern void addSourceFiles_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions16clearSourceFilesEv")]
+                internal static extern void clearSourceFiles_0(global::System.IntPtr instance);
+
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
                     EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getIncludeDirsEj")]
@@ -191,13 +206,18 @@ namespace CppSharp
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions11getFileNameEv")]
-                internal static extern global::System.IntPtr getFileName_0(global::System.IntPtr instance);
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getLibraryFileEv")]
+                internal static extern global::System.IntPtr getLibraryFile_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions11setFileNameEPKc")]
-                internal static extern void setFileName_0(global::System.IntPtr instance, global::System.IntPtr s);
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14setLibraryFileEPKc")]
+                internal static extern void setLibraryFile_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions19getSourceFilesCountEv")]
+                internal static extern uint getSourceFilesCount_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@@ -255,7 +275,7 @@ namespace CppSharp
 
             private static void* __CopyValue(ParserOptions.Internal native)
             {
-                var ret = Marshal.AllocHGlobal(120);
+                var ret = Marshal.AllocHGlobal(132);
                 CppSharp.Parser.ParserOptions.Internal.cctor_2(ret, new global::System.IntPtr(&native));
                 return ret.ToPointer();
             }
@@ -276,7 +296,7 @@ namespace CppSharp
 
             public ParserOptions()
             {
-                __Instance = Marshal.AllocHGlobal(120);
+                __Instance = Marshal.AllocHGlobal(132);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 Internal.ctor_0((__Instance + __PointerAdjustment));
@@ -284,7 +304,7 @@ namespace CppSharp
 
             public ParserOptions(CppSharp.Parser.ParserOptions _0)
             {
-                __Instance = Marshal.AllocHGlobal(120);
+                __Instance = Marshal.AllocHGlobal(132);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 if (ReferenceEquals(_0, null))
@@ -325,6 +345,24 @@ namespace CppSharp
                 Internal.clearArguments_0((__Instance + __PointerAdjustment));
             }
 
+            public string getSourceFiles(uint i)
+            {
+                var __ret = Internal.getSourceFiles_0((__Instance + __PointerAdjustment), i);
+                return Marshal.PtrToStringAnsi(__ret);
+            }
+
+            public void addSourceFiles(string s)
+            {
+                var arg0 = Marshal.StringToHGlobalAnsi(s);
+                Internal.addSourceFiles_0((__Instance + __PointerAdjustment), arg0);
+                Marshal.FreeHGlobal(arg0);
+            }
+
+            public void clearSourceFiles()
+            {
+                Internal.clearSourceFiles_0((__Instance + __PointerAdjustment));
+            }
+
             public string getIncludeDirs(uint i)
             {
                 var __ret = Internal.getIncludeDirs_0((__Instance + __PointerAdjustment), i);
@@ -424,22 +462,31 @@ namespace CppSharp
                 }
             }
 
-            public string FileName
+            public string LibraryFile
             {
                 get
                 {
-                    var __ret = Internal.getFileName_0((__Instance + __PointerAdjustment));
+                    var __ret = Internal.getLibraryFile_0((__Instance + __PointerAdjustment));
                     return Marshal.PtrToStringAnsi(__ret);
                 }
 
                 set
                 {
                     var arg0 = Marshal.StringToHGlobalAnsi(value);
-                    Internal.setFileName_0((__Instance + __PointerAdjustment), arg0);
+                    Internal.setLibraryFile_0((__Instance + __PointerAdjustment), arg0);
                     Marshal.FreeHGlobal(arg0);
                 }
             }
 
+            public uint SourceFilesCount
+            {
+                get
+                {
+                    var __ret = Internal.getSourceFilesCount_0((__Instance + __PointerAdjustment));
+                    return __ret;
+                }
+            }
+
             public uint IncludeDirsCount
             {
                 get
diff --git a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppParser.cs b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppParser.cs
index 52bbb48a..23d88eb0 100644
--- a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppParser.cs
@@ -49,34 +49,34 @@ namespace CppSharp
 
         public unsafe partial class ParserOptions : IDisposable
         {
-            [StructLayout(LayoutKind.Explicit, Size = 144)]
+            [StructLayout(LayoutKind.Explicit, Size = 156)]
             public partial struct Internal
             {
-                [FieldOffset(96)]
+                [FieldOffset(108)]
                 public global::System.IntPtr ASTContext;
 
-                [FieldOffset(100)]
+                [FieldOffset(112)]
                 public int ToolSetToUse;
 
-                [FieldOffset(128)]
+                [FieldOffset(140)]
                 public CppSharp.Parser.AST.CppAbi Abi;
 
-                [FieldOffset(132)]
+                [FieldOffset(144)]
                 public byte NoStandardIncludes;
 
-                [FieldOffset(133)]
+                [FieldOffset(145)]
                 public byte NoBuiltinIncludes;
 
-                [FieldOffset(134)]
+                [FieldOffset(146)]
                 public byte MicrosoftMode;
 
-                [FieldOffset(135)]
+                [FieldOffset(147)]
                 public byte Verbose;
 
-                [FieldOffset(136)]
+                [FieldOffset(148)]
                 public CppSharp.Parser.LanguageVersion LanguageVersion;
 
-                [FieldOffset(140)]
+                [FieldOffset(152)]
                 public global::System.IntPtr TargetInfo;
 
                 [SuppressUnmanagedCodeSecurity]
@@ -109,6 +109,21 @@ namespace CppSharp
                     EntryPoint="?clearArguments@ParserOptions@CppParser@CppSharp@@QAEXXZ")]
                 internal static extern void clearArguments_0(global::System.IntPtr instance);
 
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
+                    EntryPoint="?getSourceFiles@ParserOptions@CppParser@CppSharp@@QAEPBDI@Z")]
+                internal static extern global::System.IntPtr getSourceFiles_0(global::System.IntPtr instance, uint i);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
+                    EntryPoint="?addSourceFiles@ParserOptions@CppParser@CppSharp@@QAEXPBD@Z")]
+                internal static extern void addSourceFiles_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
+                    EntryPoint="?clearSourceFiles@ParserOptions@CppParser@CppSharp@@QAEXXZ")]
+                internal static extern void clearSourceFiles_0(global::System.IntPtr instance);
+
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
                     EntryPoint="?getIncludeDirs@ParserOptions@CppParser@CppSharp@@QAEPBDI@Z")]
@@ -191,13 +206,18 @@ namespace CppSharp
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
-                    EntryPoint="?getFileName@ParserOptions@CppParser@CppSharp@@QAEPBDXZ")]
-                internal static extern global::System.IntPtr getFileName_0(global::System.IntPtr instance);
+                    EntryPoint="?getLibraryFile@ParserOptions@CppParser@CppSharp@@QAEPBDXZ")]
+                internal static extern global::System.IntPtr getLibraryFile_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
-                    EntryPoint="?setFileName@ParserOptions@CppParser@CppSharp@@QAEXPBD@Z")]
-                internal static extern void setFileName_0(global::System.IntPtr instance, global::System.IntPtr s);
+                    EntryPoint="?setLibraryFile@ParserOptions@CppParser@CppSharp@@QAEXPBD@Z")]
+                internal static extern void setLibraryFile_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
+                    EntryPoint="?getSourceFilesCount@ParserOptions@CppParser@CppSharp@@QAEIXZ")]
+                internal static extern uint getSourceFilesCount_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.ThisCall,
@@ -255,7 +275,7 @@ namespace CppSharp
 
             private static void* __CopyValue(ParserOptions.Internal native)
             {
-                var ret = Marshal.AllocHGlobal(144);
+                var ret = Marshal.AllocHGlobal(156);
                 CppSharp.Parser.ParserOptions.Internal.cctor_2(ret, new global::System.IntPtr(&native));
                 return ret.ToPointer();
             }
@@ -276,7 +296,7 @@ namespace CppSharp
 
             public ParserOptions()
             {
-                __Instance = Marshal.AllocHGlobal(144);
+                __Instance = Marshal.AllocHGlobal(156);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 Internal.ctor_0((__Instance + __PointerAdjustment));
@@ -284,7 +304,7 @@ namespace CppSharp
 
             public ParserOptions(CppSharp.Parser.ParserOptions _0)
             {
-                __Instance = Marshal.AllocHGlobal(144);
+                __Instance = Marshal.AllocHGlobal(156);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 if (ReferenceEquals(_0, null))
@@ -325,6 +345,24 @@ namespace CppSharp
                 Internal.clearArguments_0((__Instance + __PointerAdjustment));
             }
 
+            public string getSourceFiles(uint i)
+            {
+                var __ret = Internal.getSourceFiles_0((__Instance + __PointerAdjustment), i);
+                return Marshal.PtrToStringAnsi(__ret);
+            }
+
+            public void addSourceFiles(string s)
+            {
+                var arg0 = Marshal.StringToHGlobalAnsi(s);
+                Internal.addSourceFiles_0((__Instance + __PointerAdjustment), arg0);
+                Marshal.FreeHGlobal(arg0);
+            }
+
+            public void clearSourceFiles()
+            {
+                Internal.clearSourceFiles_0((__Instance + __PointerAdjustment));
+            }
+
             public string getIncludeDirs(uint i)
             {
                 var __ret = Internal.getIncludeDirs_0((__Instance + __PointerAdjustment), i);
@@ -424,22 +462,31 @@ namespace CppSharp
                 }
             }
 
-            public string FileName
+            public string LibraryFile
             {
                 get
                 {
-                    var __ret = Internal.getFileName_0((__Instance + __PointerAdjustment));
+                    var __ret = Internal.getLibraryFile_0((__Instance + __PointerAdjustment));
                     return Marshal.PtrToStringAnsi(__ret);
                 }
 
                 set
                 {
                     var arg0 = Marshal.StringToHGlobalAnsi(value);
-                    Internal.setFileName_0((__Instance + __PointerAdjustment), arg0);
+                    Internal.setLibraryFile_0((__Instance + __PointerAdjustment), arg0);
                     Marshal.FreeHGlobal(arg0);
                 }
             }
 
+            public uint SourceFilesCount
+            {
+                get
+                {
+                    var __ret = Internal.getSourceFilesCount_0((__Instance + __PointerAdjustment));
+                    return __ret;
+                }
+            }
+
             public uint IncludeDirsCount
             {
                 get
diff --git a/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppParser.cs b/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppParser.cs
index bc0920d6..f4048732 100644
--- a/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppParser.cs
@@ -49,34 +49,34 @@ namespace CppSharp
 
         public unsafe partial class ParserOptions : IDisposable
         {
-            [StructLayout(LayoutKind.Explicit, Size = 232)]
+            [StructLayout(LayoutKind.Explicit, Size = 256)]
             public partial struct Internal
             {
-                [FieldOffset(168)]
+                [FieldOffset(192)]
                 public global::System.IntPtr ASTContext;
 
-                [FieldOffset(176)]
+                [FieldOffset(200)]
                 public int ToolSetToUse;
 
-                [FieldOffset(208)]
+                [FieldOffset(232)]
                 public CppSharp.Parser.AST.CppAbi Abi;
 
-                [FieldOffset(212)]
+                [FieldOffset(236)]
                 public byte NoStandardIncludes;
 
-                [FieldOffset(213)]
+                [FieldOffset(237)]
                 public byte NoBuiltinIncludes;
 
-                [FieldOffset(214)]
+                [FieldOffset(238)]
                 public byte MicrosoftMode;
 
-                [FieldOffset(215)]
+                [FieldOffset(239)]
                 public byte Verbose;
 
-                [FieldOffset(216)]
+                [FieldOffset(240)]
                 public CppSharp.Parser.LanguageVersion LanguageVersion;
 
-                [FieldOffset(224)]
+                [FieldOffset(248)]
                 public global::System.IntPtr TargetInfo;
 
                 [SuppressUnmanagedCodeSecurity]
@@ -109,6 +109,21 @@ namespace CppSharp
                     EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14clearArgumentsEv")]
                 internal static extern void clearArguments_0(global::System.IntPtr instance);
 
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getSourceFilesEj")]
+                internal static extern global::System.IntPtr getSourceFiles_0(global::System.IntPtr instance, uint i);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14addSourceFilesEPKc")]
+                internal static extern void addSourceFiles_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions16clearSourceFilesEv")]
+                internal static extern void clearSourceFiles_0(global::System.IntPtr instance);
+
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
                     EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getIncludeDirsEj")]
@@ -191,13 +206,18 @@ namespace CppSharp
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions11getFileNameEv")]
-                internal static extern global::System.IntPtr getFileName_0(global::System.IntPtr instance);
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getLibraryFileEv")]
+                internal static extern global::System.IntPtr getLibraryFile_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions11setFileNameEPKc")]
-                internal static extern void setFileName_0(global::System.IntPtr instance, global::System.IntPtr s);
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14setLibraryFileEPKc")]
+                internal static extern void setLibraryFile_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions19getSourceFilesCountEv")]
+                internal static extern uint getSourceFilesCount_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@@ -255,7 +275,7 @@ namespace CppSharp
 
             private static void* __CopyValue(ParserOptions.Internal native)
             {
-                var ret = Marshal.AllocHGlobal(232);
+                var ret = Marshal.AllocHGlobal(256);
                 CppSharp.Parser.ParserOptions.Internal.cctor_2(ret, new global::System.IntPtr(&native));
                 return ret.ToPointer();
             }
@@ -276,7 +296,7 @@ namespace CppSharp
 
             public ParserOptions()
             {
-                __Instance = Marshal.AllocHGlobal(232);
+                __Instance = Marshal.AllocHGlobal(256);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 Internal.ctor_0((__Instance + __PointerAdjustment));
@@ -284,7 +304,7 @@ namespace CppSharp
 
             public ParserOptions(CppSharp.Parser.ParserOptions _0)
             {
-                __Instance = Marshal.AllocHGlobal(232);
+                __Instance = Marshal.AllocHGlobal(256);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 if (ReferenceEquals(_0, null))
@@ -325,6 +345,24 @@ namespace CppSharp
                 Internal.clearArguments_0((__Instance + __PointerAdjustment));
             }
 
+            public string getSourceFiles(uint i)
+            {
+                var __ret = Internal.getSourceFiles_0((__Instance + __PointerAdjustment), i);
+                return Marshal.PtrToStringAnsi(__ret);
+            }
+
+            public void addSourceFiles(string s)
+            {
+                var arg0 = Marshal.StringToHGlobalAnsi(s);
+                Internal.addSourceFiles_0((__Instance + __PointerAdjustment), arg0);
+                Marshal.FreeHGlobal(arg0);
+            }
+
+            public void clearSourceFiles()
+            {
+                Internal.clearSourceFiles_0((__Instance + __PointerAdjustment));
+            }
+
             public string getIncludeDirs(uint i)
             {
                 var __ret = Internal.getIncludeDirs_0((__Instance + __PointerAdjustment), i);
@@ -424,22 +462,31 @@ namespace CppSharp
                 }
             }
 
-            public string FileName
+            public string LibraryFile
             {
                 get
                 {
-                    var __ret = Internal.getFileName_0((__Instance + __PointerAdjustment));
+                    var __ret = Internal.getLibraryFile_0((__Instance + __PointerAdjustment));
                     return Marshal.PtrToStringAnsi(__ret);
                 }
 
                 set
                 {
                     var arg0 = Marshal.StringToHGlobalAnsi(value);
-                    Internal.setFileName_0((__Instance + __PointerAdjustment), arg0);
+                    Internal.setLibraryFile_0((__Instance + __PointerAdjustment), arg0);
                     Marshal.FreeHGlobal(arg0);
                 }
             }
 
+            public uint SourceFilesCount
+            {
+                get
+                {
+                    var __ret = Internal.getSourceFilesCount_0((__Instance + __PointerAdjustment));
+                    return __ret;
+                }
+            }
+
             public uint IncludeDirsCount
             {
                 get
diff --git a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppParser.cs b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppParser.cs
index f967a685..16d30aa9 100644
--- a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppParser.cs
@@ -49,34 +49,34 @@ namespace CppSharp
 
         public unsafe partial class ParserOptions : IDisposable
         {
-            [StructLayout(LayoutKind.Explicit, Size = 200)]
+            [StructLayout(LayoutKind.Explicit, Size = 224)]
             public partial struct Internal
             {
-                [FieldOffset(152)]
+                [FieldOffset(176)]
                 public global::System.IntPtr ASTContext;
 
-                [FieldOffset(160)]
+                [FieldOffset(184)]
                 public int ToolSetToUse;
 
-                [FieldOffset(176)]
+                [FieldOffset(200)]
                 public CppSharp.Parser.AST.CppAbi Abi;
 
-                [FieldOffset(180)]
+                [FieldOffset(204)]
                 public byte NoStandardIncludes;
 
-                [FieldOffset(181)]
+                [FieldOffset(205)]
                 public byte NoBuiltinIncludes;
 
-                [FieldOffset(182)]
+                [FieldOffset(206)]
                 public byte MicrosoftMode;
 
-                [FieldOffset(183)]
+                [FieldOffset(207)]
                 public byte Verbose;
 
-                [FieldOffset(184)]
+                [FieldOffset(208)]
                 public CppSharp.Parser.LanguageVersion LanguageVersion;
 
-                [FieldOffset(192)]
+                [FieldOffset(216)]
                 public global::System.IntPtr TargetInfo;
 
                 [SuppressUnmanagedCodeSecurity]
@@ -109,6 +109,21 @@ namespace CppSharp
                     EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14clearArgumentsEv")]
                 internal static extern void clearArguments_0(global::System.IntPtr instance);
 
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getSourceFilesEj")]
+                internal static extern global::System.IntPtr getSourceFiles_0(global::System.IntPtr instance, uint i);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14addSourceFilesEPKc")]
+                internal static extern void addSourceFiles_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions16clearSourceFilesEv")]
+                internal static extern void clearSourceFiles_0(global::System.IntPtr instance);
+
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
                     EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getIncludeDirsEj")]
@@ -191,13 +206,18 @@ namespace CppSharp
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions11getFileNameEv")]
-                internal static extern global::System.IntPtr getFileName_0(global::System.IntPtr instance);
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14getLibraryFileEv")]
+                internal static extern global::System.IntPtr getLibraryFile_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions11setFileNameEPKc")]
-                internal static extern void setFileName_0(global::System.IntPtr instance, global::System.IntPtr s);
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions14setLibraryFileEPKc")]
+                internal static extern void setLibraryFile_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="_ZN8CppSharp9CppParser13ParserOptions19getSourceFilesCountEv")]
+                internal static extern uint getSourceFilesCount_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@@ -255,7 +275,7 @@ namespace CppSharp
 
             private static void* __CopyValue(ParserOptions.Internal native)
             {
-                var ret = Marshal.AllocHGlobal(200);
+                var ret = Marshal.AllocHGlobal(224);
                 CppSharp.Parser.ParserOptions.Internal.cctor_1(ret, new global::System.IntPtr(&native));
                 return ret.ToPointer();
             }
@@ -276,7 +296,7 @@ namespace CppSharp
 
             public ParserOptions()
             {
-                __Instance = Marshal.AllocHGlobal(200);
+                __Instance = Marshal.AllocHGlobal(224);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 Internal.ctor_0((__Instance + __PointerAdjustment));
@@ -284,7 +304,7 @@ namespace CppSharp
 
             public ParserOptions(CppSharp.Parser.ParserOptions _0)
             {
-                __Instance = Marshal.AllocHGlobal(200);
+                __Instance = Marshal.AllocHGlobal(224);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 if (ReferenceEquals(_0, null))
@@ -325,6 +345,24 @@ namespace CppSharp
                 Internal.clearArguments_0((__Instance + __PointerAdjustment));
             }
 
+            public string getSourceFiles(uint i)
+            {
+                var __ret = Internal.getSourceFiles_0((__Instance + __PointerAdjustment), i);
+                return Marshal.PtrToStringAnsi(__ret);
+            }
+
+            public void addSourceFiles(string s)
+            {
+                var arg0 = Marshal.StringToHGlobalAnsi(s);
+                Internal.addSourceFiles_0((__Instance + __PointerAdjustment), arg0);
+                Marshal.FreeHGlobal(arg0);
+            }
+
+            public void clearSourceFiles()
+            {
+                Internal.clearSourceFiles_0((__Instance + __PointerAdjustment));
+            }
+
             public string getIncludeDirs(uint i)
             {
                 var __ret = Internal.getIncludeDirs_0((__Instance + __PointerAdjustment), i);
@@ -424,22 +462,31 @@ namespace CppSharp
                 }
             }
 
-            public string FileName
+            public string LibraryFile
             {
                 get
                 {
-                    var __ret = Internal.getFileName_0((__Instance + __PointerAdjustment));
+                    var __ret = Internal.getLibraryFile_0((__Instance + __PointerAdjustment));
                     return Marshal.PtrToStringAnsi(__ret);
                 }
 
                 set
                 {
                     var arg0 = Marshal.StringToHGlobalAnsi(value);
-                    Internal.setFileName_0((__Instance + __PointerAdjustment), arg0);
+                    Internal.setLibraryFile_0((__Instance + __PointerAdjustment), arg0);
                     Marshal.FreeHGlobal(arg0);
                 }
             }
 
+            public uint SourceFilesCount
+            {
+                get
+                {
+                    var __ret = Internal.getSourceFilesCount_0((__Instance + __PointerAdjustment));
+                    return __ret;
+                }
+            }
+
             public uint IncludeDirsCount
             {
                 get
diff --git a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppParser.cs b/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppParser.cs
index 0df31f4a..ed90de30 100644
--- a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppParser.cs
@@ -49,34 +49,34 @@ namespace CppSharp
 
         public unsafe partial class ParserOptions : IDisposable
         {
-            [StructLayout(LayoutKind.Explicit, Size = 248)]
+            [StructLayout(LayoutKind.Explicit, Size = 272)]
             public partial struct Internal
             {
-                [FieldOffset(176)]
+                [FieldOffset(200)]
                 public global::System.IntPtr ASTContext;
 
-                [FieldOffset(184)]
+                [FieldOffset(208)]
                 public int ToolSetToUse;
 
-                [FieldOffset(224)]
+                [FieldOffset(248)]
                 public CppSharp.Parser.AST.CppAbi Abi;
 
-                [FieldOffset(228)]
+                [FieldOffset(252)]
                 public byte NoStandardIncludes;
 
-                [FieldOffset(229)]
+                [FieldOffset(253)]
                 public byte NoBuiltinIncludes;
 
-                [FieldOffset(230)]
+                [FieldOffset(254)]
                 public byte MicrosoftMode;
 
-                [FieldOffset(231)]
+                [FieldOffset(255)]
                 public byte Verbose;
 
-                [FieldOffset(232)]
+                [FieldOffset(256)]
                 public CppSharp.Parser.LanguageVersion LanguageVersion;
 
-                [FieldOffset(240)]
+                [FieldOffset(264)]
                 public global::System.IntPtr TargetInfo;
 
                 [SuppressUnmanagedCodeSecurity]
@@ -109,6 +109,21 @@ namespace CppSharp
                     EntryPoint="?clearArguments@ParserOptions@CppParser@CppSharp@@QEAAXXZ")]
                 internal static extern void clearArguments_0(global::System.IntPtr instance);
 
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="?getSourceFiles@ParserOptions@CppParser@CppSharp@@QEAAPEBDI@Z")]
+                internal static extern global::System.IntPtr getSourceFiles_0(global::System.IntPtr instance, uint i);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="?addSourceFiles@ParserOptions@CppParser@CppSharp@@QEAAXPEBD@Z")]
+                internal static extern void addSourceFiles_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="?clearSourceFiles@ParserOptions@CppParser@CppSharp@@QEAAXXZ")]
+                internal static extern void clearSourceFiles_0(global::System.IntPtr instance);
+
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
                     EntryPoint="?getIncludeDirs@ParserOptions@CppParser@CppSharp@@QEAAPEBDI@Z")]
@@ -191,13 +206,18 @@ namespace CppSharp
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="?getFileName@ParserOptions@CppParser@CppSharp@@QEAAPEBDXZ")]
-                internal static extern global::System.IntPtr getFileName_0(global::System.IntPtr instance);
+                    EntryPoint="?getLibraryFile@ParserOptions@CppParser@CppSharp@@QEAAPEBDXZ")]
+                internal static extern global::System.IntPtr getLibraryFile_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
-                    EntryPoint="?setFileName@ParserOptions@CppParser@CppSharp@@QEAAXPEBD@Z")]
-                internal static extern void setFileName_0(global::System.IntPtr instance, global::System.IntPtr s);
+                    EntryPoint="?setLibraryFile@ParserOptions@CppParser@CppSharp@@QEAAXPEBD@Z")]
+                internal static extern void setLibraryFile_0(global::System.IntPtr instance, global::System.IntPtr s);
+
+                [SuppressUnmanagedCodeSecurity]
+                [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
+                    EntryPoint="?getSourceFilesCount@ParserOptions@CppParser@CppSharp@@QEAAIXZ")]
+                internal static extern uint getSourceFilesCount_0(global::System.IntPtr instance);
 
                 [SuppressUnmanagedCodeSecurity]
                 [DllImport("CppSharp.CppParser.dll", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
@@ -255,7 +275,7 @@ namespace CppSharp
 
             private static void* __CopyValue(ParserOptions.Internal native)
             {
-                var ret = Marshal.AllocHGlobal(248);
+                var ret = Marshal.AllocHGlobal(272);
                 CppSharp.Parser.ParserOptions.Internal.cctor_2(ret, new global::System.IntPtr(&native));
                 return ret.ToPointer();
             }
@@ -276,7 +296,7 @@ namespace CppSharp
 
             public ParserOptions()
             {
-                __Instance = Marshal.AllocHGlobal(248);
+                __Instance = Marshal.AllocHGlobal(272);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 Internal.ctor_0((__Instance + __PointerAdjustment));
@@ -284,7 +304,7 @@ namespace CppSharp
 
             public ParserOptions(CppSharp.Parser.ParserOptions _0)
             {
-                __Instance = Marshal.AllocHGlobal(248);
+                __Instance = Marshal.AllocHGlobal(272);
                 __ownsNativeInstance = true;
                 NativeToManagedMap[__Instance] = this;
                 if (ReferenceEquals(_0, null))
@@ -325,6 +345,24 @@ namespace CppSharp
                 Internal.clearArguments_0((__Instance + __PointerAdjustment));
             }
 
+            public string getSourceFiles(uint i)
+            {
+                var __ret = Internal.getSourceFiles_0((__Instance + __PointerAdjustment), i);
+                return Marshal.PtrToStringAnsi(__ret);
+            }
+
+            public void addSourceFiles(string s)
+            {
+                var arg0 = Marshal.StringToHGlobalAnsi(s);
+                Internal.addSourceFiles_0((__Instance + __PointerAdjustment), arg0);
+                Marshal.FreeHGlobal(arg0);
+            }
+
+            public void clearSourceFiles()
+            {
+                Internal.clearSourceFiles_0((__Instance + __PointerAdjustment));
+            }
+
             public string getIncludeDirs(uint i)
             {
                 var __ret = Internal.getIncludeDirs_0((__Instance + __PointerAdjustment), i);
@@ -424,22 +462,31 @@ namespace CppSharp
                 }
             }
 
-            public string FileName
+            public string LibraryFile
             {
                 get
                 {
-                    var __ret = Internal.getFileName_0((__Instance + __PointerAdjustment));
+                    var __ret = Internal.getLibraryFile_0((__Instance + __PointerAdjustment));
                     return Marshal.PtrToStringAnsi(__ret);
                 }
 
                 set
                 {
                     var arg0 = Marshal.StringToHGlobalAnsi(value);
-                    Internal.setFileName_0((__Instance + __PointerAdjustment), arg0);
+                    Internal.setLibraryFile_0((__Instance + __PointerAdjustment), arg0);
                     Marshal.FreeHGlobal(arg0);
                 }
             }
 
+            public uint SourceFilesCount
+            {
+                get
+                {
+                    var __ret = Internal.getSourceFilesCount_0((__Instance + __PointerAdjustment));
+                    return __ret;
+                }
+            }
+
             public uint IncludeDirsCount
             {
                 get
diff --git a/src/CppParser/CppParser.cpp b/src/CppParser/CppParser.cpp
index ccb9fc02..afaf9dc1 100644
--- a/src/CppParser/CppParser.cpp
+++ b/src/CppParser/CppParser.cpp
@@ -24,7 +24,8 @@ ParserOptions::ParserOptions()
 }
 
 DEF_VECTOR_STRING(ParserOptions, Arguments)
-DEF_STRING(ParserOptions, FileName)
+DEF_STRING(ParserOptions, LibraryFile)
+DEF_VECTOR_STRING(ParserOptions, SourceFiles)
 DEF_VECTOR_STRING(ParserOptions, IncludeDirs)
 DEF_VECTOR_STRING(ParserOptions, SystemIncludeDirs)
 DEF_VECTOR_STRING(ParserOptions, Defines)
diff --git a/src/CppParser/CppParser.h b/src/CppParser/CppParser.h
index c579e6a8..8a30fb3f 100644
--- a/src/CppParser/CppParser.h
+++ b/src/CppParser/CppParser.h
@@ -37,8 +37,9 @@ struct CS_API ParserOptions
 
     VECTOR_STRING(Arguments)
 
-    // C/C++ header file name.
-    STRING(FileName)
+    STRING(LibraryFile)
+    // C/C++ header file names.
+    VECTOR_STRING(SourceFiles)
 
     // Include directories
     VECTOR_STRING(IncludeDirs)
diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp
index a71d227f..b3514558 100644
--- a/src/CppParser/Parser.cpp
+++ b/src/CppParser/Parser.cpp
@@ -3222,13 +3222,13 @@ void Parser::HandleDiagnostics(ParserResult* res)
     }
 }
 
-ParserResult* Parser::ParseHeader(const std::string& File, ParserResult* res)
+ParserResult* Parser::ParseHeader(const std::vector<std::string>& SourceFiles, ParserResult* res)
 {
     assert(Opts->ASTContext && "Expected a valid ASTContext");
 
     res->ASTContext = Lib;
 
-    if (File.empty())
+    if (SourceFiles.empty())
     {
         res->Kind = ParserResultKind::FileNotFound;
         return res;
@@ -3250,20 +3250,28 @@ ParserResult* Parser::ParseHeader(const std::string& File, ParserResult* res)
         std::pair<const clang::FileEntry *, const clang::DirectoryEntry *>,
         0> Includers;
 
-    auto FileEntry = C->getPreprocessor().getHeaderSearchInfo().LookupFile(File,
-        clang::SourceLocation(), /*isAngled*/true,
-        nullptr, Dir, Includers, nullptr, nullptr, nullptr, nullptr);
-    if (!FileEntry)
+    std::vector<const clang::FileEntry*> FileEntries;
+    for (const auto& SourceFile : SourceFiles)
     {
-        res->Kind = ParserResultKind::FileNotFound;
-        return res;
+        auto FileEntry = C->getPreprocessor().getHeaderSearchInfo().LookupFile(SourceFile,
+            clang::SourceLocation(), /*isAngled*/true,
+            nullptr, Dir, Includers, nullptr, nullptr, nullptr, nullptr);
+        if (!FileEntry)
+        {
+            res->Kind = ParserResultKind::FileNotFound;
+            return res;
+        }
+        FileEntries.push_back(FileEntry);
     }
 
     // Create a virtual file that includes the header. This gets rid of some
     // Clang warnings about parsing an header file as the main file.
 
     std::string str;
-    str += "#include \"" + File + "\"" + "\n";
+    for (const auto& SourceFile : SourceFiles)
+    {
+        str += "#include \"" + SourceFile + "\"" + "\n";
+    }
     str += "\0";
 
     auto buffer = llvm::MemoryBuffer::getMemBuffer(str);
@@ -3287,6 +3295,7 @@ ParserResult* Parser::ParseHeader(const std::string& File, ParserResult* res)
 
     AST = &C->getASTContext();
 
+    auto FileEntry = FileEntries[0];
     auto FileName = FileEntry->getName();
     auto Unit = Lib->FindOrCreateModule(FileName);
 
@@ -3294,7 +3303,7 @@ ParserResult* Parser::ParseHeader(const std::string& File, ParserResult* res)
     HandleDeclaration(TU, Unit);
 
     if (Unit->OriginalPtr == nullptr)
-        Unit->OriginalPtr = (void*) FileEntry;
+        Unit->OriginalPtr = (void*)FileEntry;
 
     // Initialize enough Clang codegen machinery so we can get at ABI details.
     llvm::LLVMContext Ctx;
@@ -3524,7 +3533,7 @@ ParserResult* ClangParser::ParseHeader(ParserOptions* Opts)
 
     auto res = new ParserResult();
     res->CodeParser = new Parser(Opts);
-    return res->CodeParser->ParseHeader(Opts->FileName, res);
+    return res->CodeParser->ParseHeader(Opts->SourceFiles, res);
 }
 
 ParserResult* ClangParser::ParseLibrary(ParserOptions* Opts)
@@ -3534,7 +3543,7 @@ ParserResult* ClangParser::ParseLibrary(ParserOptions* Opts)
 
     auto res = new ParserResult();
     res->CodeParser = new Parser(Opts);
-    return res->CodeParser->ParseLibrary(Opts->FileName, res);
+    return res->CodeParser->ParseLibrary(Opts->LibraryFile, res);
 }
 
 ParserTargetInfo* ClangParser::GetTargetInfo(ParserOptions* Opts)
diff --git a/src/CppParser/Parser.h b/src/CppParser/Parser.h
index 6fe2fd7e..5f23845e 100644
--- a/src/CppParser/Parser.h
+++ b/src/CppParser/Parser.h
@@ -48,7 +48,7 @@ public:
     Parser(ParserOptions* Opts);
 
     void SetupHeader();
-    ParserResult* ParseHeader(const std::string& File, ParserResult* res);
+    ParserResult* ParseHeader(const std::vector<std::string>& SourceFiles, ParserResult* res);
     ParserResult* ParseLibrary(const std::string& File, ParserResult* res);
     ParserResultKind ParseArchive(llvm::StringRef File,
                                   llvm::object::Archive* Archive,
diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs
index ed65b101..e5d771c8 100644
--- a/src/Generator/Driver.cs
+++ b/src/Generator/Driver.cs
@@ -12,7 +12,6 @@ using CppSharp.Passes;
 using CppSharp.Types;
 using Microsoft.CSharp;
 using CppSharp.Parser;
-using System.CodeDom;
 using System;
 using System.Reflection;
 
@@ -99,24 +98,29 @@ namespace CppSharp
                 Options.SetupMSVC();
         }
 
-        void OnSourceFileParsed(SourceFile file, ParserResult result)
+        void OnSourceFileParsed(IList<SourceFile> files, ParserResult result)
         {
-            OnFileParsed(file.Path, result);
+            OnFileParsed(files.Select(f => f.Path), result);
         }
 
         void OnFileParsed(string file, ParserResult result)
+        {
+            OnFileParsed(new[] { file }, result);
+        }
+
+        void OnFileParsed(IEnumerable<string> files, ParserResult result)
         {
             switch (result.Kind)
             {
                 case ParserResultKind.Success:
-                    Diagnostics.Message("Parsed '{0}'", file);
+                    Diagnostics.Message("Parsed '{0}'", string.Join(", ", files));
                     break;
                 case ParserResultKind.Error:
-                    Diagnostics.Error("Error parsing '{0}'", file);
+                    Diagnostics.Error("Error parsing '{0}'", string.Join(", ", files));
                     hasParsingErrors = true;
                     break;
                 case ParserResultKind.FileNotFound:
-                    Diagnostics.Error("File '{0}' was not found", file);
+                    Diagnostics.Error("A file from '{0}' was not found", string.Join(",", files));
                     break;
             }
 
@@ -137,11 +141,10 @@ namespace CppSharp
             }
         }
 
-        public ParserOptions BuildParseOptions(SourceFile file)
+        public ParserOptions BuildParserOptions()
         {
             var options = new ParserOptions
             {
-                FileName = file.Path,
                 Abi = Options.Abi,
                 ToolSetToUse = Options.ToolSetToUse,
                 TargetTriple = Options.TargetTriple,
@@ -197,7 +200,7 @@ namespace CppSharp
                 options.addLibraryDirs(lib);
             }
 
-            foreach (var module in Options.Modules.Where(m => m.Headers.Contains(file.Path)))
+            foreach (var module in Options.Modules)
             {
                 foreach (var include in module.IncludeDirs)
                     options.addIncludeDirs(include);
@@ -219,8 +222,8 @@ namespace CppSharp
         {
             var parser = new ClangParser(new Parser.AST.ASTContext());
 
-            parser.SourceParsed += OnSourceFileParsed;
-            parser.ParseProject(Project);
+            parser.SourcesParsed += OnSourceFileParsed;
+            parser.ParseProject(Project, Options.UnityBuild);
            
             TargetInfo = parser.GetTargetInfo(Options);
 
@@ -234,7 +237,7 @@ namespace CppSharp
             foreach (var header in Options.Modules.SelectMany(m => m.Headers))
             {
                 var source = Project.AddFile(header);
-                source.Options = BuildParseOptions(source);
+                source.Options = BuildParserOptions();
             }
         }
 
@@ -416,7 +419,7 @@ namespace CppSharp
                          !compilerParameters.ReferencedAssemblies.Contains(libraryMappings[d]))
                     .Select(l => libraryMappings[l])).ToArray());
 
-            Diagnostics.Message("Compiling generated code...");
+            Diagnostics.Message("Compiling {0}...", module.LibraryName);
             CompilerResults compilerResults;
             using (var codeProvider = new CSharpCodeProvider(
                 new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }))
@@ -523,7 +526,11 @@ namespace CppSharp
                 driver.SaveCode(outputs);
                 if (driver.Options.IsCSharpGenerator && driver.Options.CompileCode)
                     foreach (var module in driver.Options.Modules)
+                    {
                         driver.CompileCode(module);
+                        if (driver.HasCompilationErrors)
+                            break;
+                    }
             }
 
             driver.Generator.Dispose();
diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs
index 518ad779..16d8e1bd 100644
--- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs
+++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs
@@ -5,7 +5,6 @@ using CppSharp.AST.Extensions;
 using CppSharp.Types;
 using Type = CppSharp.AST.Type;
 using ParserTargetInfo = CppSharp.Parser.ParserTargetInfo;
-using System.Linq;
 
 namespace CppSharp.Generators.CSharp
 {
@@ -142,7 +141,7 @@ namespace CppSharp.Generators.CSharp
                 Class @class;
                 if (arrayType.TryGetClass(out @class))
                 {
-                    return new CSharpTypePrinterResult()
+                    return new CSharpTypePrinterResult
                     {
                         Type = "fixed byte",
                         NameSuffix = string.Format("[{0}]", array.Size * @class.Layout.Size)
@@ -158,7 +157,7 @@ namespace CppSharp.Generators.CSharp
 
                 // Do not write the fixed keyword multiple times for nested array types
                 var fixedKeyword = array.Type is ArrayType ? string.Empty : "fixed ";
-                return new CSharpTypePrinterResult()
+                return new CSharpTypePrinterResult
                 {
                     Type = string.Format("{0}{1}", fixedKeyword, arrayElemType),
                     NameSuffix = string.Format("[{0}]", array.Size)
diff --git a/src/Generator/Options.cs b/src/Generator/Options.cs
index 613ed72a..e6ad0796 100644
--- a/src/Generator/Options.cs
+++ b/src/Generator/Options.cs
@@ -156,6 +156,12 @@ namespace CppSharp
         /// </summary>
         public bool GenerateFinalizers;
 
+        /// <summary>
+        /// If this option is off (the default), each header is parsed separately which is much slower
+        /// but safer because of a clean state of the preprocessor for each header.
+        /// </summary>
+        public bool UnityBuild { get; set; }
+
         public string IncludePrefix;
         public bool WriteOnlyWhenChanged;
         public Func<TranslationUnit, string> GenerateName;
diff --git a/src/Generator/Passes/CleanUnitPass.cs b/src/Generator/Passes/CleanUnitPass.cs
index ca0b4ac3..c5cb0e49 100644
--- a/src/Generator/Passes/CleanUnitPass.cs
+++ b/src/Generator/Passes/CleanUnitPass.cs
@@ -18,9 +18,10 @@ namespace CppSharp.Passes
         {
             if (unit.IsValid && !unit.IsSystemHeader && unit.HasDeclarations)
             {
-                var includeDir = Path.GetDirectoryName(unit.FilePath);
+                var includeDir = Path.GetFullPath(Path.GetDirectoryName(unit.FilePath));
                 unit.Module = DriverOptions.Modules.FirstOrDefault(
-                    m => m.IncludeDirs.Contains(includeDir)) ?? DriverOptions.MainModule;
+                    m => m.IncludeDirs.Any(i => Path.GetFullPath(i) == includeDir)) ??
+                    DriverOptions.MainModule;
                 unit.Module.Units.Add(unit);
             }