Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/CppAst.Tests/TestFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,32 @@ public void TestFunctionVariadic()
);
}



[Test]
public void TestFunctionTemplate()
{
ParseAssert(@"
template<class T>
void function0(T t);
",
compilation =>
{
Assert.False(compilation.HasErrors);

Assert.AreEqual(1, compilation.Functions.Count);

{
var cppFunction = compilation.Functions[0];
Assert.AreEqual(1, cppFunction.Parameters.Count);
Assert.AreEqual("void", cppFunction.ReturnType.ToString());
Assert.AreEqual(cppFunction.IsFunctionTemplate, true);
Assert.AreEqual(cppFunction.TemplateParameters.Count, 1);
}

}
);
}

}
}
43 changes: 43 additions & 0 deletions src/CppAst.Tests/TestNamespaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,48 @@ struct MyStruct;
}
);
}

[Test]
public void TestInlineNamespace()
{
var text = @"
namespace A
{

inline namespace __1
{
// Test using Template
template <typename T>
struct MyStruct;

using MyStructInt = MyStruct<int>;
}

}

";

ParseAssert(text,
compilation =>
{
Assert.False(compilation.HasErrors);

Assert.AreEqual(1, compilation.Namespaces.Count);

var inlineNs = compilation.Namespaces[0].Namespaces[0];
Assert.AreEqual(inlineNs.Name, "__1");
Assert.AreEqual(true, inlineNs.IsInlineNamespace);

var cppStruct = compilation.FindByFullName<CppClass>("A::MyStruct");
Assert.AreEqual(inlineNs.Classes[0], cppStruct);
Assert.AreEqual(cppStruct.FullName, "A::MyStruct<T>");

var cppTypedef = compilation.FindByFullName<CppTypedef>("A::MyStructInt");
var cppStructInt = cppTypedef.ElementType as CppClass;
//So now we can use this full name in exporter convenience.
Assert.AreEqual(cppStructInt.FullName, "A::MyStruct<int>");
}
);
}
}
}
25 changes: 25 additions & 0 deletions src/CppAst/CppBaseType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@ public override string ToString()
}

builder.Append(Type.GetDisplayName());

var cls = Type as CppClass;
if(cls != null && cls.TemplateKind != CppTemplateKind.NormalClass)
{
builder.Append("<");

if (cls.TemplateKind == CppTemplateKind.TemplateSpecializedClass)
{
for (var i = 0; i < cls.TemplateSpecializedArguments.Count; i++)
{
if (i > 0) builder.Append(", ");
builder.Append(cls.TemplateSpecializedArguments[i].ToString());
}
}
else if (cls.TemplateKind == CppTemplateKind.TemplateClass)
{
for (var i = 0; i < cls.TemplateParameters.Count; i++)
{
if (i > 0) builder.Append(", ");
builder.Append(cls.TemplateParameters[i].ToString());
}
}

builder.Append(">");
}
return builder.ToString();
}
}
Expand Down
51 changes: 44 additions & 7 deletions src/CppAst/CppClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,57 @@ public CppClass(string name) : base(CppTypeKind.StructOrClass)
/// <inheritdoc />
public string Name { get; set; }

public string FullName
{
get
public override string FullName
{
get
{
StringBuilder sb = new StringBuilder();
string fullparent = FullParentName;
if(string.IsNullOrEmpty(fullparent))
if (string.IsNullOrEmpty(fullparent))
{
return Name;
sb.Append(Name);
}
else
{
return $"{fullparent}{Name}";
sb.Append($"{fullparent}::{Name}");
}

if (TemplateKind == CppTemplateKind.TemplateClass
|| TemplateKind == CppTemplateKind.PartialTemplateClass)
{
sb.Append('<');
for (int i = 0; i < TemplateParameters.Count; i++)
{
var tp = TemplateParameters[i];
if (i != 0)
{
sb.Append(", ");
}
sb.Append(tp.ToString());
}
sb.Append('>');
}
}
else if (TemplateKind == CppTemplateKind.TemplateSpecializedClass)
{
sb.Append('<');
for (int i = 0; i < TemplateSpecializedArguments.Count; i++)
{
var ta = TemplateSpecializedArguments[i];
if (i != 0)
{
sb.Append(", ");
}
sb.Append(ta.ArgString);
}
sb.Append('>');
}
//else if(TemplateKind == CppTemplateKind.PartialTemplateClass)
//{
// sb.Append('<');
// sb.Append('>');
//}
return sb.ToString();
}
}

