Browse Source

Improved support in parser for template classes and functions.

* Use clangIndex to identify declarations across translation units.
* Added new Find*ByUSR methods and removed unused Find*(IntPtr) methods.
* Added Depth/Index and IsParameterPack fields to TemplateParameterType.
* Fixed member initialization issues in C++ Method class.
* Added AST tests for function and class templates.
* All tests pass with new and old parser.
pull/248/head
Elias Holzer 11 years ago
parent
commit
933df5e65a
  1. 1
      build/LLVM.lua
  2. 20
      src/AST/Class.cs
  3. 8
      src/AST/Declaration.cs
  4. 7
      src/AST/Function.cs
  5. 43
      src/AST/Namespace.cs
  6. 72
      src/AST/Template.cs
  7. 8
      src/AST/Type.cs
  8. 16
      src/AST/TypeExtensions.cs
  9. 27
      src/Core/Parser/ASTConverter.cs
  10. 137
      src/CppParser/AST.cpp
  11. 33
      src/CppParser/AST.h
  12. 176
      src/CppParser/Bindings/CLI/AST.cpp
  13. 109
      src/CppParser/Bindings/CLI/AST.h
  14. 652
      src/CppParser/Bindings/CSharp/AST.cs
  15. 365
      src/CppParser/Parser.cpp
  16. 6
      src/CppParser/Parser.h
  17. 59
      src/Generator.Tests/AST/TestAST.cs
  18. 4
      src/Generator.Tests/ASTTestFixture.cs
  19. 375
      src/Parser/Parser.cpp
  20. 6
      src/Parser/Parser.h
  21. 36
      tests/Native/AST.h
  22. 9
      tests/Native/ASTExtensions.h

1
build/LLVM.lua

@ -79,6 +79,7 @@ function SetupLLVMLibs() @@ -79,6 +79,7 @@ function SetupLLVMLibs()
"clangParse",
"clangSema",
"clangSerialization",
"clangIndex",
}
StaticLinksOpt { "LLVMProfileData" }

20
src/AST/Class.cs

@ -220,9 +220,27 @@ namespace CppSharp.AST @@ -220,9 +220,27 @@ namespace CppSharp.AST
return base.GetOverloads(function);
}
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 override T Visit<T>(IDeclVisitor<T> visitor)
{
return visitor.VisitClassDecl(this);
}
}
}
}

8
src/AST/Declaration.cs

@ -285,6 +285,14 @@ namespace CppSharp.AST @@ -285,6 +285,14 @@ namespace CppSharp.AST
// Pointer to the original declaration from Clang.
public IntPtr OriginalPtr;
// The Unified Symbol Resolution (USR) for the declaration.
// A Unified Symbol Resolution (USR) is a string that identifies a
// particular entity (function, class, variable, etc.) within a program.
// USRs can be compared across translation units to determine, e.g.,
// when references in one translation refer to an entity defined in
// another translation unit.
public string USR;
public List<Attribute> Attributes { get; private set; }
protected Declaration()

7
src/AST/Function.cs

@ -119,6 +119,11 @@ namespace CppSharp.AST @@ -119,6 +119,11 @@ namespace CppSharp.AST
OriginalFunction = function.OriginalFunction;
Mangled = function.Mangled;
Index = function.Index;
if (function.SpecializationInfo != null)
{
SpecializationInfo = new FunctionTemplateSpecialization(function.SpecializationInfo);
SpecializationInfo.SpecializedFunction = function;
}
}
public QualifiedType ReturnType { get; set; }
@ -136,6 +141,8 @@ namespace CppSharp.AST @@ -136,6 +141,8 @@ namespace CppSharp.AST
public CallingConvention CallingConvention { get; set; }
public FunctionTemplateSpecialization SpecializationInfo { get; set; }
public bool IsThisCall
{
get { return CallingConvention == CallingConvention.ThisCall; }

43
src/AST/Namespace.cs

@ -216,6 +216,22 @@ namespace CppSharp.AST @@ -216,6 +216,22 @@ namespace CppSharp.AST
return @namespace.FindFunction(funcName, createDecl);
}
public Function FindFunction(string name)
{
return Functions
.Concat(Templates.OfType<FunctionTemplate>()
.Select(t => t.TemplatedFunction))
.FirstOrDefault(f => f.Name == name);
}
public Function FindFunctionByUSR(string usr)
{
return Functions
.Concat(Templates.OfType<FunctionTemplate>()
.Select(t => t.TemplatedFunction))
.FirstOrDefault(f => f.USR == usr);
}
Class CreateClass(string name, bool isComplete)
{
var @class = new Class
@ -294,23 +310,28 @@ namespace CppSharp.AST @@ -294,23 +310,28 @@ namespace CppSharp.AST
return newClass;
}
public FunctionTemplate FindFunctionTemplate(string name,
List<TemplateParameter> @params)
public FunctionTemplate FindFunctionTemplate(string name)
{
return Templates.OfType<FunctionTemplate>()
.FirstOrDefault(t => t.Name == name);
}
public FunctionTemplate FindFunctionTemplateByUSR(string usr)
{
return Templates.FirstOrDefault(template => template.Name == name
&& template.Parameters.SequenceEqual(@params)) as FunctionTemplate;
return Templates.OfType<FunctionTemplate>()
.FirstOrDefault(t => t.USR == usr);
}
public FunctionTemplate FindFunctionTemplate(IntPtr ptr)
public ClassTemplate FindClassTemplate(string name)
{
return Templates.FirstOrDefault(template =>
template.OriginalPtr == ptr) as FunctionTemplate;
return Templates.OfType<ClassTemplate>()
.FirstOrDefault(t => t.Name == name);
}
public ClassTemplate FindClassTemplate(IntPtr ptr)
public ClassTemplate FindClassTemplateByUSR(string usr)
{
return Templates.FirstOrDefault(template =>
template.OriginalPtr == ptr) as ClassTemplate;
return Templates.OfType<ClassTemplate>()
.FirstOrDefault(t => t.USR == usr);
}
public TypedefDecl FindTypedef(string name, bool createDecl = false)
@ -417,4 +438,4 @@ namespace CppSharp.AST @@ -417,4 +438,4 @@ namespace CppSharp.AST
return visitor.VisitNamespace(this);
}
}
}
}

72
src/AST/Template.cs

@ -13,6 +13,10 @@ namespace CppSharp.AST @@ -13,6 +13,10 @@ namespace CppSharp.AST
// Generic type constraint
public string Constraint;
// Whether the template parameter represents a type parameter,
// like "T" in template<typename T>.
public bool IsTypeParameter;
}
/// <summary>
@ -24,8 +28,18 @@ namespace CppSharp.AST @@ -24,8 +28,18 @@ namespace CppSharp.AST
// Name of the declaration.
public override string Name
{
get { return TemplatedDecl.Name; }
set { base.Name = value; }
get
{
if (TemplatedDecl != null)
return TemplatedDecl.Name;
return base.Name;
}
set
{
base.Name = value;
if (TemplatedDecl != null)
TemplatedDecl.Name = value;
}
}
protected Template()
@ -111,27 +125,14 @@ namespace CppSharp.AST @@ -111,27 +125,14 @@ namespace CppSharp.AST
}
}
public ClassTemplateSpecialization FindSpecialization(
TemplateSpecializationType type)
{
return Specializations.FirstOrDefault(
spec => spec.Arguments.SequenceEqual(type.Arguments));
}
public ClassTemplateSpecialization FindSpecialization(IntPtr ptr)
{
return Specializations.FirstOrDefault(spec => spec.OriginalPtr == ptr);
}
public ClassTemplatePartialSpecialization FindPartialSpecialization(
TemplateSpecializationType type)
public ClassTemplateSpecialization FindSpecializationByUSR(string usr)
{
return FindSpecialization(type) as ClassTemplatePartialSpecialization;
return Specializations.FirstOrDefault(spec => spec.USR == usr);
}
public ClassTemplatePartialSpecialization FindPartialSpecialization(IntPtr ptr)
public ClassTemplatePartialSpecialization FindPartialSpecializationByUSR(string usr)
{
return FindSpecialization(ptr) as ClassTemplatePartialSpecialization;
return FindSpecializationByUSR(usr) as ClassTemplatePartialSpecialization;
}
}
@ -193,13 +194,17 @@ namespace CppSharp.AST @@ -193,13 +194,17 @@ namespace CppSharp.AST
/// </summary>
public class FunctionTemplate : Template
{
public List<FunctionTemplateSpecialization> Specializations;
public FunctionTemplate()
{
Specializations = new List<FunctionTemplateSpecialization>();
}
public FunctionTemplate(Declaration decl)
: base(decl)
{
Specializations = new List<FunctionTemplateSpecialization>();
}
public Function TemplatedFunction
@ -212,4 +217,33 @@ namespace CppSharp.AST @@ -212,4 +217,33 @@ namespace CppSharp.AST
return visitor.VisitFunctionTemplateDecl(this);
}
}
/// <summary>
/// Represents a function template specialization, which refers to a function
/// template with a given set of template arguments.
/// </summary>
public class FunctionTemplateSpecialization
{
public FunctionTemplate Template;
public List<TemplateArgument> Arguments;
public Function SpecializedFunction;
public TemplateSpecializationKind SpecializationKind;
public FunctionTemplateSpecialization()
{
Arguments = new List<TemplateArgument>();
}
public FunctionTemplateSpecialization(FunctionTemplateSpecialization fts)
{
Template = fts.Template;
Arguments = new List<TemplateArgument>();
Arguments.AddRange(fts.Arguments);
SpecializedFunction = fts.SpecializedFunction;
SpecializationKind = fts.SpecializationKind;
}
}
}

8
src/AST/Type.cs

@ -508,6 +508,9 @@ namespace CppSharp.AST @@ -508,6 +508,9 @@ namespace CppSharp.AST
public class TemplateParameterType : Type
{
public TemplateParameter Parameter;
public uint Depth;
public uint Index;
public bool IsParameterPack;
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
@ -520,7 +523,10 @@ namespace CppSharp.AST @@ -520,7 +523,10 @@ namespace CppSharp.AST
var type = obj as TemplateParameterType;
if (type == null) return false;
return Parameter.Equals(type.Parameter);
return Parameter.Equals(type.Parameter)
&& Depth.Equals(type.Depth)
&& Index.Equals(type.Index)
&& IsParameterPack.Equals(type.IsParameterPack);
}
public override int GetHashCode()

16
src/AST/TypeExtensions.cs

@ -158,16 +158,22 @@ @@ -158,16 +158,22 @@
public static Type Desugar(this Type t)
{
var type = t as TypedefType;
if (type != null)
var typeDef = t as TypedefType;
if (typeDef != null)
{
var decl = type.Declaration.Type;
var decl = typeDef.Declaration.Type;
if (decl != null)
return decl.Desugar();
}
var substType = t as TemplateParameterSubstitutionType;
if (substType != null)
{
var replacement = substType.Replacement.Type;
if (replacement != null)
return replacement.Desugar();
}
return t;
}

27
src/Core/Parser/ASTConverter.cs

