From d474f0a04fd783a2a46a9a3435e7e16cbbed0b7d Mon Sep 17 00:00:00 2001 From: triton Date: Wed, 29 Aug 2012 21:44:23 +0100 Subject: [PATCH] Added a bridge project containing the managed files bridging the native Clang parser. --- src/Bridge/Bridge.csproj | 64 +++++++ src/Bridge/Class.cs | 90 ++++++++++ src/Bridge/Comment.cs | 14 ++ src/Bridge/Declaration.cs | 53 ++++++ src/Bridge/Enumeration.cs | 57 +++++++ src/Bridge/Field.cs | 24 +++ src/Bridge/Function.cs | 55 ++++++ src/Bridge/Library.cs | 102 +++++++++++ src/Bridge/Method.cs | 26 +++ src/Bridge/Namespace.cs | 86 ++++++++++ src/Bridge/Properties/AssemblyInfo.cs | 36 ++++ src/Bridge/Property.cs | 42 +++++ src/Bridge/Type.cs | 232 ++++++++++++++++++++++++++ 13 files changed, 881 insertions(+) create mode 100644 src/Bridge/Bridge.csproj create mode 100644 src/Bridge/Class.cs create mode 100644 src/Bridge/Comment.cs create mode 100644 src/Bridge/Declaration.cs create mode 100644 src/Bridge/Enumeration.cs create mode 100644 src/Bridge/Field.cs create mode 100644 src/Bridge/Function.cs create mode 100644 src/Bridge/Library.cs create mode 100644 src/Bridge/Method.cs create mode 100644 src/Bridge/Namespace.cs create mode 100644 src/Bridge/Properties/AssemblyInfo.cs create mode 100644 src/Bridge/Property.cs create mode 100644 src/Bridge/Type.cs diff --git a/src/Bridge/Bridge.csproj b/src/Bridge/Bridge.csproj new file mode 100644 index 00000000..bf0b6461 --- /dev/null +++ b/src/Bridge/Bridge.csproj @@ -0,0 +1,64 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {6BEB8FA2-97AA-40B7-AB92-42F6EDDC4490} + Library + Properties + Bridge + Bridge + v4.0 + 512 + + + true + full + false + ..\..\bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Bridge/Class.cs b/src/Bridge/Class.cs new file mode 100644 index 00000000..9b0d04ef --- /dev/null +++ b/src/Bridge/Class.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; + +namespace Cxxi +{ + // A C++ access specifier. + public enum AccessSpecifier + { + Private, + Protected, + Public + } + + // Represents a base class of a C++ class. + public class BaseClassSpecifier + { + BaseClassSpecifier(Class @class, AccessSpecifier access, + bool isVirtual = false) + { + Class = @class; + Access = access; + IsVirtual = isVirtual; + } + + public Class Class { get; set; } + public AccessSpecifier Access { get; set; } + public bool IsVirtual { get; set; } + } + + // Represents a C++ virtual function table. + public class VFTable + { + + } + + // Represents a C++ virtual base table. + public class VBTable + { + + } + + // Represents ABI-specific layout details for a class. + public class ClassLayout + { + public CppAbi ABI { get; set; } + public bool HasOwnVFTable { get; set; } + public VFTable VirtualFunctions { get; set; } + public VBTable VirtualBases { get; set; } + } + + // Represents a C++ record declaration. + public class Class : Declaration + { + + public Class() + { + Bases = new List(); + Fields = new List(); + Properties = new List(); + Methods = new List(); + NestedClasses = new List(); + NestedEnums = new List(); + IsAbstract = false; + } + + public List Bases; + public List NestedClasses; + public List NestedEnums; + public List Fields; + public List Properties; + public List Methods; + + public bool HasBase + { + get { return Bases.Count > 0; } + } + + // True if the record is a POD (Plain Old Data) type. + public bool IsPOD; + + // ABI-specific class layout. + public List Layouts { get; set; } + + // True if class only provides pure virtual methods. + public bool IsAbstract { get; set; } + + public string TemplateName { get; set; } + public string TemplateClassName { get; set; } + } +} \ No newline at end of file diff --git a/src/Bridge/Comment.cs b/src/Bridge/Comment.cs new file mode 100644 index 00000000..f5279deb --- /dev/null +++ b/src/Bridge/Comment.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cxxi +{ + /// + /// Represents a C++ comment. + /// + public class Comment + { + + } +} diff --git a/src/Bridge/Declaration.cs b/src/Bridge/Declaration.cs new file mode 100644 index 00000000..0cd577af --- /dev/null +++ b/src/Bridge/Declaration.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace Cxxi +{ + /// + /// Represents a C++ declaration. + /// + public class Declaration + { + public Declaration() + { + } + + public Declaration(string name) + { + Name = name; + } + + public override string ToString() + { + return Name; + } + + // Name of the type. + public string Name; + + // Doxygen-style brief comment. + public string BriefComment; + + // Namespace the type is declared in. + public Namespace Namespace; + + // Wether the type should be ignored. + public bool Ignore; + + // Contains a debug text of the type declaration. + public string DebugText; + } + + /// + /// Represents a C preprocessor macro definition. + /// + public class MacroDefine : Declaration + { + public MacroDefine() + { + } + + // Contains the macro definition text. + public string Expression; + } +} \ No newline at end of file diff --git a/src/Bridge/Enumeration.cs b/src/Bridge/Enumeration.cs new file mode 100644 index 00000000..596cf0b7 --- /dev/null +++ b/src/Bridge/Enumeration.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; + +namespace Cxxi +{ + /// + /// Represents a C/C++ enumeration. + /// + public class Enumeration : Declaration + { + [Flags] + public enum EnumModifiers + { + Anonymous, + Scoped, + Flags + } + + /// + /// Represents a C/C++ enumeration item. + /// + public class Item + { + public string Name; + public long Value; + public string Expression; + public string Comment; + public bool ExplicitValue = true; + } + + public Enumeration() + { + Items = new List(); + ItemsByName = new Dictionary(); + Type = new BuiltinType(PrimitiveType.Int32); + } + + public Enumeration AddItem(Item item) + { + Items.Add(item); + ItemsByName[item.Name] = item; + return this; + } + + public Enumeration SetFlags() + { + Modifiers |= EnumModifiers.Flags; + return this; + } + + public BuiltinType Type { get; set; } + public EnumModifiers Modifiers { get; set; } + + public List Items; + public Dictionary ItemsByName; + } +} \ No newline at end of file diff --git a/src/Bridge/Field.cs b/src/Bridge/Field.cs new file mode 100644 index 00000000..2f30ae07 --- /dev/null +++ b/src/Bridge/Field.cs @@ -0,0 +1,24 @@ +using System; + +namespace Cxxi +{ + /// + /// Represents a field in a C/C++ record declaration. + /// + public class Field : Declaration + { + public Field() + { + } + + public Field(string name, Type type, AccessSpecifier access) + { + Name = name; + Type = type; + Access = access; + } + + public Type Type { get; set; } + public AccessSpecifier Access { get; set; } + } +} \ No newline at end of file diff --git a/src/Bridge/Function.cs b/src/Bridge/Function.cs new file mode 100644 index 00000000..3c02ff30 --- /dev/null +++ b/src/Bridge/Function.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; + +namespace Cxxi +{ + public enum CallingConvention + { + Default, + C, + StdCall, + ThisCall, + FastCall + } + + public enum ParameterUsage + { + Unknown, + In, + Out, + InOut + } + + public class Parameter : Declaration + { + public Parameter() + { + Usage = ParameterUsage.Unknown; + HasDefaultValue = false; + } + + public Type Type { get; set; } + public ParameterUsage Usage { get; set; } + public bool HasDefaultValue { get; set; } + } + + public class Function : Declaration + { + public Function() + { + Parameters = new List(); + CallingConvention = CallingConvention.Default; + IsVariadic = false; + IsInline = false; + } + + public Type ReturnType { get; set; } + public List Parameters { get; set; } + public CallingConvention CallingConvention { get; set; } + public bool IsVariadic { get; set; } + public bool IsInline { get; set; } + + // The C# name + public string FormattedName { get; set; } + } +} \ No newline at end of file diff --git a/src/Bridge/Library.cs b/src/Bridge/Library.cs new file mode 100644 index 00000000..d2ce1114 --- /dev/null +++ b/src/Bridge/Library.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; + +namespace Cxxi +{ + public enum CppAbi + { + Itanium, + Microsoft, + ARM + } + + public enum InlineMethods + { + Present, + Unavailable + } + + [DebuggerDisplay("File = {FileName}, Ignored = {Ignore}")] + public class Module + { + public Module(string File) + { + Global = new Namespace(); + Macros = new List(); + Namespaces = new List(); + FilePath = File; + Ignore = false; + } + + public bool Ignore; + public string FilePath; + + public string FileName + { + get { return Path.GetFileName(FilePath); } + } + + public List Macros; + + public Namespace Global; + public List Namespaces; + + public bool HasDeclarations + { + get + { + return Global.HasDeclarations + || Namespaces.Exists(n => n.HasDeclarations); + } + } + } + + public class Library + { + public Library(string name) + { + Name = name; + Modules = new List(); + } + + public Module FindOrCreateModule(string File) + { + var module = Modules.Find(m => m.FilePath.Equals(File)); + + if (module == null) + { + module = new Module(File); + Modules.Add(module); + } + + return module; + } + + public Enumeration FindEnum(string Name) + { + foreach (var module in Modules) + { + var type = module.Global.FindEnum(Name); + if (type != null) return type; + } + + return null; + } + + public Class FindClass(string Name) + { + foreach (var module in Modules) + { + var type = module.Global.FindClass(Name); + if (type != null) return type; + } + + return null; + } + + public string Name { get; set; } + public List Modules { get; set; } + } +} \ No newline at end of file diff --git a/src/Bridge/Method.cs b/src/Bridge/Method.cs new file mode 100644 index 00000000..a1203ccb --- /dev/null +++ b/src/Bridge/Method.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; + +namespace Cxxi +{ + /// + /// Represents a C++ method. + /// + public class Method : Function + { + + public Method() + { + } + + public AccessSpecifier Access { get; set; } + + public bool IsVirtual { get; set; } + public bool IsStatic { get; set; } + public bool IsConst { get; set; } + public bool IsArtificial { get; set; } + public bool IsConstructor { get; set; } + public bool IsDestructor { get; set; } + public bool IsCopyCtor { get; set; } + } +} \ No newline at end of file diff --git a/src/Bridge/Namespace.cs b/src/Bridge/Namespace.cs new file mode 100644 index 00000000..4324b79c --- /dev/null +++ b/src/Bridge/Namespace.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; + +namespace Cxxi +{ + /// + /// Represents a C++ namespace. + /// + public class Namespace + { + public Namespace() + : this(null, String.Empty) + { + } + + public Namespace(Namespace parent, string name, bool isAnonymous = false) + { + Name = name; + Parent = parent; + IsAnonymous = isAnonymous; + + Enums = new List(); + Functions = new List(); + Classes = new List(); + } + + public Enumeration FindEnum(string Name) + { + return FindEnumWithName(Name); + } + + public Function FindFunction(string Name) + { + return Functions.Find(e => e.Name.Equals(Name)); + } + + public Class FindClass(string Name) + { + return Classes.Find(e => e.Name.Equals(Name)); + } + + public T FindType(string Name) where T : Declaration + { + var type = FindEnumWithName(Name) + ?? FindFunction(Name) ?? (Declaration)FindClass(Name); + + return type as T; + } + + public Enumeration FindEnumWithName(string Name) + { + return Enums.Find(e => e.Name.Equals(Name)); + } + + public Enumeration FindEnumWithItem(string Name) + { + return Enums.Find(e => e.ItemsByName.ContainsKey(Name)); + } + + public bool HasDeclarations + { + get + { + Predicate pred = (t => !t.Ignore); + return Enums.Exists(pred) || HasFunctions || Classes.Exists(pred); + } + } + + public bool HasFunctions + { + get + { + Predicate pred = (t => !t.Ignore); + return Functions.Exists(pred); + } + } + + public string Name { get; set; } + public Namespace Parent { get; set; } + public bool IsAnonymous { get; set; } + + public List Enums; + public List Functions; + public List Classes; + } +} \ No newline at end of file diff --git a/src/Bridge/Properties/AssemblyInfo.cs b/src/Bridge/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..35ce8430 --- /dev/null +++ b/src/Bridge/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Bridge")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Bridge")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5b0589ff-83fd-4b9b-bcff-14fde1263358")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Bridge/Property.cs b/src/Bridge/Property.cs new file mode 100644 index 00000000..d5a8096b --- /dev/null +++ b/src/Bridge/Property.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; + +namespace Cxxi +{ + /// + /// Represents a C++ property. + /// + public class Property + { + + public Property(string name, Declaration type) + { + Name = name; + Type = type; + } + + public string Name + { + get; + set; + } + + public Declaration Type + { + get; + set; + } + + public Method GetMethod + { + get; + set; + } + + public Method SetMethod + { + get; + set; + } + } +} \ No newline at end of file diff --git a/src/Bridge/Type.cs b/src/Bridge/Type.cs new file mode 100644 index 00000000..a1109843 --- /dev/null +++ b/src/Bridge/Type.cs @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cxxi +{ + /// + /// Represents a C++ type reference. + /// + public abstract class Type + { + public Type() + { + } + + public override string ToString() + { + return ToCSharp(); + } + + // Converts the type to a C# type. + public abstract string ToCSharp(); + } + + /// + /// Represents a C++ tag type reference. + /// + public class TagType : Type + { + public TagType() + { + } + + public Declaration Declaration; + + public override string ToCSharp() + { + if (Declaration == null) + return string.Empty; + return Declaration.Name; + } + } + + /// + /// Represents an C/C++ array type. + /// + public class ArrayType : Type + { + public enum ArraySize + { + Constant, + Variable + } + + public ArrayType() + { + } + + // Type of the array elements. + public Type Type; + + // Size type of array. + public ArraySize SizeType; + + // In case of a constant size array. + public long Size; + + public override string ToCSharp() + { + return string.Format("{0}[{1}]", Type, Size); + } + } + + /// + /// Represents an C/C++ function type. + /// + public class FunctionType : Type + { + // Return type of the function. + public Type ReturnType; + + public override string ToCSharp() + { + return string.Format("Func<{0}>", ReturnType); + } + } + + /// + /// Represents a C++ pointer/reference type. + /// + public class PointerType : Type + { + public PointerType() + { + + } + + /// + /// Represents the modifiers on a C++ type reference. + /// + public enum TypeModifier + { + Value, + Pointer, + // L-value references + LVReference, + // R-value references + RVReference + } + + static string ConvertModifierToString(TypeModifier modifier) + { + switch (modifier) + { + case TypeModifier.Value: return string.Empty; + case TypeModifier.Pointer: + case TypeModifier.LVReference: + case TypeModifier.RVReference: return "*"; + } + + return string.Empty; + } + + public Type Pointee; + + public TypeModifier Modifier; + + public override string ToCSharp() + { + if (Pointee is FunctionType) + return Pointee.ToCSharp(); + + return string.Format("{0}{1}", + Pointee, ConvertModifierToString(Modifier)); + } + } + + #region Primitives + + /// + /// Represents the C++ built-in types. + /// + public enum PrimitiveType + { + Null, + Void, + Bool, + WideChar, + Int8, + UInt8, + Int16, + UInt16, + Int32, + UInt32, + Int64, + UInt64, + Float, + Double + } + + /// + /// Represents an instance of a C++ built-in type. + /// + public class BuiltinType : Type + { + public BuiltinType() + { + } + + public BuiltinType(PrimitiveType type) + { + Type = type; + } + + // Primitive type of built-in type. + public PrimitiveType Type; + + public override string ToCSharp() + { + return Type.ConvertToTypeName(); + } + } + + public static class PrimitiveTypeExtensions + { + public static System.Type ConvertToType(this PrimitiveType Primitive) + { + switch (Primitive) + { + case PrimitiveType.Bool: return typeof(bool); + case PrimitiveType.Void: return typeof(void); + case PrimitiveType.WideChar: return typeof(char); + case PrimitiveType.Int8: return typeof(sbyte); + case PrimitiveType.UInt8: return typeof(byte); + case PrimitiveType.Int16: return typeof(short); + case PrimitiveType.UInt16: return typeof(ushort); + case PrimitiveType.Int32: return typeof(int); + case PrimitiveType.UInt32: return typeof(uint); + case PrimitiveType.Int64: return typeof(long); + case PrimitiveType.UInt64: return typeof(ulong); + case PrimitiveType.Float: return typeof(float); + case PrimitiveType.Double: return typeof(double); + } + + return typeof(int); + } + + public static string ConvertToTypeName(this PrimitiveType Primitive) + { + switch (Primitive) + { + case PrimitiveType.Bool: return "bool"; + case PrimitiveType.Void: return "void"; + case PrimitiveType.WideChar: return "char"; + case PrimitiveType.Int8: return "sbyte"; + case PrimitiveType.UInt8: return "byte"; + case PrimitiveType.Int16: return "short"; + case PrimitiveType.UInt16: return "ushort"; + case PrimitiveType.Int32: return "int"; + case PrimitiveType.UInt32: return "uint"; + case PrimitiveType.Int64: return "long"; + case PrimitiveType.UInt64: return "ulong"; + case PrimitiveType.Float: return "float"; + case PrimitiveType.Double: return "double"; + } + + return String.Empty; + } + } + + #endregion +} \ No newline at end of file