Browse Source

Merge pull request #341 from ddobrev/master

Simplified the pass for inlines thus including more symbols
pull/343/head
João Matos 11 years ago
parent
commit
d8840132b2
  1. 93
      src/Generator/Passes/GenerateInlinesCodePass.cs

93
src/Generator/Passes/GenerateInlinesCodePass.cs

@ -1,103 +1,42 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using CppSharp.AST; using CppSharp.AST;
using CppAbi = CppSharp.Parser.AST.CppAbi;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
public class GenerateInlinesCodePass : TranslationUnitPass public class GenerateInlinesCodePass : TranslationUnitPass
{ {
private TranslationUnit currentUnit; public GenerateInlinesCodePass()
private readonly List<string> headers = new List<string>(); {
private readonly List<string> mangledInlines = new List<string>(); this.SkipPatterns = new List<string>();
}
public List<string> SkipPatterns { get; private set; }
public override bool VisitLibrary(ASTContext context) public override bool VisitLibrary(ASTContext context)
{ {
bool result = base.VisitLibrary(context); bool result = base.VisitLibrary(context);
Directory.CreateDirectory(Driver.Options.OutputDir); Directory.CreateDirectory(Driver.Options.OutputDir);
WriteInlinesIncludes(); WriteInlinesIncludes(context);
WriteInlinedSymbols();
return result; return result;
} }
private void WriteInlinesIncludes() private void WriteInlinesIncludes(ASTContext context)
{ {
var cppBuilder = new StringBuilder(); var cppBuilder = new StringBuilder();
headers.Sort(); foreach (var header in from translationUnit in context.TranslationUnits
foreach (var header in headers) where translationUnit.IsValid && !translationUnit.IsSystemHeader &&
translationUnit.GenerationKind == GenerationKind.Generate
let fileName = translationUnit.FileName
where SkipPatterns.All(p => !fileName.EndsWith(p))
orderby fileName
select fileName)
cppBuilder.AppendFormat("#include \"{0}\"\n", header); cppBuilder.AppendFormat("#include \"{0}\"\n", header);
var cpp = string.Format("{0}.cpp", Driver.Options.InlinesLibraryName); var cpp = string.Format("{0}.cpp", Driver.Options.InlinesLibraryName);
var path = Path.Combine(Driver.Options.OutputDir, cpp); var path = Path.Combine(Driver.Options.OutputDir, cpp);
File.WriteAllText(path, cppBuilder.ToString()); File.WriteAllText(path, cppBuilder.ToString());
} }
private void WriteInlinedSymbols()
{
switch (Driver.Options.Abi)
{
case CppAbi.Microsoft:
var defBuilder = new StringBuilder("EXPORTS\r\n");
for (int i = 0; i < mangledInlines.Count; i++)
defBuilder.AppendFormat(" {0} @{1}\r\n",
mangledInlines[i], i + 1);
var def = string.Format("{0}.def", Driver.Options.InlinesLibraryName);
File.WriteAllText(Path.Combine(Driver.Options.OutputDir, def),
defBuilder.ToString());
break;
default:
var symbolsBuilder = new StringBuilder();
foreach (var mangledInline in mangledInlines)
symbolsBuilder.AppendFormat("{0}\n", mangledInline);
var txt = string.Format("{0}.txt", Driver.Options.InlinesLibraryName);
File.WriteAllText(Path.Combine(Driver.Options.OutputDir, txt),
symbolsBuilder.ToString());
break;
}
}
public override bool VisitTranslationUnit(TranslationUnit unit)
{
currentUnit = unit;
return base.VisitTranslationUnit(unit);
}
public override bool VisitFunctionDecl(Function function)
{
CheckForSymbols(function);
return base.VisitFunctionDecl(function);
}
public override bool VisitVariableDecl(Variable variable)
{
CheckForSymbols(variable);
return base.VisitVariableDecl(variable);
}
private void CheckForSymbols(IMangledDecl mangled)
{
string symbol = mangled.Mangled;
var declaration = (Declaration) mangled;
if (declaration.IsGenerated && AccessValid(declaration) &&
!Driver.Symbols.FindSymbol(ref symbol) &&
!currentUnit.FilePath.EndsWith("_impl.h") &&
!currentUnit.FilePath.EndsWith("_p.h"))
{
if (!headers.Contains(currentUnit.FileName))
headers.Add(currentUnit.FileName);
if (!mangledInlines.Contains(mangled.Mangled))
mangledInlines.Add(mangled.Mangled);
}
}
private static bool AccessValid(Declaration declaration)
{
if (declaration.Access == AccessSpecifier.Private)
{
var method = declaration as Method;
return method != null && method.IsOverride;
}
return true;
}
} }
} }

Loading…
Cancel
Save