@ -496,6 +496,9 @@ namespace CppSharp @@ -496,6 +496,9 @@ namespace CppSharp
{
var _type = new AST.TemplateParameterType();
_type.Parameter = DeclConverter.VisitTemplateParameter(type.Parameter);
_type.Depth = type.Depth;
_type.Index = type.Index;
_type.IsParameterPack = type.IsParameterPack;
VisitType(type, _type);
return _type;
}
@ -1255,6 +1258,7 @@ namespace CppSharp @@ -1255,6 +1258,7 @@ namespace CppSharp
{
var _param = new AST.TemplateParameter();
_param.Name = param.Name;
_param.IsTypeParameter = param.IsTypeParameter;
return _param;
}
@ -1356,11 +1360,30 @@ namespace CppSharp @@ -1356,11 +1360,30 @@ namespace CppSharp
public override AST.Declaration VisitFunctionTemplate(FunctionTemplate decl)
{
var _decl = new AST.FunctionTemplate();
var _decl = new AST.FunctionTemplate(Visit(decl.TemplatedDecl));
VisitTemplate(decl, _decl);
for (uint i = 0; i < decl.SpecializationsCount; ++i)
{
var _spec = VisitFunctionTemplateSpecialization(decl.getSpecializations(i));
_decl.Specializations.Add(_spec);
}
return _decl;
}
private AST.FunctionTemplateSpecialization VisitFunctionTemplateSpecialization(FunctionTemplateSpecialization spec)
{
var _spec = new AST.FunctionTemplateSpecialization();
_spec.Template = (AST.FunctionTemplate)Visit(spec.Template);
_spec.SpecializedFunction = (AST.Function)Visit(spec.SpecializedFunction);
_spec.SpecializationKind = VisitSpecializationKind(spec.SpecializationKind);
for (uint i = 0; i < spec.ArgumentsCount; ++i)
{
var _arg = VisitTemplateArgument(spec.getArguments(i));
_spec.Arguments.Add(_arg);
}
return _spec;
}
void VisitPreprocessedEntity(PreprocessedEntity entity, AST.PreprocessedEntity _entity)
{
VisitDeclaration(entity, _entity);
@ -1416,4 +1439,4 @@ namespace CppSharp @@ -1416,4 +1439,4 @@ namespace CppSharp
#endregion
}
#endif
#endif

137
src/CppParser/AST.cpp

@ -69,8 +69,16 @@ TemplateSpecializationType::TemplateSpecializationType( @@ -69,8 +69,16 @@ TemplateSpecializationType::TemplateSpecializationType(
DEF_VECTOR(TemplateSpecializationType, TemplateArgument, Arguments)
// TemplateParameter
TemplateParameter::TemplateParameter() {}
TemplateParameter::TemplateParameter(const TemplateParameter& rhs) : Name(rhs.Name) {}
TemplateParameter::TemplateParameter()
: IsTypeParameter(false)
{
}
TemplateParameter::TemplateParameter(const TemplateParameter& rhs)
: Name(rhs.Name)
, IsTypeParameter(rhs.IsTypeParameter)
{
}
DEF_STRING(TemplateParameter, Name)
@ -341,60 +349,44 @@ Enumeration* DeclarationContext::FindEnumWithItem(const std::string& Name) @@ -341,60 +349,44 @@ Enumeration* DeclarationContext::FindEnumWithItem(const std::string& Name)
return nullptr;
}
Function* DeclarationContext::FindFunction(const std::string& Name, bool Create)
Function* DeclarationContext::FindFunction(const std::string& USR)
{
auto foundFunction = std::find_if(Functions.begin(), Functions.end(),
[&](Function* func) { return func->Name == Name; });
[&](Function* func) { return func->USR == USR; });
if (foundFunction != Functions.end())
return *foundFunction;
if (!Create)
return nullptr;
auto function = new Function();
function->Name = Name;
function->_Namespace = this;
Functions.push_back(function);
return function;
}
ClassTemplate*
DeclarationContext::FindClassTemplate(void* OriginalPtr)
{
auto foundTemplate = std::find_if(Templates.begin(), Templates.end(),
[&](Template* t) { return t->OriginalPtr == OriginalPtr; });
[&](Template* t) { return t->TemplatedDecl->USR == USR; });
if (foundTemplate != Templates.end())
return static_cast<ClassTemplate*>(*foundTemplate);
return static_cast<Function*>((*foundTemplate)->TemplatedDecl);
return nullptr;
}
FunctionTemplate*
DeclarationContext::FindFunctionTemplate(void* OriginalPtr)
ClassTemplate*
DeclarationContext::FindClassTemplate(const std::string& USR)
{
auto foundFunction = std::find_if(Templates.begin(), Templates.end(),
[&](Template* func) { return func->OriginalPtr == OriginalPtr; });
auto foundTemplate = std::find_if(Templates.begin(), Templates.end(),
[&](Template* t) { return t->USR == USR; });
if (foundFunction != Templates.end())
return static_cast<FunctionTemplate*>(*foundFunction);
if (foundTemplate != Templates.end())
return static_cast<ClassTemplate*>(*foundTemplate);
return nullptr;
}
FunctionTemplate*
DeclarationContext::FindFunctionTemplate(const std::string& Name,
const std::vector<TemplateParameter>& Params)
DeclarationContext::FindFunctionTemplate(const std::string& USR)
{
FunctionTemplate* func = 0;
auto foundFunction = std::find_if(Templates.begin(), Templates.end(),
[&](Template* func) { return func->Name == Name && func->Parameters == Params; }
auto foundTemplate = std::find_if(Templates.begin(), Templates.end(),
[&](Template* t) { return t->USR == USR; }
);
if (foundFunction != Templates.end())
return static_cast<FunctionTemplate*>(*foundFunction);
if (foundTemplate != Templates.end())
return static_cast<FunctionTemplate*>(*foundTemplate);
return nullptr;
}
@ -423,15 +415,32 @@ TypedefDecl::TypedefDecl() : Declaration(DeclarationKind::Typedef) {} @@ -423,15 +415,32 @@ TypedefDecl::TypedefDecl() : Declaration(DeclarationKind::Typedef) {}
Parameter::Parameter() : Declaration(DeclarationKind::Parameter),
IsIndirect(false), HasDefaultValue(false) {}
Function::Function() : Declaration(DeclarationKind::Function),
IsReturnIndirect(false) {}
Function::Function()
: Declaration(DeclarationKind::Function)
, IsReturnIndirect(false)
, SpecializationInfo(0)
{
}
DEF_STRING(Function, Mangled)
DEF_STRING(Function, Signature)
DEF_VECTOR(Function, Parameter*, Parameters)
Method::Method() : IsDefaultConstructor(false), IsCopyConstructor(false),
IsMoveConstructor(false) { Kind = DeclarationKind::Method; }
Method::Method()
: Function()
, AccessDecl(0)
, IsVirtual(false)
, IsStatic(false)
, IsConst(false)
, IsImplicit(false)
, IsExplicit(false)
, IsOverride(false)
, IsDefaultConstructor(false)
, IsCopyConstructor(false)
, IsMoveConstructor(false)
{
Kind = DeclarationKind::Method;
}
// Enumeration
@ -496,16 +505,44 @@ ClassTemplate::ClassTemplate() : Template(DeclarationKind::ClassTemplate) {} @@ -496,16 +505,44 @@ ClassTemplate::ClassTemplate() : Template(DeclarationKind::ClassTemplate) {}
DEF_VECTOR(ClassTemplate, ClassTemplateSpecialization*, Specializations)
ClassTemplateSpecialization::ClassTemplateSpecialization() : TemplatedDecl(0)
{ Kind = DeclarationKind::ClassTemplateSpecialization; }
ClassTemplateSpecialization::ClassTemplateSpecialization()
: Class()
, TemplatedDecl(0)
{
Kind = DeclarationKind::ClassTemplateSpecialization;
}
DEF_VECTOR(ClassTemplateSpecialization, TemplateArgument, Arguments)
ClassTemplatePartialSpecialization::ClassTemplatePartialSpecialization()
{ Kind = DeclarationKind::ClassTemplatePartialSpecialization; }
: ClassTemplateSpecialization()
{
Kind = DeclarationKind::ClassTemplatePartialSpecialization;
}
FunctionTemplate::FunctionTemplate() : Template(DeclarationKind::FunctionTemplate) {}
DEF_VECTOR(FunctionTemplate, FunctionTemplateSpecialization*, Specializations)
FunctionTemplateSpecialization* FunctionTemplate::FindSpecialization(const std::string& usr)
{
auto foundSpec = std::find_if(Specializations.begin(), Specializations.end(),
[&](FunctionTemplateSpecialization* cts) { return cts->SpecializedFunction->USR == usr; });
if (foundSpec != Specializations.end())
return static_cast<FunctionTemplateSpecialization*>(*foundSpec);
return nullptr;
}
FunctionTemplateSpecialization::FunctionTemplateSpecialization()
: Template(0)
, SpecializedFunction(0)
{
}
DEF_VECTOR(FunctionTemplateSpecialization, TemplateArgument, Arguments)
Namespace::Namespace()
: DeclarationContext(DeclarationKind::Namespace)
, IsInline(false)
@ -536,10 +573,10 @@ DEF_VECTOR_STRING(NativeLibrary, Symbols) @@ -536,10 +573,10 @@ DEF_VECTOR_STRING(NativeLibrary, Symbols)
// ASTContext
DEF_VECTOR(ASTContext, TranslationUnit*, TranslationUnits)
ClassTemplateSpecialization* ClassTemplate::FindSpecialization(void* ptr)
ClassTemplateSpecialization* ClassTemplate::FindSpecialization(const std::string& usr)
{
auto foundSpec = std::find_if(Specializations.begin(), Specializations.end(),
[&](ClassTemplateSpecialization* cts) { return cts->OriginalPtr == ptr; });
[&](ClassTemplateSpecialization* cts) { return cts->USR == usr; });
if (foundSpec != Specializations.end())
return static_cast<ClassTemplateSpecialization*>(*foundSpec);
@ -547,26 +584,14 @@ ClassTemplateSpecialization* ClassTemplate::FindSpecialization(void* ptr) @@ -547,26 +584,14 @@ ClassTemplateSpecialization* ClassTemplate::FindSpecialization(void* ptr)
return nullptr;
}
ClassTemplateSpecialization*
ClassTemplate::FindSpecialization(TemplateSpecializationType type)
ClassTemplatePartialSpecialization* ClassTemplate::FindPartialSpecialization(const std::string& usr)
{
return 0;
}
ClassTemplatePartialSpecialization* ClassTemplate::FindPartialSpecialization(void* ptr)
{
auto foundSpec = FindSpecialization(ptr);
auto foundSpec = FindSpecialization(usr);
if (foundSpec != nullptr)
return static_cast<ClassTemplatePartialSpecialization*>(foundSpec);
return nullptr;
}
ClassTemplatePartialSpecialization*
ClassTemplate::FindPartialSpecialization(TemplateSpecializationType type)
{
return 0;
}
ASTContext::ASTContext() {}
TranslationUnit* ASTContext::FindOrCreateModule(std::string File)

33
src/CppParser/AST.h