/// <inheritdoc />
Expand Down
67 changes: 39 additions & 28 deletions src/CppAst/CppElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,46 @@ public string FullParentName
{
get
{
string tmpname = "";
var p = Parent;
while (p != null)
{
if (p is CppClass)
{
var cpp = p as CppClass;
tmpname = $"{cpp.Name}::{tmpname}";
p = cpp.Parent;
}
else if (p is CppNamespace)
{
var ns = p as CppNamespace;
tmpname = $"{ns.Name}::{tmpname}";
p = ns.Parent;
}
else if (p is CppCompilation)
{
// root namespace here, just ignore~
p = null;
}
else
{
throw new NotImplementedException("Can not be here, not support type here!");
}
}
string tmpname = "";
var p = Parent;
while (p != null)
{
if (p is CppClass)
{
var cpp = p as CppClass;
tmpname = $"{cpp.Name}::{tmpname}";
p = cpp.Parent;
}
else if (p is CppNamespace)
{
var ns = p as CppNamespace;

return tmpname;
}
//Just ignore inline namespace
if (!ns.IsInlineNamespace)
{
tmpname = $"{ns.Name}::{tmpname}";
}
p = ns.Parent;
}
else if (p is CppCompilation)
{
// root namespace here, just ignore~
p = null;
}
else
{
throw new NotImplementedException("Can not be here, not support type here!");
}
}

//Try to remove not need `::` in string tails.
if (tmpname.EndsWith("::"))
{
tmpname = tmpname.Substring(0, tmpname.Length - 2);
}

return tmpname;
}
}

/// <summary>
Expand Down
31 changes: 15 additions & 16 deletions src/CppAst/CppEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,21 @@ public CppEnum(string name) : base(CppTypeKind.Enum)
/// <inheritdoc />
public string Name { get; set; }

public string FullName
{
get
{
string fullparent = FullParentName;
if (string.IsNullOrEmpty(fullparent))
{
return Name;
}
else
{
return $"{fullparent}{Name}";
}
}
}

public override string FullName
{
get
{
string fullparent = FullParentName;
if (string.IsNullOrEmpty(fullparent))
{
return Name;
}
else
{
return $"{fullparent}::{Name}";
}
}
}

/// <summary>
/// Gets or sets a boolean indicating if this enum is scoped.
Expand Down
1 change: 1 addition & 0 deletions src/CppAst/CppFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public int DefaultParamCount

public bool IsConst => ((int)Flags & (int)CppFunctionFlags.Const) != 0;

public bool IsFunctionTemplate => ((int)Flags & (int)CppFunctionFlags.FunctionTemplate) != 0;

/// <inheritdoc />
public List<CppType> TemplateParameters { get; }
Expand Down
5 changes: 5 additions & 0 deletions src/CppAst/CppFunctionFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,10 @@ public enum CppFunctionFlags
/// This is a variadic function (has `...` parameter)
/// </summary>
Variadic = 1 << 8,

/// <summary>
/// This is a function template (has template params in function)
/// </summary>
FunctionTemplate = 1 << 9,
}
}
17 changes: 16 additions & 1 deletion src/CppAst/CppGlobalDeclarationContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ private CppElement SearchForChild(CppElement parent, string child_name)
if (t != null) return t;
}

//Not found, try to find in inline namespace.
if(parent is CppNamespace)
{
var ns = parent as CppNamespace;
foreach(var sn in ns.Namespaces)
{
if (sn.IsInlineNamespace)
{
var findElem = SearchForChild(sn, child_name);
//Find it in inline namespace, just return.
if(findElem != null) return findElem;
}
}
}

return null;
}

Expand All @@ -117,7 +132,7 @@ private CppElement SearchForChild(CppElement parent, string child_name)
/// </summary>
/// <param name="name">Name of the element to find</param>
/// <returns>The CppElement found or null if not found</returns>
public CppElement FindByFullName(string name)
public CppElement FindByFullName(string name)
{
var arr = name.Split(new string[] { "::" }, StringSplitOptions.RemoveEmptyEntries);
if(arr.Length == 0) return null;
Expand Down
Loading