Tools and libraries to glue C/C++ APIs to high-level languages
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

94 lines
2.6 KiB

using System;
using System.Linq;
namespace Cxxi.Passes
{
public class CleanInvalidDeclNamesPass : TranslationUnitPass
{
private int uniqueName;
public CleanInvalidDeclNamesPass()
{
}
string CheckName(string name)
{
// Generate a new name if the decl still does not have a name
if (string.IsNullOrWhiteSpace(name))
return string.Format("_{0}", uniqueName++);
var firstChar = name.FirstOrDefault();
// Clean up the item name if the first digit is not a valid name.
if (char.IsNumber(firstChar))
return '_' + name;
return name;
}
public override bool VisitDeclaration(Declaration decl)
{
decl.Name = CheckName(decl.Name);
StringHelpers.CleanupText(ref decl.DebugText);
return base.VisitDeclaration(decl);
}
public override bool VisitTypedefDecl(TypedefDecl typedef)
{
var @class = typedef.Namespace.FindClass(typedef.Name);
// Clang will walk the typedef'd tag decl and the typedef decl,
// so we ignore the class and process just the typedef.
if (@class != null)
typedef.ExplicityIgnored = true;
if (typedef.Type == null)
typedef.ExplicityIgnored = true;
return base.VisitTypedefDecl(typedef);
}
private static void CheckEnumName(Enumeration @enum)
{
// If we still do not have a valid name, then try to guess one
// based on the enum value names.
if (!String.IsNullOrWhiteSpace(@enum.Name))
return;
var prefix = @enum.Items.Select(item => item.Name)
.ToArray().CommonPrefix();
// Try a simple heuristic to make sure we end up with a valid name.
if (prefix.Length < 3)
return;
prefix = prefix.Trim().Trim(new char[] { '_' });
@enum.Name = prefix;
}
public override bool VisitEnumDecl(Enumeration @enum)
{
CheckEnumName(@enum);
return base.VisitEnumDecl(@enum);
}
public override bool VisitEnumItem(Enumeration.Item item)
{
item.Name = CheckName(item.Name);
return base.VisitEnumItem(item);
}
}
public static class CleanInvalidDeclNamesExtensions
{
public static void CleanInvalidDeclNames(this PassBuilder builder)
{
var pass = new CleanInvalidDeclNamesPass();
builder.AddPass(pass);
}
}
}