@ -191,12 +191,16 @@ struct CS_API TemplateParameter @@ -191,12 +191,16 @@ struct CS_API TemplateParameter
}
STRING(Name)
bool IsTypeParameter;
};
struct CS_API TemplateParameterType : public Type
{
DECLARE_TYPE_KIND(TemplateParameter)
TemplateParameter Parameter;
unsigned int Depth;
unsigned int Index;
bool IsParameterPack;
};
struct CS_API TemplateParameterSubstitutionType : public Type
@ -372,6 +376,7 @@ struct CS_API Declaration @@ -372,6 +376,7 @@ struct CS_API Declaration
unsigned DefinitionOrder;
VECTOR(PreprocessedEntity*, PreprocessedEntities)
void* OriginalPtr;
std::string USR;
};
struct Class;
@ -399,16 +404,14 @@ struct CS_API DeclarationContext : public Declaration @@ -399,16 +404,14 @@ struct CS_API DeclarationContext : public Declaration
CS_IGNORE Class* FindClass(const std::string& Name, bool IsComplete,
bool Create = false);
CS_IGNORE ClassTemplate* FindClassTemplate(void* OriginalPtr);
CS_IGNORE FunctionTemplate* FindFunctionTemplate(void* OriginalPtr);
CS_IGNORE FunctionTemplate* FindFunctionTemplate(const std::string& Name,
const std::vector<TemplateParameter>& Params);
CS_IGNORE ClassTemplate* FindClassTemplate(const std::string& USR);
CS_IGNORE FunctionTemplate* FindFunctionTemplate(const std::string& USR);
CS_IGNORE Enumeration* FindEnum(void* OriginalPtr);
CS_IGNORE Enumeration* FindEnum(const std::string& Name, bool Create = false);
CS_IGNORE Enumeration* FindEnumWithItem(const std::string& Name);
CS_IGNORE Function* FindFunction(const std::string& Name, bool Create = false);
CS_IGNORE Function* FindFunction(const std::string& USR);
CS_IGNORE TypedefDecl* FindTypedef(const std::string& Name, bool Create = false);
@ -498,6 +501,8 @@ enum struct CXXOperatorKind @@ -498,6 +501,8 @@ enum struct CXXOperatorKind
Conditional
};
struct FunctionTemplateSpecialization;
struct CS_API Function : public Declaration
{
Function();
@ -514,6 +519,7 @@ struct CS_API Function : public Declaration @@ -514,6 +519,7 @@ struct CS_API Function : public Declaration
STRING(Signature)
CppSharp::CppParser::AST::CallingConvention CallingConvention;
VECTOR(Parameter*, Parameters)
FunctionTemplateSpecialization* SpecializationInfo;
};
struct AccessSpecifierDecl;
@ -638,10 +644,8 @@ struct CS_API ClassTemplate : public Template @@ -638,10 +644,8 @@ struct CS_API ClassTemplate : public Template
{
ClassTemplate();
VECTOR(ClassTemplateSpecialization*, Specializations)
ClassTemplateSpecialization* FindSpecialization(void* ptr);
ClassTemplateSpecialization* FindSpecialization(TemplateSpecializationType type);
ClassTemplatePartialSpecialization* FindPartialSpecialization(void* ptr);
ClassTemplatePartialSpecialization* FindPartialSpecialization(TemplateSpecializationType type);
ClassTemplateSpecialization* FindSpecialization(const std::string& usr);
ClassTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr);
};
enum struct TemplateSpecializationKind
@ -669,6 +673,17 @@ struct CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecializ @@ -669,6 +673,17 @@ struct CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecializ
struct CS_API FunctionTemplate : public Template
{
FunctionTemplate();
VECTOR(FunctionTemplateSpecialization*, Specializations)
FunctionTemplateSpecialization* FindSpecialization(const std::string& usr);
};
struct CS_API FunctionTemplateSpecialization
{
FunctionTemplateSpecialization();
FunctionTemplate* Template;
VECTOR(TemplateArgument, Arguments)
Function* SpecializedFunction;
TemplateSpecializationKind SpecializationKind;
};
struct CS_API Namespace : public DeclarationContext

176
src/CppParser/Bindings/CLI/AST.cpp

