mirror of https://github.com/mono/CppSharp.git
c-sharpdotnetmonobindingsbridgecclangcpluspluscppsharpglueinteropparserparsingpinvokeswigsyntax-treevisitorsxamarinxamarin-bindings
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.
302 lines
8.6 KiB
302 lines
8.6 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using CppSharp.AST.Extensions; |
|
|
|
namespace CppSharp.AST |
|
{ |
|
// A C++ access specifier. |
|
public enum AccessSpecifier |
|
{ |
|
Private, |
|
Protected, |
|
Public, |
|
Internal |
|
} |
|
|
|
public enum TagKind |
|
{ |
|
Struct, |
|
Interface, |
|
Union, |
|
Class, |
|
Enum |
|
} |
|
|
|
// A C++ access specifier declaration. |
|
public class AccessSpecifierDecl : Declaration |
|
{ |
|
public override T Visit<T>(IDeclVisitor<T> visitor) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
} |
|
|
|
// Represents a base class of a C++ class. |
|
public class BaseClassSpecifier : DeclarationBase |
|
{ |
|
public BaseClassSpecifier() |
|
{ |
|
} |
|
|
|
public BaseClassSpecifier(BaseClassSpecifier other) |
|
{ |
|
Access = other.Access; |
|
IsVirtual = other.IsVirtual; |
|
Type = other.Type; |
|
Offset = other.Offset; |
|
} |
|
|
|
public AccessSpecifier Access { get; set; } |
|
public bool IsVirtual { get; set; } |
|
public Type Type { get; set; } |
|
public int Offset { get; set; } |
|
|
|
public Class Class |
|
{ |
|
get |
|
{ |
|
Type.TryGetClass(out var @class); |
|
return @class; |
|
} |
|
} |
|
|
|
public bool IsClass => Type.IsClass(); |
|
} |
|
|
|
public enum ClassType |
|
{ |
|
ValueType, |
|
RefType, |
|
Interface |
|
} |
|
|
|
// Represents a C++ record decl. |
|
public class Class : DeclarationContext |
|
{ |
|
public List<BaseClassSpecifier> Bases; |
|
public List<Field> Fields; |
|
public List<Property> Properties; |
|
public List<Method> Methods; |
|
public List<AccessSpecifierDecl> Specifiers; |
|
|
|
// True if the record is a POD (Plain Old Data) type. |
|
public bool IsPOD; |
|
|
|
// Semantic type of the class. |
|
public ClassType Type; |
|
|
|
// ABI-specific class layout. |
|
public ClassLayout Layout; |
|
|
|
// True if class provides pure virtual methods. |
|
public bool IsAbstract; |
|
|
|
// True if the type is to be treated as a union. |
|
public bool IsUnion; |
|
|
|
public TagKind TagKind { get; set; } |
|
|
|
// True if the class is final / sealed. |
|
public bool IsFinal { get; set; } |
|
|
|
private bool? isOpaque; |
|
|
|
public bool IsInjected { get; set; } |
|
|
|
// True if the type is to be treated as opaque. |
|
public bool IsOpaque |
|
{ |
|
get => isOpaque ?? (IsIncomplete && CompleteDeclaration == null); |
|
set => isOpaque = value; |
|
} |
|
|
|
// True if the class is dynamic. |
|
public bool IsDynamic; |
|
|
|
// True if the class is polymorphic. |
|
public bool IsPolymorphic; |
|
|
|
// True if the class has a non trivial default constructor. |
|
public bool HasNonTrivialDefaultConstructor; |
|
|
|
// True if the class has a non trivial copy constructor. |
|
public bool HasNonTrivialCopyConstructor; |
|
|
|
// True if the class has a non trivial destructor. |
|
public bool HasNonTrivialDestructor; |
|
|
|
// True if the class represents a static class. |
|
public bool IsStatic; |
|
|
|
public Class() |
|
{ |
|
Bases = new List<BaseClassSpecifier>(); |
|
Fields = new List<Field>(); |
|
Properties = new List<Property>(); |
|
Methods = new List<Method>(); |
|
Specifiers = new List<AccessSpecifierDecl>(); |
|
IsAbstract = false; |
|
IsUnion = false; |
|
IsFinal = false; |
|
IsPOD = false; |
|
Type = ClassType.RefType; |
|
Layout = new ClassLayout(); |
|
templateParameters = new List<Declaration>(); |
|
specializations = new List<ClassTemplateSpecialization>(); |
|
} |
|
|
|
public bool HasBase => Bases.Count > 0; |
|
|
|
public bool HasBaseClass => BaseClass != null; |
|
|
|
public Class BaseClass |
|
{ |
|
get |
|
{ |
|
foreach (var @base in Bases) |
|
{ |
|
if (@base.IsClass && @base.Class.IsGenerated) |
|
return @base.Class; |
|
} |
|
|
|
return null; |
|
} |
|
} |
|
|
|
public bool HasNonIgnoredBase => |
|
HasBaseClass && !IsValueType |
|
&& BaseClass != null |
|
&& !BaseClass.IsValueType |
|
&& BaseClass.IsGenerated; |
|
|
|
public bool NeedsBase => HasNonIgnoredBase && IsGenerated; |
|
|
|
// When we have an interface, this is the class mapped to that interface. |
|
public Class OriginalClass { get; set; } |
|
|
|
public bool IsValueType => Type == ClassType.ValueType || IsUnion; |
|
|
|
public bool IsRefType => Type == ClassType.RefType && !IsUnion; |
|
|
|
public bool IsInterface => Type == ClassType.Interface; |
|
|
|
public bool HasUnionFields { get; set; } |
|
|
|
public bool IsAbstractImpl |
|
{ |
|
get { return Methods.Any(m => m.SynthKind == FunctionSynthKind.AbstractImplCall); } |
|
} |
|
|
|
public IEnumerable<Method> Constructors |
|
{ |
|
get |
|
{ |
|
return Methods.Where( |
|
method => method.IsConstructor || method.IsCopyConstructor); |
|
} |
|
} |
|
|
|
public IEnumerable<Method> Destructors |
|
{ |
|
get |
|
{ |
|
return Methods.Where(method => method.IsDestructor); |
|
} |
|
} |
|
|
|
public IEnumerable<Method> Operators |
|
{ |
|
get |
|
{ |
|
return Methods.Where(method => method.IsOperator); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// If this class is a template, this list contains all of its template parameters. |
|
/// <para> |
|
/// <see cref="ClassTemplate"/> cannot be relied upon to contain all of them because |
|
/// ClassTemplateDecl in Clang is not a complete declaration, it only serves to forward template classes. |
|
/// </para> |
|
/// </summary> |
|
public List<Declaration> TemplateParameters |
|
{ |
|
get |
|
{ |
|
if (!IsDependent) |
|
throw new InvalidOperationException( |
|
"Only dependent classes have template parameters."); |
|
return templateParameters; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// If this class is a template, this list contains all of its specializations. |
|
/// <see cref="ClassTemplate"/> cannot be relied upon to contain all of them because |
|
/// ClassTemplateDecl in Clang is not a complete declaration, it only serves to forward template classes. |
|
/// </summary> |
|
public List<ClassTemplateSpecialization> Specializations |
|
{ |
|
get |
|
{ |
|
if (!IsDependent) |
|
throw new InvalidOperationException( |
|
"Only dependent classes have specializations."); |
|
return specializations; |
|
} |
|
} |
|
|
|
public bool IsTemplate => IsDependent && TemplateParameters.Count > 0; |
|
|
|
public override IEnumerable<Function> FindOperator(CXXOperatorKind kind) |
|
{ |
|
return Methods.Where(m => m.OperatorKind == kind); |
|
} |
|
|
|
public override IEnumerable<Function> GetOverloads(Function function) |
|
{ |
|
if (function.IsOperator) |
|
return Methods.Where(fn => fn.OperatorKind == function.OperatorKind); |
|
|
|
var overloads = Methods.Where(m => m.Name == function.Name) |
|
.Union(Declarations.Where(d => d is Function && d.Name == function.Name)) |
|
.Cast<Function>(); |
|
|
|
overloads = overloads.Union(base.GetOverloads(function)); |
|
|
|
return overloads; |
|
} |
|
|
|
public Method FindMethod(string name) |
|
{ |
|
return Methods |
|
.Concat(Templates.OfType<FunctionTemplate>() |
|
.Select(t => t.TemplatedFunction) |
|
.OfType<Method>()) |
|
.FirstOrDefault(m => m.Name == name); |
|
} |
|
|
|
public Method FindMethodByUSR(string usr) |
|
{ |
|
return Methods |
|
.Concat(Templates.OfType<FunctionTemplate>() |
|
.Select(t => t.TemplatedFunction) |
|
.OfType<Method>()) |
|
.FirstOrDefault(m => m.USR == usr); |
|
} |
|
|
|
public Variable FindVariable(string name) |
|
{ |
|
return Variables.FirstOrDefault(m => m.Name == name); |
|
} |
|
|
|
public override T Visit<T>(IDeclVisitor<T> visitor) |
|
{ |
|
return visitor.VisitClassDecl(this); |
|
} |
|
|
|
private List<Declaration> templateParameters; |
|
private List<ClassTemplateSpecialization> specializations; |
|
} |
|
}
|
|
|