public override SyntaxNode VisitParameter(ParameterSyntax node) { string fullName = SyntaxUtils.GetFullName(node); if (this.GetRemapInfo(fullName, out List <AttributeSyntax> listAttributes, node.Type.ToString(), out string newType, out string newName)) { node = (ParameterSyntax)base.VisitParameter(node); if (listAttributes != null) { foreach (var attrNode in listAttributes) { var attrListNode = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList <AttributeSyntax>(attrNode)); node = node.WithAttributeLists(node.AttributeLists.Add(attrListNode)); } } if (newName != null) { node = node.WithIdentifier(SyntaxFactory.Identifier(newName)); } if (newType != null) { node = node.WithType(SyntaxFactory.ParseTypeName(newType).WithTrailingTrivia(SyntaxFactory.Space)); // Get rid of the NativeTypeName attribute so the type we just changed to doesn't get overridden var attr = SyntaxUtils.GetAttribute(node.AttributeLists, "NativeTypeName"); if (attr != null) { node = node.RemoveNode(attr, SyntaxRemoveOptions.KeepLeadingTrivia); } } }
private void AddNode(Architecture arch, SyntaxNode node) { string name = SyntaxUtils.GetFullName(node, true); string fullSignature = GetFullSignature(node); if (!this.namesToInfos.TryGetValue(name, out var crossArchInfos)) { crossArchInfos = new List <CrossArchInfo>(); this.namesToInfos[name] = crossArchInfos; } foreach (var info in crossArchInfos) { if (info.FullSignature == fullSignature) { info.Arch |= arch; return; } } var newInfo = new CrossArchInfo() { Arch = arch, FullSignature = fullSignature }; crossArchInfos.Add(newInfo); }
private void AddNode(Architecture arch, SyntaxNode node) { string name = SyntaxUtils.GetFullName(node, true); string fullSignature = GetFullSignature(node); string altSignature = string.Empty; if (arch == Architecture.X86 && node is StructDeclarationSyntax structNode) { var packing4AttrList = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList <AttributeSyntax>( SyntaxFactory.Attribute( SyntaxFactory.ParseName("StructLayout"), SyntaxFactory.ParseAttributeArgumentList("(LayoutKind.Sequential, Pack = 4)")))); var tempNode = structNode.AddAttributeLists(packing4AttrList); altSignature = GetFullSignature(tempNode); } lock (this.namesToInfos) { if (!this.namesToInfos.TryGetValue(name, out var crossArchInfos)) { crossArchInfos = new List <CrossArchInfo>(); this.namesToInfos[name] = crossArchInfos; } foreach (var info in crossArchInfos) { if (info.FullSignature == fullSignature || info.FullSignature == altSignature) { info.Arch |= arch; return; } } var newInfo = new CrossArchInfo() { Arch = arch, FullSignature = fullSignature }; crossArchInfos.Add(newInfo); } }
public override SyntaxNode VisitDelegateDeclaration(DelegateDeclarationSyntax node) { string fullName = SyntaxUtils.GetFullName(node); // Remove duplicate delegates in this tree if (this.visitedDelegateNames.Contains(fullName)) { return(null); } this.visitedDelegateNames.Add(fullName); string returnFullName = $"{fullName}::return"; if (this.GetRemapInfo(returnFullName, out List <AttributeSyntax> listAttributes, node.ReturnType.ToString(), out var newType, out _)) { node = (DelegateDeclarationSyntax)base.VisitDelegateDeclaration(node); if (listAttributes != null) { foreach (var attrNode in listAttributes) { var attrListNode = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList <AttributeSyntax>(attrNode)) .WithTarget( SyntaxFactory.AttributeTargetSpecifier( SyntaxFactory.Token(SyntaxKind.ReturnKeyword))); node = node.WithAttributeLists(node.AttributeLists.Add(attrListNode)); } if (newType != null) { node = node.WithReturnType(SyntaxFactory.ParseTypeName(newType).WithTrailingTrivia(SyntaxFactory.Space)); } } return(node); } return(base.VisitDelegateDeclaration(node)); }
public override SyntaxNode VisitParameter(ParameterSyntax node) { string fullName = SyntaxUtils.GetFullName(node); if (this.GetRemapInfo(fullName, out List <AttributeSyntax> listAttributes, node.Type.ToString(), out string newType, out string newName)) { node = (ParameterSyntax)base.VisitParameter(node); if (listAttributes != null) { foreach (var attrNode in listAttributes) { var attrListNode = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList <AttributeSyntax>(attrNode)); node = node.WithAttributeLists(node.AttributeLists.Add(attrListNode)); } } if (newName != null) { node = node.WithIdentifier(SyntaxFactory.Identifier(newName)); } if (newType != null) { node = node.WithType(SyntaxFactory.ParseTypeName(newType).WithTrailingTrivia(SyntaxFactory.Space)); } return(node); } var ret = (ParameterSyntax)base.VisitParameter(node); // Get rid of default parameter values if (ret.Default != null) { ret = ret.WithDefault(null); } return(ret); }
private string GetFullNameWithArch(SyntaxNode node, Architecture arch) { return(GetUniqueNameWithArches(SyntaxUtils.GetFullName(node, true), arch)); }
public IEnumerable <Architecture> GetSignatureArchGroupings(SyntaxNode node) { string name = SyntaxUtils.GetFullName(node, true); return(this.GetSignatureArchGroupings(name)); }
public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node) { string fullName = SyntaxUtils.GetFullName(node); this.GetRemapInfo(fullName, out var listAttributes, node.Declaration.Type.ToString(), out string newType, out string newName); // ClangSharp mistakenly emits string[] for WCHAR[] Foo = "Bar". // Change it to string if (newType == null && node.Declaration.Type.ToString() == "string[]") { newType = "string"; } // Turn public static readonly Guids into string constants with an attribute // to signal language projections to turn them into Guid constants. Guid constants // aren't allowed in metadata, requiring us to surface them this way if (node.Modifiers.ToString() == "public static readonly" && node.Declaration.Type.ToString() == "Guid") { Guid guidVal = Guid.Empty; var varInitializer = node.Declaration.Variables.First().Initializer; if (varInitializer.Value is ObjectCreationExpressionSyntax objCreationSyntax) { var args = objCreationSyntax.ArgumentList.Arguments; if (args.Count == 11) { uint p0 = EncodeHelpers.ParseHex(args[0].ToString()); ushort p1 = (ushort)EncodeHelpers.ParseHex(args[1].ToString()); ushort p2 = (ushort)EncodeHelpers.ParseHex(args[2].ToString()); byte p3 = (byte)EncodeHelpers.ParseHex(args[3].ToString()); byte p4 = (byte)EncodeHelpers.ParseHex(args[4].ToString()); byte p5 = (byte)EncodeHelpers.ParseHex(args[5].ToString()); byte p6 = (byte)EncodeHelpers.ParseHex(args[6].ToString()); byte p7 = (byte)EncodeHelpers.ParseHex(args[7].ToString()); byte p8 = (byte)EncodeHelpers.ParseHex(args[8].ToString()); byte p9 = (byte)EncodeHelpers.ParseHex(args[9].ToString()); byte p10 = (byte)EncodeHelpers.ParseHex(args[10].ToString()); guidVal = new Guid(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } else if (objCreationSyntax.ArgumentList.Arguments.Count == 1) { // If this is an invalid format, remove the node if (!Guid.TryParse(objCreationSyntax.ArgumentList.Arguments[0].ToString(), out guidVal)) { return(null); } } } if (guidVal == Guid.Empty) { return(node); } node = node.RemoveNode(varInitializer, SyntaxRemoveOptions.KeepExteriorTrivia | SyntaxRemoveOptions.KeepEndOfLine); node = node.AddAttributeLists(EncodeHelpers.ConvertGuidToAttributeList(guidVal).WithLeadingTrivia(node.GetLeadingTrivia())); return(node); } node = (FieldDeclarationSyntax)base.VisitFieldDeclaration(node); if (listAttributes != null) { foreach (var attrNode in listAttributes) { var attrListNode = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList <AttributeSyntax>(attrNode)); node = node.WithAttributeLists(node.AttributeLists.Add(attrListNode)); } } var firstVar = node.Declaration.Variables.First(); if (newName != null) { var newVar = SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(newName)); node = node.ReplaceNode(firstVar, newVar); } if (newType != null) { node = node.WithDeclaration(node.Declaration.WithType(SyntaxFactory.ParseTypeName(newType).WithTrailingTrivia(SyntaxFactory.Space))); } return(node); }
public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) { // Skip methods where we weren't given a import lib name. Should we warn the caller? if (node.AttributeLists.ToString().Contains("[DllImport(\"\"")) { return(null); } string fullName = SyntaxUtils.GetFullName(node); // Remove duplicate static methods if (node.Body == null) { // If this function is supposed to be in a certain namespace, remove it if it's not. // We only respect this for static methods if (this.requiredNamespaces.TryGetValue(fullName, out var requiredNamespace)) { var ns = GetEnclosingNamespace(node); if (ns != requiredNamespace) { return(null); } } // Remove duplicate methods in this tree if (this.visitedStaticMethodNames.Contains(fullName)) { return(null); } this.visitedStaticMethodNames.Add(fullName); } // Any method with a body has to be part of a call to a vtable for an interface. // If it's not, get rid of it else if (!node.Body.ToString().Contains("GetDelegateForFunctionPointer")) { return(null); } string returnFullName = $"{fullName}::return"; // Find remap info for the return parameter for this method and apply any that we find if (this.GetRemapInfo(returnFullName, out List <AttributeSyntax> listAttributes, node.ReturnType.ToString(), out var newType, out _)) { node = (MethodDeclarationSyntax)base.VisitMethodDeclaration(node); if (listAttributes != null) { foreach (var attrNode in listAttributes) { var attrListNode = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList <AttributeSyntax>(attrNode)) .WithTarget( SyntaxFactory.AttributeTargetSpecifier( SyntaxFactory.Token(SyntaxKind.ReturnKeyword))); node = node.WithAttributeLists(node.AttributeLists.Add(attrListNode)); } } if (newType != null) { node = node.WithReturnType(SyntaxFactory.ParseTypeName(newType).WithTrailingTrivia(SyntaxFactory.Space)); } return(node); } return(base.VisitMethodDeclaration(node)); }