@ -627,6 +627,16 @@ void CppSharp::Parser::AST::TemplateParameter::Name::set(System::String^ s) @@ -627,6 +627,16 @@ void CppSharp::Parser::AST::TemplateParameter::Name::set(System::String^ s)
((::CppSharp::CppParser::AST::TemplateParameter*)NativePtr)->setName(arg0);
}
bool CppSharp::Parser::AST::TemplateParameter::IsTypeParameter::get()
{
return ((::CppSharp::CppParser::AST::TemplateParameter*)NativePtr)->IsTypeParameter;
}
void CppSharp::Parser::AST::TemplateParameter::IsTypeParameter::set(bool value)
{
((::CppSharp::CppParser::AST::TemplateParameter*)NativePtr)->IsTypeParameter = value;
}
CppSharp::Parser::AST::TemplateParameterType::TemplateParameterType(::CppSharp::CppParser::AST::TemplateParameterType* native)
: CppSharp::Parser::AST::Type((::CppSharp::CppParser::AST::Type*)native)
{
@ -654,6 +664,36 @@ void CppSharp::Parser::AST::TemplateParameterType::Parameter::set(CppSharp::Pars @@ -654,6 +664,36 @@ void CppSharp::Parser::AST::TemplateParameterType::Parameter::set(CppSharp::Pars
((::CppSharp::CppParser::AST::TemplateParameterType*)NativePtr)->Parameter = *(::CppSharp::CppParser::AST::TemplateParameter*)value->NativePtr;
}
unsigned int CppSharp::Parser::AST::TemplateParameterType::Depth::get()
{
return ((::CppSharp::CppParser::AST::TemplateParameterType*)NativePtr)->Depth;
}
void CppSharp::Parser::AST::TemplateParameterType::Depth::set(unsigned int value)
{
((::CppSharp::CppParser::AST::TemplateParameterType*)NativePtr)->Depth = value;
}
unsigned int CppSharp::Parser::AST::TemplateParameterType::Index::get()
{
return ((::CppSharp::CppParser::AST::TemplateParameterType*)NativePtr)->Index;
}
void CppSharp::Parser::AST::TemplateParameterType::Index::set(unsigned int value)
{
((::CppSharp::CppParser::AST::TemplateParameterType*)NativePtr)->Index = value;
}
bool CppSharp::Parser::AST::TemplateParameterType::IsParameterPack::get()
{
return ((::CppSharp::CppParser::AST::TemplateParameterType*)NativePtr)->IsParameterPack;
}
void CppSharp::Parser::AST::TemplateParameterType::IsParameterPack::set(bool value)
{
((::CppSharp::CppParser::AST::TemplateParameterType*)NativePtr)->IsParameterPack = value;
}
CppSharp::Parser::AST::TemplateParameterSubstitutionType::TemplateParameterSubstitutionType(::CppSharp::CppParser::AST::TemplateParameterSubstitutionType* native)
: CppSharp::Parser::AST::Type((::CppSharp::CppParser::AST::Type*)native)
{
@ -1614,6 +1654,16 @@ void CppSharp::Parser::AST::Function::CallingConvention::set(CppSharp::Parser::A @@ -1614,6 +1654,16 @@ void CppSharp::Parser::AST::Function::CallingConvention::set(CppSharp::Parser::A
((::CppSharp::CppParser::AST::Function*)NativePtr)->CallingConvention = (::CppSharp::CppParser::AST::CallingConvention)value;
}
CppSharp::Parser::AST::FunctionTemplateSpecialization^ CppSharp::Parser::AST::Function::SpecializationInfo::get()
{
return (((::CppSharp::CppParser::AST::Function*)NativePtr)->SpecializationInfo == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::FunctionTemplateSpecialization((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)((::CppSharp::CppParser::AST::Function*)NativePtr)->SpecializationInfo);
}
void CppSharp::Parser::AST::Function::SpecializationInfo::set(CppSharp::Parser::AST::FunctionTemplateSpecialization^ value)
{
((::CppSharp::CppParser::AST::Function*)NativePtr)->SpecializationInfo = (::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)value->NativePtr;
}
CppSharp::Parser::AST::Method::Method(::CppSharp::CppParser::AST::Method* native)
: CppSharp::Parser::AST::Function((::CppSharp::CppParser::AST::Function*)native)
{
@ -2295,38 +2345,6 @@ void CppSharp::Parser::AST::ClassTemplate::addSpecializations(CppSharp::Parser:: @@ -2295,38 +2345,6 @@ void CppSharp::Parser::AST::ClassTemplate::addSpecializations(CppSharp::Parser::
((::CppSharp::CppParser::AST::ClassTemplate*)NativePtr)->addSpecializations(arg0);
}
CppSharp::Parser::AST::ClassTemplateSpecialization^ CppSharp::Parser::AST::ClassTemplate::FindSpecialization(void* ptr)
{
auto arg0 = (void*)ptr;
auto __ret = ((::CppSharp::CppParser::AST::ClassTemplate*)NativePtr)->FindSpecialization(arg0);
if (__ret == nullptr) return nullptr;
return (__ret == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::ClassTemplateSpecialization((::CppSharp::CppParser::AST::ClassTemplateSpecialization*)__ret);
}
CppSharp::Parser::AST::ClassTemplateSpecialization^ CppSharp::Parser::AST::ClassTemplate::FindSpecialization(CppSharp::Parser::AST::TemplateSpecializationType^ type)
{
auto arg0 = *(::CppSharp::CppParser::AST::TemplateSpecializationType*)type->NativePtr;
auto __ret = ((::CppSharp::CppParser::AST::ClassTemplate*)NativePtr)->FindSpecialization(arg0);
if (__ret == nullptr) return nullptr;
return (__ret == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::ClassTemplateSpecialization((::CppSharp::CppParser::AST::ClassTemplateSpecialization*)__ret);
}
CppSharp::Parser::AST::ClassTemplatePartialSpecialization^ CppSharp::Parser::AST::ClassTemplate::FindPartialSpecialization(void* ptr)
{
auto arg0 = (void*)ptr;
auto __ret = ((::CppSharp::CppParser::AST::ClassTemplate*)NativePtr)->FindPartialSpecialization(arg0);
if (__ret == nullptr) return nullptr;
return (__ret == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::ClassTemplatePartialSpecialization((::CppSharp::CppParser::AST::ClassTemplatePartialSpecialization*)__ret);
}
CppSharp::Parser::AST::ClassTemplatePartialSpecialization^ CppSharp::Parser::AST::ClassTemplate::FindPartialSpecialization(CppSharp::Parser::AST::TemplateSpecializationType^ type)
{
auto arg0 = *(::CppSharp::CppParser::AST::TemplateSpecializationType*)type->NativePtr;
auto __ret = ((::CppSharp::CppParser::AST::ClassTemplate*)NativePtr)->FindPartialSpecialization(arg0);
if (__ret == nullptr) return nullptr;
return (__ret == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::ClassTemplatePartialSpecialization((::CppSharp::CppParser::AST::ClassTemplatePartialSpecialization*)__ret);
}
unsigned int CppSharp::Parser::AST::ClassTemplate::SpecializationsCount::get()
{
auto __ret = ((::CppSharp::CppParser::AST::ClassTemplate*)NativePtr)->getSpecializationsCount();
@ -2423,6 +2441,100 @@ CppSharp::Parser::AST::FunctionTemplate::FunctionTemplate() @@ -2423,6 +2441,100 @@ CppSharp::Parser::AST::FunctionTemplate::FunctionTemplate()
NativePtr = new ::CppSharp::CppParser::AST::FunctionTemplate();
}
CppSharp::Parser::AST::FunctionTemplateSpecialization^ CppSharp::Parser::AST::FunctionTemplate::getSpecializations(unsigned int i)
{
auto __ret = ((::CppSharp::CppParser::AST::FunctionTemplate*)NativePtr)->getSpecializations(i);
if (__ret == nullptr) return nullptr;
return (__ret == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::FunctionTemplateSpecialization((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)__ret);
}
void CppSharp::Parser::AST::FunctionTemplate::addSpecializations(CppSharp::Parser::AST::FunctionTemplateSpecialization^ s)
{
auto arg0 = (::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)s->NativePtr;
((::CppSharp::CppParser::AST::FunctionTemplate*)NativePtr)->addSpecializations(arg0);
}
unsigned int CppSharp::Parser::AST::FunctionTemplate::SpecializationsCount::get()
{
auto __ret = ((::CppSharp::CppParser::AST::FunctionTemplate*)NativePtr)->getSpecializationsCount();
return __ret;
}
CppSharp::Parser::AST::FunctionTemplateSpecialization::FunctionTemplateSpecialization(::CppSharp::CppParser::AST::FunctionTemplateSpecialization* native)
{
NativePtr = native;
}
CppSharp::Parser::AST::FunctionTemplateSpecialization::FunctionTemplateSpecialization(System::IntPtr native)
{
auto __native = (::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)native.ToPointer();
NativePtr = __native;
}
CppSharp::Parser::AST::FunctionTemplateSpecialization::FunctionTemplateSpecialization()
{
NativePtr = new ::CppSharp::CppParser::AST::FunctionTemplateSpecialization();
}
CppSharp::Parser::AST::TemplateArgument^ CppSharp::Parser::AST::FunctionTemplateSpecialization::getArguments(unsigned int i)
{
auto __ret = ((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->getArguments(i);
auto ____ret = new ::CppSharp::CppParser::AST::TemplateArgument(__ret);
return (____ret == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::TemplateArgument((::CppSharp::CppParser::AST::TemplateArgument*)____ret);
}
void CppSharp::Parser::AST::FunctionTemplateSpecialization::addArguments(CppSharp::Parser::AST::TemplateArgument^ s)
{
auto &arg0 = *(::CppSharp::CppParser::AST::TemplateArgument*)s->NativePtr;
((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->addArguments(arg0);
}
System::IntPtr CppSharp::Parser::AST::FunctionTemplateSpecialization::__Instance::get()
{
return System::IntPtr(NativePtr);
}
void CppSharp::Parser::AST::FunctionTemplateSpecialization::__Instance::set(System::IntPtr object)
{
NativePtr = (::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)object.ToPointer();
}
unsigned int CppSharp::Parser::AST::FunctionTemplateSpecialization::ArgumentsCount::get()
{
auto __ret = ((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->getArgumentsCount();
return __ret;
}
CppSharp::Parser::AST::FunctionTemplate^ CppSharp::Parser::AST::FunctionTemplateSpecialization::Template::get()
{
return (((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->Template == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::FunctionTemplate((::CppSharp::CppParser::AST::FunctionTemplate*)((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->Template);
}
void CppSharp::Parser::AST::FunctionTemplateSpecialization::Template::set(CppSharp::Parser::AST::FunctionTemplate^ value)
{
((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->Template = (::CppSharp::CppParser::AST::FunctionTemplate*)value->NativePtr;
}
CppSharp::Parser::AST::Function^ CppSharp::Parser::AST::FunctionTemplateSpecialization::SpecializedFunction::get()
{
return (((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->SpecializedFunction == nullptr) ? nullptr : gcnew CppSharp::Parser::AST::Function((::CppSharp::CppParser::AST::Function*)((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->SpecializedFunction);
}
void CppSharp::Parser::AST::FunctionTemplateSpecialization::SpecializedFunction::set(CppSharp::Parser::AST::Function^ value)
{
((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->SpecializedFunction = (::CppSharp::CppParser::AST::Function*)value->NativePtr;
}
CppSharp::Parser::AST::TemplateSpecializationKind CppSharp::Parser::AST::FunctionTemplateSpecialization::SpecializationKind::get()
{
return (CppSharp::Parser::AST::TemplateSpecializationKind)((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->SpecializationKind;
}
void CppSharp::Parser::AST::FunctionTemplateSpecialization::SpecializationKind::set(CppSharp::Parser::AST::TemplateSpecializationKind value)
{
((::CppSharp::CppParser::AST::FunctionTemplateSpecialization*)NativePtr)->SpecializationKind = (::CppSharp::CppParser::AST::TemplateSpecializationKind)value;
}
CppSharp::Parser::AST::Namespace::Namespace(::CppSharp::CppParser::AST::Namespace* native)
: CppSharp::Parser::AST::DeclarationContext((::CppSharp::CppParser::AST::DeclarationContext*)native)
{

109
src/CppParser/Bindings/CLI/AST.h

@ -43,6 +43,7 @@ namespace CppSharp @@ -43,6 +43,7 @@ namespace CppSharp
ref class FullComment;
ref class Function;
ref class FunctionTemplate;
ref class FunctionTemplateSpecialization;
ref class FunctionType;
ref class InjectedClassNameType;
ref class MacroDefinition;
@ -202,6 +203,15 @@ namespace CppSharp @@ -202,6 +203,15 @@ namespace CppSharp
Unknown = 5
};
public enum struct TemplateSpecializationKind
{
Undeclared = 0,
ImplicitInstantiation = 1,
ExplicitSpecialization = 2,
ExplicitInstantiationDeclaration = 3,
ExplicitInstantiationDefinition = 4
};
public enum struct CppAbi
{
Itanium = 0,
@ -221,15 +231,6 @@ namespace CppSharp @@ -221,15 +231,6 @@ namespace CppSharp
UnusedFunctionPointer = 7
};
public enum struct TemplateSpecializationKind
{
Undeclared = 0,
ImplicitInstantiation = 1,
ExplicitSpecialization = 2,
ExplicitInstantiationDeclaration = 3,
ExplicitInstantiationDefinition = 4
};
public enum struct PrimitiveType
{
Null = 0,
@ -658,6 +659,12 @@ namespace CppSharp @@ -658,6 +659,12 @@ namespace CppSharp
void set(System::String^);
}
property bool IsTypeParameter
{
bool get();
void set(bool);
}
static bool operator==(CppSharp::Parser::AST::TemplateParameter^ __op, CppSharp::Parser::AST::TemplateParameter^ param);
};
@ -674,6 +681,24 @@ namespace CppSharp @@ -674,6 +681,24 @@ namespace CppSharp
CppSharp::Parser::AST::TemplateParameter^ get();
void set(CppSharp::Parser::AST::TemplateParameter^);
}
property unsigned int Depth
{
unsigned int get();
void set(unsigned int);
}
property unsigned int Index
{
unsigned int get();
void set(unsigned int);
}
property bool IsParameterPack
{
bool get();
void set(bool);
}
};
public ref class TemplateParameterSubstitutionType : CppSharp::Parser::AST::Type
@ -1201,6 +1226,12 @@ namespace CppSharp @@ -1201,6 +1226,12 @@ namespace CppSharp
void set(CppSharp::Parser::AST::CallingConvention);
}
property CppSharp::Parser::AST::FunctionTemplateSpecialization^ SpecializationInfo
{
CppSharp::Parser::AST::FunctionTemplateSpecialization^ get();
void set(CppSharp::Parser::AST::FunctionTemplateSpecialization^);
}
CppSharp::Parser::AST::Parameter^ getParameters(unsigned int i);
void addParameters(CppSharp::Parser::AST::Parameter^ s);
@ -1590,14 +1621,6 @@ namespace CppSharp @@ -1590,14 +1621,6 @@ namespace CppSharp
CppSharp::Parser::AST::ClassTemplateSpecialization^ getSpecializations(unsigned int i);
void addSpecializations(CppSharp::Parser::AST::ClassTemplateSpecialization^ s);
CppSharp::Parser::AST::ClassTemplateSpecialization^ FindSpecialization(void* ptr);
CppSharp::Parser::AST::ClassTemplateSpecialization^ FindSpecialization(CppSharp::Parser::AST::TemplateSpecializationType^ type);
CppSharp::Parser::AST::ClassTemplatePartialSpecialization^ FindPartialSpecialization(void* ptr);
CppSharp::Parser::AST::ClassTemplatePartialSpecialization^ FindPartialSpecialization(CppSharp::Parser::AST::TemplateSpecializationType^ type);
};
public ref class ClassTemplateSpecialization : CppSharp::Parser::AST::Class
@ -1646,6 +1669,58 @@ namespace CppSharp @@ -1646,6 +1669,58 @@ namespace CppSharp
FunctionTemplate(::CppSharp::CppParser::AST::FunctionTemplate* native);
FunctionTemplate(System::IntPtr native);
FunctionTemplate();
property unsigned int SpecializationsCount
{
unsigned int get();
}
CppSharp::Parser::AST::FunctionTemplateSpecialization^ getSpecializations(unsigned int i);
void addSpecializations(CppSharp::Parser::AST::FunctionTemplateSpecialization^ s);
};
public ref class FunctionTemplateSpecialization : ICppInstance
{
public:
property ::CppSharp::CppParser::AST::FunctionTemplateSpecialization* NativePtr;
property System::IntPtr __Instance
{
virtual System::IntPtr get();
virtual void set(System::IntPtr instance);
}
FunctionTemplateSpecialization(::CppSharp::CppParser::AST::FunctionTemplateSpecialization* native);
FunctionTemplateSpecialization(System::IntPtr native);
FunctionTemplateSpecialization();
property unsigned int ArgumentsCount
{
unsigned int get();
}
property CppSharp::Parser::AST::FunctionTemplate^ Template
{
CppSharp::Parser::AST::FunctionTemplate^ get();
void set(CppSharp::Parser::AST::FunctionTemplate^);
}
property CppSharp::Parser::AST::Function^ SpecializedFunction
{
CppSharp::Parser::AST::Function^ get();
void set(CppSharp::Parser::AST::Function^);
}
property CppSharp::Parser::AST::TemplateSpecializationKind SpecializationKind
{
CppSharp::Parser::AST::TemplateSpecializationKind get();
void set(CppSharp::Parser::AST::TemplateSpecializationKind);
}
CppSharp::Parser::AST::TemplateArgument^ getArguments(unsigned int i);
void addArguments(CppSharp::Parser::AST::TemplateArgument^ s);
};
public ref class Namespace : CppSharp::Parser::AST::DeclarationContext

652
src/CppParser/Bindings/CSharp/AST.cs

File diff suppressed because it is too large Load Diff

365
src/CppParser/Parser.cpp

@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
#include <clang/Sema/SemaConsumer.h>
#include <clang/Frontend/Utils.h>
#include <clang/Driver/Util.h>
#include <clang/Index/USRGeneration.h>
#include <CodeGen/CodeGenModule.h>
#include <CodeGen/CodeGenTypes.h>
#include <CodeGen/TargetInfo.h>
@ -296,6 +297,15 @@ static std::string GetTagDeclName(const clang::TagDecl* D) @@ -296,6 +297,15 @@ static std::string GetTagDeclName(const clang::TagDecl* D)
return GetDeclName(D);
}
static std::string GetDeclUSR(const clang::Decl* D)
{
using namespace clang;
SmallString<8> usr;
if (!index::generateUSRForDecl(D, usr))
return usr.str();
return "<invalid>";
}
static clang::Decl* GetPreviousDeclInContext(const clang::Decl* D)
{
assert(!D->getLexicalDeclContext()->decls_empty());
@ -727,26 +737,32 @@ WalkTemplateSpecializationKind(clang::TemplateSpecializationKind Kind) @@ -727,26 +737,32 @@ WalkTemplateSpecializationKind(clang::TemplateSpecializationKind Kind)
ClassTemplateSpecialization*
Parser::WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl* CTS)
{
using namespace clang;
auto CT = WalkClassTemplate(CTS->getSpecializedTemplate());
auto Spec = CT->FindSpecialization(CTS);
if (Spec != nullptr)
return Spec;
auto USR = GetDeclUSR(CTS);
auto TS = CT->FindSpecialization(USR);
if (TS != nullptr)
return TS;
auto TS = new ClassTemplateSpecialization();
TS = new ClassTemplateSpecialization();
HandleDeclaration(CTS, TS);
TS->Name = CTS->getName();
auto NS = GetNamespace(CTS);
assert(NS && "Expected a valid namespace");
TS->_Namespace = NS;
TS->Name = CTS->getName();
TS->TemplatedDecl = CT;
TS->SpecializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind());
auto &TAL = CTS->getTemplateArgs();
if (auto TSI = CTS->getTypeAsWritten())
{
auto TL = TSI->getTypeLoc();
auto TSL = TL.getAs<TemplateSpecializationTypeLoc>();
TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL);
}
CT->Specializations.push_back(TS);
// TODO: Parse the template argument list
if (CTS->isCompleteDefinition())
WalkRecordCXX(CTS, TS);
@ -758,12 +774,15 @@ Parser::WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl* @@ -758,12 +774,15 @@ Parser::WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl*
ClassTemplatePartialSpecialization*
Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecializationDecl* CTS)
{
using namespace clang;
auto CT = WalkClassTemplate(CTS->getSpecializedTemplate());
auto Spec = CT->FindPartialSpecialization((void*) CTS);
if (Spec != nullptr)
return Spec;
auto USR = GetDeclUSR(CTS);
auto TS = CT->FindPartialSpecialization(USR);
if (TS != nullptr)
return TS;
auto TS = new ClassTemplatePartialSpecialization();
TS = new ClassTemplatePartialSpecialization();
HandleDeclaration(CTS, TS);
TS->Name = CTS->getName();
@ -774,10 +793,15 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia @@ -774,10 +793,15 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia
TS->TemplatedDecl = CT;
TS->SpecializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind());
auto &TAL = CTS->getTemplateArgs();
if (auto TSI = CTS->getTypeAsWritten())
{
auto TL = TSI->getTypeLoc();
auto TSL = TL.getAs<TemplateSpecializationTypeLoc>();
TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL);
}
CT->Specializations.push_back(TS);
// TODO: Parse the template argument list
if (CTS->isCompleteDefinition())
WalkRecordCXX(CTS, TS);
@ -786,57 +810,166 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia @@ -786,57 +810,166 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia
//-----------------------------------//
CppSharp::CppParser::TemplateParameter
WalkTemplateParameter(const clang::NamedDecl* D)
{
using namespace clang;
auto TP = CppSharp::CppParser::TemplateParameter();
if (D == nullptr)
return TP;
TP.Name = GetDeclName(D);
switch (D->getKind())
{
case Decl::TemplateTypeParm:
{
auto TTPD = cast<TemplateTypeParmDecl>(D);
TP.IsTypeParameter = true;
break;
}
default:
break;
}
return TP;
}
//-----------------------------------//
static std::vector<CppSharp::CppParser::TemplateParameter>
WalkTemplateParameterList(const clang::TemplateParameterList* TPL)
{
auto params = std::vector<CppSharp::CppParser::TemplateParameter>();
for (auto it = TPL->begin(); it != TPL->end(); ++it)
{
auto ND = *it;
auto TP = WalkTemplateParameter(ND);
params.push_back(TP);
}
return params;
}
//-----------------------------------//
ClassTemplate* Parser::WalkClassTemplate(clang::ClassTemplateDecl* TD)
{
auto NS = GetNamespace(TD);
assert(NS && "Expected a valid namespace");
auto CT = NS->FindClassTemplate((void*) TD);
auto USR = GetDeclUSR(TD);
auto CT = NS->FindClassTemplate(USR);
if (CT != nullptr)
return CT;
CT = new ClassTemplate();
HandleDeclaration(TD, CT);
CT->Name = GetDeclName(TD);
CT->_Namespace = NS;
NS->Templates.push_back(CT);
CT->TemplatedDecl = WalkRecordCXX(TD->getTemplatedDecl());
CT->Parameters = WalkTemplateParameterList(TD->getTemplateParameters());
auto TPL = TD->getTemplateParameters();
for(auto it = TPL->begin(); it != TPL->end(); ++it)
{
auto ND = *it;
return CT;
}
auto TP = TemplateParameter();
TP.Name = ND->getNameAsString();
//-----------------------------------//
std::vector<CppSharp::CppParser::TemplateArgument>
Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, clang::TemplateSpecializationTypeLoc* TSTL)
{
using namespace clang;
auto params = std::vector<CppSharp::CppParser::TemplateArgument>();
CT->Parameters.push_back(TP);
for (size_t i = 0, e = TAL->size(); i < e; i++)
{
auto TA = TAL->get(i);
auto ArgLoc = TSTL->getArgLoc(i);
auto Arg = WalkTemplateArgument(TA, &ArgLoc);
params.push_back(Arg);
}
return CT;
return params;
}
//-----------------------------------//
static std::vector<CppSharp::CppParser::TemplateParameter>
WalkTemplateParameterList(const clang::TemplateParameterList* TPL)
std::vector<CppSharp::CppParser::TemplateArgument>
Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TALI)
{
auto params = std::vector<CppSharp::CppParser::TemplateParameter>();
for(auto it = TPL->begin(); it != TPL->end(); ++it)
{
auto ND = *it;
using namespace clang;
auto TP = CppSharp::CppParser::TemplateParameter();
TP.Name = ND->getNameAsString();
auto params = std::vector<CppSharp::CppParser::TemplateArgument>();
for (size_t i = 0, e = TAL->size(); i < e; i++)
{
auto TA = TAL->get(i);
auto ArgLoc = TALI->operator[](i);
auto TP = WalkTemplateArgument(TA, &ArgLoc);
params.push_back(TP);
}
return params;
}
//-----------------------------------//
CppSharp::CppParser::TemplateArgument
Parser::WalkTemplateArgument(const clang::TemplateArgument& TA, clang::TemplateArgumentLoc* ArgLoc)
{
auto Arg = CppSharp::CppParser::TemplateArgument();
switch (TA.getKind())
{
case clang::TemplateArgument::Type:
{
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::Type;
if (ArgLoc)
{
auto ArgTL = ArgLoc->getTypeSourceInfo()->getTypeLoc();
Arg.Type = GetQualifiedType(TA.getAsType(), WalkType(TA.getAsType(), &ArgTL));
}
else
{
Arg.Type = GetQualifiedType(TA.getAsType(), WalkType(TA.getAsType()));
}
break;
}
case clang::TemplateArgument::Declaration:
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::Declaration;
Arg.Declaration = WalkDeclaration(TA.getAsDecl(), 0);
break;
case clang::TemplateArgument::NullPtr:
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::NullPtr;
break;
case clang::TemplateArgument::Integral:
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::Integral;
//Arg.Type = WalkType(TA.getIntegralType(), 0);
Arg.Integral = TA.getAsIntegral().getLimitedValue();
break;
case clang::TemplateArgument::Template:
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::Template;
break;
case clang::TemplateArgument::TemplateExpansion:
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::TemplateExpansion;
break;
case clang::TemplateArgument::Expression:
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::Expression;
break;
case clang::TemplateArgument::Pack:
Arg.Kind = CppSharp::CppParser::TemplateArgument::ArgumentKind::Pack;
break;
}
return Arg;
}
//-----------------------------------//
FunctionTemplate* Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD)
{
using namespace clang;
@ -844,32 +977,27 @@ FunctionTemplate* Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD) @@ -844,32 +977,27 @@ FunctionTemplate* Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD)
auto NS = GetNamespace(TD);
assert(NS && "Expected a valid namespace");
auto FT = NS->FindFunctionTemplate((void*)TD);
auto USR = GetDeclUSR(TD);
auto FT = NS->FindFunctionTemplate(USR);
if (FT != nullptr)
return FT;
auto Params = WalkTemplateParameterList(TD->getTemplateParameters());
CppSharp::CppParser::AST::Function* Function = nullptr;
auto TemplatedDecl = TD->getTemplatedDecl();
if (auto MD = dyn_cast<CXXMethodDecl>(TemplatedDecl))
Function = WalkMethodCXX(MD);
Function = WalkMethodCXX(MD, /*AddToClass=*/false);
else
Function = WalkFunction(TemplatedDecl, /*IsDependent=*/true,
/*AddToNamespace=*/false);
auto Name = TD->getNameAsString();
FT = NS->FindFunctionTemplate(Name, Params);
if (FT != nullptr && FT->TemplatedDecl == Function)
return FT;
FT = new FunctionTemplate();
HandleDeclaration(TD, FT);
FT->Name = GetDeclName(TD);
FT->_Namespace = NS;
FT->TemplatedDecl = Function;
FT->Parameters = Params;
FT->Parameters = WalkTemplateParameterList(TD->getTemplateParameters());
NS->Templates.push_back(FT);
@ -878,6 +1006,26 @@ FunctionTemplate* Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD) @@ -878,6 +1006,26 @@ FunctionTemplate* Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD)
//-----------------------------------//
CppSharp::CppParser::FunctionTemplateSpecialization*
Parser::WalkFunctionTemplateSpec(clang::FunctionTemplateSpecializationInfo* FTSI, CppSharp::CppParser::Function* Function)
{
using namespace clang;
auto FTS = new CppSharp::CppParser::FunctionTemplateSpecialization();
FTS->SpecializationKind = WalkTemplateSpecializationKind(FTSI->getTemplateSpecializationKind());
if (auto MD = dyn_cast<CXXMethodDecl>(FTSI->Function))
FTS->SpecializedFunction = Function;
else
FTS->SpecializedFunction = Function;
if (auto TALI = FTSI->TemplateArgumentsAsWritten)
FTS->Arguments = WalkTemplateArgumentList(FTSI->TemplateArguments, TALI);
FTS->Template = WalkFunctionTemplate(FTSI->getTemplate());
FTS->Template->Specializations.push_back(FTS);
return FTS;
}
//-----------------------------------//
static CXXMethodKind GetMethodKindFromDecl(clang::DeclarationName Name)
{
using namespace clang;
@ -921,13 +1069,13 @@ static CXXOperatorKind GetOperatorKindFromDecl(clang::DeclarationName Name) @@ -921,13 +1069,13 @@ static CXXOperatorKind GetOperatorKindFromDecl(clang::DeclarationName Name)
return CXXOperatorKind::None;
}
Method* Parser::WalkMethodCXX(clang::CXXMethodDecl* MD)
Method* Parser::WalkMethodCXX(clang::CXXMethodDecl* MD, bool AddToClass)
{
using namespace clang;
// We could be in a redeclaration, so process the primary context.
if (MD->getPrimaryContext() != MD)
return WalkMethodCXX(cast<CXXMethodDecl>(MD->getPrimaryContext()));
return WalkMethodCXX(cast<CXXMethodDecl>(MD->getPrimaryContext()), AddToClass);
auto RD = MD->getParent();
auto Decl = WalkDeclaration(RD, /*IgnoreSystemDecls=*/false);
@ -935,20 +1083,25 @@ Method* Parser::WalkMethodCXX(clang::CXXMethodDecl* MD) @@ -935,20 +1083,25 @@ Method* Parser::WalkMethodCXX(clang::CXXMethodDecl* MD)
auto Class = static_cast<CppSharp::CppParser::AST::Class*>(Decl);
// Check for an already existing method that came from the same declaration.
auto USR = GetDeclUSR(MD);
for (unsigned I = 0, E = Class->Methods.size(); I != E; ++I)
{
Method* Method = Class->Methods[I];
if (Method->OriginalPtr == MD)
return Method;
if (Method->USR == USR)
return Method;
}
for (unsigned I = 0, E = Class->Templates.size(); I != E; ++I)
{
Template* Template = Class->Templates[I];
if (Template->TemplatedDecl->USR == USR)
return static_cast<Method*>(Template->TemplatedDecl);
}
DeclarationName Name = MD->getDeclName();
Method* Method = new CppSharp::CppParser::Method();
auto Method = new CppSharp::CppParser::Method();
HandleDeclaration(MD, Method);
Method->Access = ConvertToAccess(MD->getAccess());
Method->MethodKind = GetMethodKindFromDecl(Name);
Method->MethodKind = GetMethodKindFromDecl(MD->getDeclName());
Method->IsStatic = MD->isStatic();
Method->IsVirtual = MD->isVirtual();
Method->IsConst = MD->isConst();
@ -974,7 +1127,8 @@ Method* Parser::WalkMethodCXX(clang::CXXMethodDecl* MD) @@ -974,7 +1127,8 @@ Method* Parser::WalkMethodCXX(clang::CXXMethodDecl* MD)
Method->ConversionType = GetQualifiedType(CD->getConversionType(), ConvTy);
}
Class->Methods.push_back(Method);
if (AddToClass)
Class->Methods.push_back(Method);
return Method;
}
@ -1539,69 +1693,26 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL, @@ -1539,69 +1693,26 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
if (TS->isSugared())
TST->Desugared = WalkType(TS->desugar());
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
auto UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
else if (TypeLocClass == TypeLoc::Elaborated)
if (!TL->isNull())
{
auto ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc();
TL = &ITL;
}
assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization);
auto TSTL = TL->getAs<TemplateSpecializationTypeLoc>();
for (unsigned I = 0, E = TS->getNumArgs(); I != E; ++I)
{
const clang::TemplateArgument& TA = TS->getArg(I);
auto Arg = TemplateArgument();
TemplateArgumentLoc ArgLoc;
ArgLoc = TSTL.getArgLoc(I);
switch(TA.getKind())
{
case clang::TemplateArgument::Type:
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
Arg.Kind = TemplateArgument::ArgumentKind::Type;
TypeLoc ArgTL;
ArgTL = ArgLoc.getTypeSourceInfo()->getTypeLoc();
Arg.Type = GetQualifiedType(TA.getAsType(),
WalkType(TA.getAsType(), &ArgTL));
break;
auto UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
case clang::TemplateArgument::Declaration:
Arg.Kind = TemplateArgument::ArgumentKind::Declaration;
Arg.Declaration = WalkDeclaration(TA.getAsDecl(), 0);
break;
case clang::TemplateArgument::NullPtr:
Arg.Kind = TemplateArgument::ArgumentKind::NullPtr;
break;
case clang::TemplateArgument::Integral:
Arg.Kind = TemplateArgument::ArgumentKind::Integral;
//Arg.Type = WalkType(TA.getIntegralType(), 0);
Arg.Integral = TA.getAsIntegral().getLimitedValue();
break;
case clang::TemplateArgument::Template:
Arg.Kind = TemplateArgument::ArgumentKind::Template;
break;
case clang::TemplateArgument::TemplateExpansion:
Arg.Kind = TemplateArgument::ArgumentKind::TemplateExpansion;
break;
case clang::TemplateArgument::Expression:
Arg.Kind = TemplateArgument::ArgumentKind::Expression;
break;
case clang::TemplateArgument::Pack:
Arg.Kind = TemplateArgument::ArgumentKind::Pack;
break;
else if (TypeLocClass == TypeLoc::Elaborated)
{
auto ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc();
TL = &ITL;
}
TST->Arguments.push_back(Arg);
assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization);
auto TSTL = TL->getAs<TemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(
&TemplateArgumentList(TemplateArgumentList::OnStack, TS->getArgs(), TS->getNumArgs()),
&TSTL);
}
Ty = TST;
@ -1611,10 +1722,33 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL, @@ -1611,10 +1722,33 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
{
auto TP = Type->getAs<TemplateTypeParmType>();
auto TPT = new TemplateParameterType();
auto TPT = new CppSharp::CppParser::TemplateParameterType();
if (auto Ident = TP->getIdentifier())
TPT->Parameter.Name = Ident->getName();
if (!TL->isNull())
{
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
auto UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
else if (TypeLocClass == TypeLoc::Elaborated)
{
auto ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc();
TL = &ITL;
}
assert(TL->getTypeLocClass() == TypeLoc::TemplateTypeParm);
auto TTTL = TL->getAs<TemplateTypeParmTypeLoc>();
TPT->Parameter = WalkTemplateParameter(TTTL.getDecl());
}
TPT->Depth = TP->getDepth();
TPT->Index = TP->getIndex();
TPT->IsParameterPack = TP->isParameterPack();
Ty = TPT;
break;
@ -1965,6 +2099,9 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F, @@ -1965,6 +2099,9 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F,
F->Parameters[Index++]->IsIndirect = I->info.isIndirect();
}
}
if (auto FTSI = FD->getTemplateSpecializationInfo())
F->SpecializationInfo = WalkFunctionTemplateSpec(FTSI, F);
}
Function* Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDependent,
@ -1977,9 +2114,8 @@ Function* Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDependent, @@ -1977,9 +2114,8 @@ Function* Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDependent,
auto NS = GetNamespace(FD);
assert(NS && "Expected a valid namespace");
auto Name = FD->getNameAsString();
Function* F = NS->FindFunction(Name, /*Create=*/ false);
auto USR = GetDeclUSR(FD);
auto F = NS->FindFunction(USR);
if (F != nullptr)
return F;
@ -2233,6 +2369,7 @@ void Parser::HandleDeclaration(clang::Decl* D, Declaration* Decl) @@ -2233,6 +2369,7 @@ void Parser::HandleDeclaration(clang::Decl* D, Declaration* Decl)
return;
Decl->OriginalPtr = (void*) D;
Decl->USR = GetDeclUSR(D);
if (Decl->PreprocessedEntities.empty() && !D->isImplicit())
{

6
src/CppParser/Parser.h

@ -75,14 +75,18 @@ protected: @@ -75,14 +75,18 @@ protected:
WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl* CTS);
ClassTemplatePartialSpecialization*
WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecializationDecl* CTS);
Method* WalkMethodCXX(clang::CXXMethodDecl* MD);
Method* WalkMethodCXX(clang::CXXMethodDecl* MD, bool AddToClass = true);
Field* WalkFieldCXX(clang::FieldDecl* FD, Class* Class);
ClassTemplate* WalkClassTemplate(clang::ClassTemplateDecl* TD);
FunctionTemplate* WalkFunctionTemplate(clang::FunctionTemplateDecl* TD);
FunctionTemplateSpecialization* WalkFunctionTemplateSpec(clang::FunctionTemplateSpecializationInfo* FTS, Function* Function);
Variable* WalkVariable(clang::VarDecl* VD);
RawComment* WalkRawComment(const clang::RawComment* RC);
Type* WalkType(clang::QualType QualType, clang::TypeLoc* TL = 0,
bool DesugarType = false);
TemplateArgument WalkTemplateArgument(const clang::TemplateArgument& TA, clang::TemplateArgumentLoc* ArgLoc);
std::vector<TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, clang::TemplateSpecializationTypeLoc* TSTL);
std::vector<TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL);
void WalkVTable(clang::CXXRecordDecl* RD, Class* C);
VTableLayout WalkVTableLayout(const clang::VTableLayout& VTLayout);
VTableComponent WalkVTableComponent(const clang::VTableComponent& Component);

59
src/Generator.Tests/AST/TestAST.cs

@ -19,7 +19,7 @@ namespace CppSharp.Generator.Tests.AST @@ -19,7 +19,7 @@ namespace CppSharp.Generator.Tests.AST
[SetUp]
public void Setup()
{
ParseLibrary("AST.h");
ParseLibrary("AST.h", "ASTExtensions.h");
passBuilder = new PassBuilder<TranslationUnitPass>(Driver);
}
@ -168,5 +168,62 @@ namespace CppSharp.Generator.Tests.AST @@ -168,5 +168,62 @@ namespace CppSharp.Generator.Tests.AST
Assert.NotNull(@enum);
Assert.IsTrue(@enum.ItemsByName.ContainsKey("TestItemByName"));
}
[Test]
public void TestASTFunctionTemplates()
{
var @class = AstContext.FindClass("TestTemplateFunctions").FirstOrDefault();
Assert.IsNotNull(@class, "Couldn't find TestTemplateFunctions class.");
Assert.AreEqual(6, @class.Templates.Count);
var twoParamMethodTemplate = @class.Templates.OfType<FunctionTemplate>()
.FirstOrDefault(t => t.Name == "MethodTemplateWithTwoTypeParameter");
Assert.IsNotNull(twoParamMethodTemplate);
Assert.AreEqual(2, twoParamMethodTemplate.Parameters.Count);
Assert.AreEqual("T", twoParamMethodTemplate.Parameters[0].Name);
Assert.AreEqual("S", twoParamMethodTemplate.Parameters[1].Name);
Assert.IsTrue(twoParamMethodTemplate.Parameters[0].IsTypeParameter);
Assert.IsTrue(twoParamMethodTemplate.Parameters[1].IsTypeParameter);
var twoParamMethod = twoParamMethodTemplate.TemplatedFunction as Method;
Assert.IsNotNull(twoParamMethod);
Assert.IsInstanceOf<TemplateParameterType>(twoParamMethod.Parameters[0].Type);
Assert.IsInstanceOf<TemplateParameterType>(twoParamMethod.Parameters[1].Type);
Assert.AreEqual(twoParamMethodTemplate.Parameters[0],
((TemplateParameterType)twoParamMethod.Parameters[0].Type).Parameter);
Assert.AreEqual(twoParamMethodTemplate.Parameters[1],
((TemplateParameterType)twoParamMethod.Parameters[1].Type).Parameter);
Assert.AreEqual(0, ((TemplateParameterType)twoParamMethod.Parameters[0].Type).Index);
Assert.AreEqual(1, ((TemplateParameterType)twoParamMethod.Parameters[1].Type).Index);
}
[Test]
public void TestASTClassTemplates()
{
var template = AstContext.TranslationUnits
.SelectMany(u => u.Templates.OfType<ClassTemplate>())
.FirstOrDefault(t => t.Name == "TestTemplateClass");
Assert.IsNotNull(template, "Couldn't find TestTemplateClass class.");
Assert.AreEqual(1, template.Parameters.Count);
var templateTypeParameter = template.Parameters[0];
Assert.AreEqual("T", templateTypeParameter.Name);
var ctor = template.TemplatedClass.Constructors
.FirstOrDefault(c => c.Parameters.Count == 1 && c.Parameters[0].Name == "v");
Assert.IsNotNull(ctor);
var paramType = ctor.Parameters[0].Type as TemplateParameterType;
Assert.IsNotNull(paramType);
Assert.AreEqual(templateTypeParameter, paramType.Parameter);
Assert.AreEqual(3, template.Specializations.Count);
Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[0].SpecializationKind);
Assert.AreEqual(TemplateSpecializationKind.ExplicitInstantiationDefinition, template.Specializations[1].SpecializationKind);
Assert.AreEqual(TemplateSpecializationKind.Undeclared, template.Specializations[2].SpecializationKind);
var typeDef = AstContext.FindTypedef("TestTemplateClassInt").FirstOrDefault();
Assert.IsNotNull(typeDef, "Couldn't find TestTemplateClassInt typedef.");
var integerInst = typeDef.Type as TemplateSpecializationType;
Assert.AreEqual(1, integerInst.Arguments.Count);
var intArgument = integerInst.Arguments[0];
Assert.AreEqual(new BuiltinType(PrimitiveType.Int32), intArgument.Type.Type);
Class classTemplate;
Assert.IsTrue(typeDef.Type.TryGetClass(out classTemplate));
Assert.AreEqual(classTemplate, template.TemplatedClass);
}
}
}

4
src/Generator.Tests/ASTTestFixture.cs

@ -10,7 +10,7 @@ namespace CppSharp.Generator.Tests @@ -10,7 +10,7 @@ namespace CppSharp.Generator.Tests
protected DriverOptions Options;
protected ASTContext AstContext;
protected void ParseLibrary(string file)
protected void ParseLibrary(params string[] files)
{
Options = new DriverOptions();
@ -22,7 +22,7 @@ namespace CppSharp.Generator.Tests @@ -22,7 +22,7 @@ namespace CppSharp.Generator.Tests
Options.addIncludeDirs(testsPath);
#endif
Options.Headers.Add(file);
Options.Headers.AddRange(files);
Driver = new Driver(Options, new TextDiagnosticPrinter());
if (!Driver.ParseCode())

375
src/Parser/Parser.cpp

@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
#include <clang/Sema/SemaConsumer.h>
#include <clang/Frontend/Utils.h>
#include <clang/Driver/Util.h>
#include <clang/Index/USRGeneration.h>
#include <CodeGen/CodeGenModule.h>
#include <CodeGen/CodeGenTypes.h>
#include <CodeGen/TargetInfo.h>
@ -292,6 +293,15 @@ static std::string GetTagDeclName(const clang::TagDecl* D) @@ -292,6 +293,15 @@ static std::string GetTagDeclName(const clang::TagDecl* D)
return GetDeclName(D);
}
static std::string GetDeclUSR(const clang::Decl* D)
{
using namespace clang;
SmallString<8> usr;
if (!index::generateUSRForDecl(D, usr))
return usr.str();
return "<invalid>";
}
static clang::Decl* GetPreviousDeclInContext(const clang::Decl* D)
{
assert(!D->getLexicalDeclContext()->decls_empty());
@ -725,26 +735,33 @@ WalkTemplateSpecializationKind(clang::TemplateSpecializationKind Kind) @@ -725,26 +735,33 @@ WalkTemplateSpecializationKind(clang::TemplateSpecializationKind Kind)
CppSharp::AST::ClassTemplateSpecialization^
Parser::WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl* CTS)
{
using namespace clang;
using namespace clix;
auto CT = WalkClassTemplate(CTS->getSpecializedTemplate());
auto Spec = CT->FindSpecialization(System::IntPtr(CTS));
if (Spec != nullptr)
return Spec;
auto USR = marshalString<Encoding::E_UTF8>(GetDeclUSR(CTS));
auto TS = CT->FindSpecializationByUSR(USR);
if (TS != nullptr)
return TS;
auto TS = gcnew CppSharp::AST::ClassTemplateSpecialization();
TS = gcnew CppSharp::AST::ClassTemplateSpecialization();
HandleDeclaration(CTS, TS);
TS->Name = clix::marshalString<clix::E_UTF8>(CTS->getName());
auto NS = GetNamespace(CTS);
assert(NS && "Expected a valid namespace");
TS->Namespace = NS;
TS->Name = clix::marshalString<clix::E_UTF8>(GetDeclName(CTS));
TS->TemplatedDecl = CT;
TS->SpecializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind());
auto &TAL = CTS->getTemplateArgs();
if (auto TSI = CTS->getTypeAsWritten())
{
auto TL = TSI->getTypeLoc();
auto TSL = TL.getAs<TemplateSpecializationTypeLoc>();
TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL);
}
CT->Specializations->Add(TS);
// TODO: Parse the template argument list
if (CTS->isCompleteDefinition())
WalkRecordCXX(CTS, TS);
@ -756,15 +773,19 @@ Parser::WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl* @@ -756,15 +773,19 @@ Parser::WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl*
CppSharp::AST::ClassTemplatePartialSpecialization^
Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecializationDecl* CTS)
{
using namespace clang;
using namespace clix;
auto CT = WalkClassTemplate(CTS->getSpecializedTemplate());
auto Spec = CT->FindPartialSpecialization(System::IntPtr(CTS));
if (Spec != nullptr)
return Spec;
auto USR = marshalString<Encoding::E_UTF8>(GetDeclUSR(CTS));
auto TS = CT->FindPartialSpecializationByUSR(USR);
if (TS != nullptr)
return TS;
auto TS = gcnew CppSharp::AST::ClassTemplatePartialSpecialization();
TS = gcnew CppSharp::AST::ClassTemplatePartialSpecialization();
HandleDeclaration(CTS, TS);
TS->Name = clix::marshalString<clix::E_UTF8>(CTS->getName());
TS->Name = clix::marshalString<clix::E_UTF8>(GetDeclName(CTS));
auto NS = GetNamespace(CTS);
assert(NS && "Expected a valid namespace");
@ -772,10 +793,15 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia @@ -772,10 +793,15 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia
TS->TemplatedDecl = CT;
TS->SpecializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind());
auto &TAL = CTS->getTemplateArgs();
if (auto TSI = CTS->getTypeAsWritten())
{
auto TL = TSI->getTypeLoc();
auto TSL = TL.getAs<TemplateSpecializationTypeLoc>();
TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL);
}
CT->Specializations->Add(TS);
// TODO: Parse the template argument list
if (CTS->isCompleteDefinition())
WalkRecordCXX(CTS, TS);
@ -784,6 +810,52 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia @@ -784,6 +810,52 @@ Parser::WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecia
//-----------------------------------//
CppSharp::AST::TemplateParameter
WalkTemplateParameter(const clang::NamedDecl* D)
{
using namespace clang;
using namespace clix;
auto TP = CppSharp::AST::TemplateParameter();
if (D == nullptr)
return TP;
TP.Name = marshalString<E_UTF8>(GetDeclName(D));
switch (D->getKind())
{
case Decl::TemplateTypeParm:
{
auto TTPD = cast<TemplateTypeParmDecl>(D);
TP.IsTypeParameter = true;
break;
}
default:
break;
}
return TP;
}
//-----------------------------------//
static List<CppSharp::AST::TemplateParameter>^
WalkTemplateParameterList(const clang::TemplateParameterList* TPL)
{
using namespace clang;
auto params = gcnew List<CppSharp::AST::TemplateParameter>();
for (auto it = TPL->begin(); it != TPL->end(); ++it)
{
auto ND = *it;
auto TP = WalkTemplateParameter(ND);
params->Add(TP);
}
return params;
}
//-----------------------------------//
CppSharp::AST::ClassTemplate^ Parser::WalkClassTemplate(clang::ClassTemplateDecl* TD)
{
using namespace clang;
@ -792,52 +864,121 @@ CppSharp::AST::ClassTemplate^ Parser::WalkClassTemplate(clang::ClassTemplateDecl @@ -792,52 +864,121 @@ CppSharp::AST::ClassTemplate^ Parser::WalkClassTemplate(clang::ClassTemplateDecl
auto NS = GetNamespace(TD);
assert(NS && "Expected a valid namespace");
auto CT = NS->FindClassTemplate(System::IntPtr(TD));
auto USR = marshalString<Encoding::E_UTF8>(GetDeclUSR(TD));
auto CT = NS->FindClassTemplateByUSR(USR);
if (CT != nullptr)
return CT;
CT = gcnew CppSharp::AST::ClassTemplate();
HandleDeclaration(TD, CT);
CT->Name = marshalString<E_UTF8>(GetDeclName(TD));
CT->Namespace = NS;
NS->Templates->Add(CT);
CT->TemplatedDecl = WalkRecordCXX(TD->getTemplatedDecl());
CT->Parameters = WalkTemplateParameterList(TD->getTemplateParameters());
auto TPL = TD->getTemplateParameters();
for(auto it = TPL->begin(); it != TPL->end(); ++it)
{
auto ND = *it;
return CT;
}
auto TP = CppSharp::AST::TemplateParameter();
TP.Name = clix::marshalString<clix::E_UTF8>(ND->getNameAsString());
//-----------------------------------//
List<CppSharp::AST::TemplateArgument>^
Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, clang::TemplateSpecializationTypeLoc* TSTL)
{
using namespace clang;
auto params = gcnew List<CppSharp::AST::TemplateArgument>();
CT->Parameters->Add(TP);
for (size_t i = 0, e = TAL->size(); i < e; i++)
{
auto TA = TAL->get(i);
auto ArgLoc = TSTL->getArgLoc(i);
auto TP = WalkTemplateArgument(TA, &ArgLoc);
params->Add(TP);
}
return CT;
return params;
}
//-----------------------------------//
static List<CppSharp::AST::TemplateParameter>^
WalkTemplateParameterList(const clang::TemplateParameterList* TPL)
List<CppSharp::AST::TemplateArgument>^
Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TALI)
{
auto params = gcnew List<CppSharp::AST::TemplateParameter>();
for(auto it = TPL->begin(); it != TPL->end(); ++it)
{
auto ND = *it;
using namespace clang;
auto TP = CppSharp::AST::TemplateParameter();
TP.Name = clix::marshalString<clix::E_UTF8>(ND->getNameAsString());
auto params = gcnew List<CppSharp::AST::TemplateArgument>();
for (size_t i = 0, e = TAL->size(); i < e; i++)
{
auto TA = TAL->get(i);
auto ArgLoc = TALI->operator[](i);
auto TP = WalkTemplateArgument(TA, &ArgLoc);
params->Add(TP);
}
return params;
}
//-----------------------------------//
CppSharp::AST::TemplateArgument
Parser::WalkTemplateArgument(const clang::TemplateArgument& TA, clang::TemplateArgumentLoc* ArgLoc)
{
using namespace clang;
using namespace clix;
auto Arg = CppSharp::AST::TemplateArgument();
switch (TA.getKind())
{
case TemplateArgument::Type:
{
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Type;
if (ArgLoc)
{
auto ArgTL = ArgLoc->getTypeSourceInfo()->getTypeLoc();
Arg.Type = GetQualifiedType(TA.getAsType(), WalkType(TA.getAsType(), &ArgTL));
}
else
{
Arg.Type = GetQualifiedType(TA.getAsType(), WalkType(TA.getAsType()));
}
break;
}
case TemplateArgument::Declaration:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Declaration;
Arg.Declaration = WalkDeclaration(TA.getAsDecl(), 0);
break;
case TemplateArgument::NullPtr:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::NullPtr;
break;
case TemplateArgument::Integral:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Integral;
//Arg.Type = WalkType(TA.getIntegralType(), 0);
Arg.Integral = TA.getAsIntegral().getLimitedValue();
break;
case TemplateArgument::Template:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Template;
break;
case TemplateArgument::TemplateExpansion:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::TemplateExpansion;
break;
case TemplateArgument::Expression:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Expression;
break;
case TemplateArgument::Pack:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Pack;
break;
}
return Arg;
}
//-----------------------------------//
CppSharp::AST::FunctionTemplate^
Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD)
{
@ -847,32 +988,27 @@ Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD) @@ -847,32 +988,27 @@ Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD)
auto NS = GetNamespace(TD);
assert(NS && "Expected a valid namespace");
auto FT = NS->FindFunctionTemplate(System::IntPtr(TD));
auto USR = marshalString<Encoding::E_UTF8>(GetDeclUSR(TD));
auto FT = NS->FindFunctionTemplateByUSR(USR);
if (FT != nullptr)
return FT;
auto Params = WalkTemplateParameterList(TD->getTemplateParameters());
CppSharp::AST::Function^ Function = nullptr;
auto TemplatedDecl = TD->getTemplatedDecl();
if (auto MD = dyn_cast<CXXMethodDecl>(TemplatedDecl))
Function = WalkMethodCXX(MD);
Function = WalkMethodCXX(MD, /*AddToClass=*/false);
else
Function = WalkFunction(TemplatedDecl, /*IsDependent=*/true,
/*AddToNamespace=*/false);
auto Name = clix::marshalString<clix::E_UTF8>(TD->getNameAsString());
FT = NS->FindFunctionTemplate(Name, Params);
if (FT != nullptr && FT->TemplatedDecl == Function)
return FT;
/*AddToNamespace=*/false);
FT = gcnew CppSharp::AST::FunctionTemplate(Function);
HandleDeclaration(TD, FT);
FT->Name = marshalString<E_UTF8>(GetDeclName(TD));
FT->Namespace = NS;
FT->TemplatedDecl = Function;
FT->Parameters = Params;
FT->Parameters = WalkTemplateParameterList(TD->getTemplateParameters());
NS->Templates->Add(FT);
@ -881,6 +1017,27 @@ Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD) @@ -881,6 +1017,27 @@ Parser::WalkFunctionTemplate(clang::FunctionTemplateDecl* TD)
//-----------------------------------//
CppSharp::AST::FunctionTemplateSpecialization^
Parser::WalkFunctionTemplateSpec(clang::FunctionTemplateSpecializationInfo* FTSI, CppSharp::AST::Function^ Function)
{
using namespace clang;
auto FTS = gcnew CppSharp::AST::FunctionTemplateSpecialization();
FTS->SpecializationKind = WalkTemplateSpecializationKind(FTSI->getTemplateSpecializationKind());
if (auto MD = dyn_cast<CXXMethodDecl>(FTSI->Function))
FTS->SpecializedFunction = Function;
else
FTS->SpecializedFunction = Function;
if (auto TALI = FTSI->TemplateArgumentsAsWritten)
FTS->Arguments = WalkTemplateArgumentList(FTSI->TemplateArguments, TALI);
FTS->Template = WalkFunctionTemplate(FTSI->getTemplate());
FTS->Template->Specializations->Add(FTS);
return FTS;
}
//-----------------------------------//
static CppSharp::AST::CXXMethodKind GetMethodKindFromDecl(clang::DeclarationName Name)
{
using namespace clang;
@ -924,13 +1081,14 @@ static CppSharp::AST::CXXOperatorKind GetOperatorKindFromDecl(clang::Declaration @@ -924,13 +1081,14 @@ static CppSharp::AST::CXXOperatorKind GetOperatorKindFromDecl(clang::Declaration
return CppSharp::AST::CXXOperatorKind::None;
}
CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD)
CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD, bool AddToClass)
{
using namespace clang;
using namespace clix;
// We could be in a redeclaration, so process the primary context.
if (MD->getPrimaryContext() != MD)
return WalkMethodCXX(cast<CXXMethodDecl>(MD->getPrimaryContext()));
return WalkMethodCXX(cast<CXXMethodDecl>(MD->getPrimaryContext()), AddToClass);
auto RD = MD->getParent();
auto Decl = WalkDeclaration(RD, /*IgnoreSystemDecls=*/false);
@ -938,15 +1096,12 @@ CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD) @@ -938,15 +1096,12 @@ CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD)
auto Class = safe_cast<CppSharp::AST::Class^>(Decl);
// Check for an already existing method that came from the same declaration.
for each (CppSharp::AST::Method^ Method in Class->Methods)
{
if (Method->OriginalPtr.ToPointer() == MD)
return Method;
}
DeclarationName Name = MD->getDeclName();
auto USR = marshalString<Encoding::E_UTF8>(GetDeclUSR(MD));
auto Method = Class->FindMethodByUSR(USR);
if (Method != nullptr)
return Method;
CppSharp::AST::Method^ Method = gcnew CppSharp::AST::Method();
Method = gcnew CppSharp::AST::Method();
HandleDeclaration(MD, Method);
Method->Access = ConvertToAccess(MD->getAccess());
@ -957,7 +1112,7 @@ CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD) @@ -957,7 +1112,7 @@ CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD)
WalkFunction(MD, Method);
Method->Kind = GetMethodKindFromDecl(Name);
Method->Kind = GetMethodKindFromDecl(MD->getDeclName());
if (const CXXConstructorDecl* CD = dyn_cast<CXXConstructorDecl>(MD))
{
@ -977,7 +1132,8 @@ CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD) @@ -977,7 +1132,8 @@ CppSharp::AST::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* MD)
Method->ConversionType = GetQualifiedType(CD->getConversionType(), ConvTy);
}
Class->Methods->Add(Method);
if (AddToClass)
Class->Methods->Add(Method);
return Method;
}
@ -1555,69 +1711,26 @@ CppSharp::AST::Type^ Parser::WalkType(clang::QualType QualType, clang::TypeLoc* @@ -1555,69 +1711,26 @@ CppSharp::AST::Type^ Parser::WalkType(clang::QualType QualType, clang::TypeLoc*
if (TS->isSugared())
TST->Desugared = WalkType(TS->desugar());
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
auto UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
else if (TypeLocClass == TypeLoc::Elaborated)
{
auto ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc();
TL = &ITL;
}
assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization);
auto TSTL = TL->getAs<TemplateSpecializationTypeLoc>();
for (unsigned I = 0, E = TS->getNumArgs(); I != E; ++I)
if (!TL->isNull())
{
const TemplateArgument& TA = TS->getArg(I);
auto Arg = CppSharp::AST::TemplateArgument();
TemplateArgumentLoc ArgLoc;
ArgLoc = TSTL.getArgLoc(I);
switch(TA.getKind())
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
case TemplateArgument::Type:
{
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Type;
TypeLoc ArgTL;
ArgTL = ArgLoc.getTypeSourceInfo()->getTypeLoc();
Arg.Type = GetQualifiedType(TA.getAsType(),
WalkType(TA.getAsType(), &ArgTL));
break;
auto UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
case TemplateArgument::Declaration:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Declaration;
Arg.Declaration = WalkDeclaration(TA.getAsDecl(), 0);
break;
case TemplateArgument::NullPtr:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::NullPtr;
break;
case TemplateArgument::Integral:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Integral;
//Arg.Type = WalkType(TA.getIntegralType(), 0);
Arg.Integral = TA.getAsIntegral().getLimitedValue();
break;
case TemplateArgument::Template:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Template;
break;
case TemplateArgument::TemplateExpansion:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::TemplateExpansion;
break;
case TemplateArgument::Expression:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Expression;
break;
case TemplateArgument::Pack:
Arg.Kind = CppSharp::AST::TemplateArgument::ArgumentKind::Pack;
break;
else if (TypeLocClass == TypeLoc::Elaborated)
{
auto ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc();
TL = &ITL;
}
TST->Arguments->Add(Arg);
assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization);
auto TSTL = TL->getAs<TemplateSpecializationTypeLoc>();
TST->Arguments = WalkTemplateArgumentList(
&TemplateArgumentList(TemplateArgumentList::OnStack, TS->getArgs(), TS->getNumArgs()),
&TSTL);
}
Ty = TST;
@ -1631,6 +1744,29 @@ CppSharp::AST::Type^ Parser::WalkType(clang::QualType QualType, clang::TypeLoc* @@ -1631,6 +1744,29 @@ CppSharp::AST::Type^ Parser::WalkType(clang::QualType QualType, clang::TypeLoc*
if (auto Ident = TP->getIdentifier())
TPT->Parameter.Name = marshalString<E_UTF8>(Ident->getName());
if (!TL->isNull())
{
auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified)
{
auto UTL = TL->getUnqualifiedLoc();
TL = &UTL;
}
else if (TypeLocClass == TypeLoc::Elaborated)
{
auto ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc();
TL = &ITL;
}
assert(TL->getTypeLocClass() == TypeLoc::TemplateTypeParm);
auto TTTL = TL->getAs<TemplateTypeParmTypeLoc>();
TPT->Parameter = WalkTemplateParameter(TTTL.getDecl());
}
TPT->Depth = TP->getDepth();
TPT->Index = TP->getIndex();
TPT->IsParameterPack = TP->isParameterPack();
Ty = TPT;
break;
@ -1983,6 +2119,9 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F, @@ -1983,6 +2119,9 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F,
F->Parameters[Index++]->IsIndirect = I->info.isIndirect();
}
}
if (auto FTSI = FD->getTemplateSpecializationInfo())
F->SpecializationInfo = WalkFunctionTemplateSpec(FTSI, F);
}
CppSharp::AST::Function^ Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDependent,
@ -1996,9 +2135,8 @@ CppSharp::AST::Function^ Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDe @@ -1996,9 +2135,8 @@ CppSharp::AST::Function^ Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDe
auto NS = GetNamespace(FD);
assert(NS && "Expected a valid namespace");
auto Name = marshalString<E_UTF8>(FD->getNameAsString());
CppSharp::AST::Function^ F = NS->FindFunction(Name, /*Create=*/ false);
auto USR = marshalString<Encoding::E_UTF8>(GetDeclUSR(FD));
auto F = NS->FindFunctionByUSR(USR);
if (F != nullptr)
return F;
@ -2254,6 +2392,7 @@ void Parser::HandleDeclaration(clang::Decl* D, CppSharp::AST::Declaration^ Decl) @@ -2254,6 +2392,7 @@ void Parser::HandleDeclaration(clang::Decl* D, CppSharp::AST::Declaration^ Decl)
return;
Decl->OriginalPtr = System::IntPtr(D);
Decl->USR = clix::marshalString<clix::Encoding::E_UTF8>(GetDeclUSR(D));
if (Decl->PreprocessedEntities->Count == 0 && !D->isImplicit())
{

6
src/Parser/Parser.h

@ -73,15 +73,19 @@ protected: @@ -73,15 +73,19 @@ protected:
WalkClassTemplateSpecialization(clang::ClassTemplateSpecializationDecl* CTS);
CppSharp::AST::ClassTemplatePartialSpecialization^
WalkClassTemplatePartialSpecialization(clang::ClassTemplatePartialSpecializationDecl* CTS);
CppSharp::AST::Method^ WalkMethodCXX(clang::CXXMethodDecl* MD);
CppSharp::AST::Method^ WalkMethodCXX(clang::CXXMethodDecl* MD, bool AddToClass = true);
CppSharp::AST::Field^ WalkFieldCXX(clang::FieldDecl* FD, CppSharp::AST::Class^ Class);
CppSharp::AST::ClassTemplate^ Parser::WalkClassTemplate(clang::ClassTemplateDecl* TD);
CppSharp::AST::FunctionTemplate^ Parser::WalkFunctionTemplate(
clang::FunctionTemplateDecl* TD);
CppSharp::AST::FunctionTemplateSpecialization^ WalkFunctionTemplateSpec(clang::FunctionTemplateSpecializationInfo* FTS, CppSharp::AST::Function^ Function);
CppSharp::AST::Variable^ WalkVariable(clang::VarDecl* VD);
CppSharp::AST::RawComment^ WalkRawComment(const clang::RawComment* RC);
CppSharp::AST::Type^ WalkType(clang::QualType QualType, clang::TypeLoc* TL = 0,
bool DesugarType = false);
CppSharp::AST::TemplateArgument WalkTemplateArgument(const clang::TemplateArgument& TA, clang::TemplateArgumentLoc* ArgLoc);
List<CppSharp::AST::TemplateArgument>^ WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, clang::TemplateSpecializationTypeLoc* TSTL);
List<CppSharp::AST::TemplateArgument>^ WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL);
CppSharp::AST::QualifiedType^ WalkQualifiedType(clang::TypeSourceInfo* TSI);
void WalkVTable(clang::CXXRecordDecl* RD, CppSharp::AST::Class^ C);
CppSharp::AST::VTableLayout^ WalkVTableLayout(const clang::VTableLayout& VTLayout);

36
tests/Native/AST.h

@ -22,4 +22,38 @@ namespace Math @@ -22,4 +22,38 @@ namespace Math
}
// Tests Enum.ItemByName
enum TestASTEnumItemByName { TestItemByName };
enum TestASTEnumItemByName { TestItemByName };
// Tests class templates
template<typename T>
class TestTemplateClass
{
public:
TestTemplateClass(T v);
T Identity(T x);
T value;
};
// Tests function templates
class TestTemplateFunctions
{
public:
template<typename T> T Identity(T x) { return x; }
template<int N> void Ignore() { };
template<typename T, typename S> void MethodTemplateWithTwoTypeParameter(T t, S s) { };
template<typename T> void Ignore(TestTemplateClass<T> v) { };
template<typename T> T Valid(TestTemplateClass<int> v, T x) { return x; };
template<typename T> T& Valid(TestTemplateClass<int> v, T x) const { return x; }
};
// Explicit instantiation
template class TestTemplateClass<int>;
// Implicit instantiation
typedef TestTemplateClass<int> TestTemplateClassInt;
// Now use the typedef
class TestTemplateClass2
{
public:
TestTemplateClassInt* CreateIntTemplate();
};

9
tests/Native/ASTExtensions.h

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
#include "AST.h"
#include <vector>
// Tests class templates accross translation units
// Explicit instantiation
template class TestTemplateClass<Math::Complex>;
// Implicit instantiations
typedef TestTemplateClass<Math::Complex> TestTemplateClassComplex;
typedef TestTemplateClass<std::vector<Math::Complex>> TestTemplateClassMoreComplex;
Loading…
Cancel
Save