/************************************************************************ * * CppSharp * Licensed under the MIT license. * ************************************************************************/ #include "AST.h" #include #include #include #include // copy from widenPath ('llvm/lib/Support/Windows/Path.inc') static std::string normalizePath(const std::string& File) { llvm::SmallString<2 * 128> Result; for (llvm::sys::path::const_iterator I = llvm::sys::path::begin(File), E = llvm::sys::path::end(File); I != E; ++I) { if (I->size() == 1 && *I == ".") continue; if (I->size() == 2 && *I == "..") llvm::sys::path::remove_filename(Result); else llvm::sys::path::append(Result, *I); } #ifdef _WIN32 // Clean up the file path. std::replace(Result.begin(), Result.end(), '/', '\\'); #endif return Result.c_str(); } template static std::vector split(const T& str, const T& delimiters) { std::vector v; if (str.length() == 0) { v.push_back(str); return v; } typename T::size_type start = 0; auto pos = str.find_first_of(delimiters, start); while (pos != T::npos) { if (pos != start) // ignore empty tokens v.emplace_back(str, start, pos - start); start = pos + 1; pos = str.find_first_of(delimiters, start); } if (start < str.length()) // ignore trailing delimiter // add what's left of the string v.emplace_back(str, start, str.length() - start); return v; } namespace CppSharp { namespace CppParser { namespace AST { static void deleteExpression(ExpressionObsolete* expression) { if (expression) { // HACK: see https://github.com/mono/CppSharp/issues/598 switch (expression->_class) { case StatementClassObsolete::BinaryOperator: delete static_cast(expression); break; case StatementClassObsolete::CallExprClass: delete static_cast(expression); break; case StatementClassObsolete::CXXConstructExprClass: delete static_cast(expression); break; default: delete expression; break; } } } Type::Type(TypeKind kind) : kind(kind) { } Type::Type(const Type& rhs) : kind(rhs.kind) , isDependent(rhs.isDependent) { } QualifiedType::QualifiedType() : type(0) { } TagType::TagType() : Type(TypeKind::Tag) { } ArrayType::ArrayType() : Type(TypeKind::Array) , size(0) , elementSize(0) { } FunctionType::FunctionType() : Type(TypeKind::Function) , callingConvention(CallingConvention::Default) , exceptionSpecType(ExceptionSpecType::None) { } FunctionType::~FunctionType() {} DEF_VECTOR(FunctionType, Parameter*, Parameters) PointerType::PointerType() : Type(TypeKind::Pointer) { } MemberPointerType::MemberPointerType() : Type(TypeKind::MemberPointer) { } TypedefType::TypedefType() : Type(TypeKind::Typedef) , declaration(0) { } AttributedType::AttributedType() : Type(TypeKind::Attributed) { } DecayedType::DecayedType() : Type(TypeKind::Decayed) { } // Template TemplateParameter::TemplateParameter(DeclarationKind kind) : Declaration(kind) , depth(0) , index(0) , isParameterPack(false) { } TemplateParameter::~TemplateParameter() { } TemplateTemplateParameter::TemplateTemplateParameter() : Template(DeclarationKind::TemplateTemplateParm) , isParameterPack(false) , isPackExpansion(false) , isExpandedParameterPack(false) { } TemplateTemplateParameter::~TemplateTemplateParameter() { } // TemplateParameter TypeTemplateParameter::TypeTemplateParameter() : TemplateParameter(DeclarationKind::TemplateTypeParm) { } TypeTemplateParameter::TypeTemplateParameter(const TypeTemplateParameter& rhs) : TemplateParameter(rhs.kind) , defaultArgument(rhs.defaultArgument) { } TypeTemplateParameter::~TypeTemplateParameter() {} NonTypeTemplateParameter::NonTypeTemplateParameter() : TemplateParameter(DeclarationKind::NonTypeTemplateParm) , defaultArgument(0) , position(0) , isPackExpansion(false) , isExpandedParameterPack(false) { } NonTypeTemplateParameter::NonTypeTemplateParameter(const NonTypeTemplateParameter& rhs) : TemplateParameter(rhs.kind) , defaultArgument(rhs.defaultArgument) , position(rhs.position) , isPackExpansion(rhs.isPackExpansion) , isExpandedParameterPack(rhs.isExpandedParameterPack) , type(rhs.type) { } NonTypeTemplateParameter::~NonTypeTemplateParameter() { deleteExpression(defaultArgument); } TemplateArgument::TemplateArgument() : declaration(0) , integral(0) { } TemplateSpecializationType::TemplateSpecializationType() : Type(TypeKind::TemplateSpecialization) , _template(0) { } TemplateSpecializationType::TemplateSpecializationType( const TemplateSpecializationType& rhs) : Type(rhs) , Arguments(rhs.Arguments) , _template(rhs._template) , desugared(rhs.desugared) { } TemplateSpecializationType::~TemplateSpecializationType() {} DEF_VECTOR(TemplateSpecializationType, TemplateArgument, Arguments) DependentTemplateSpecializationType::DependentTemplateSpecializationType() : Type(TypeKind::DependentTemplateSpecialization) { } DependentTemplateSpecializationType::DependentTemplateSpecializationType( const DependentTemplateSpecializationType& rhs) : Type(rhs) , Arguments(rhs.Arguments) , desugared(rhs.desugared) { } DependentTemplateSpecializationType::~DependentTemplateSpecializationType() {} DEF_VECTOR(DependentTemplateSpecializationType, TemplateArgument, Arguments) TemplateParameterType::TemplateParameterType() : Type(TypeKind::TemplateParameter) , parameter(0) { } TemplateParameterType::~TemplateParameterType() {} TemplateParameterSubstitutionType::TemplateParameterSubstitutionType() : Type(TypeKind::TemplateParameterSubstitution) , replacedParameter(0) { } InjectedClassNameType::InjectedClassNameType() : Type(TypeKind::InjectedClassName) , _class(0) { } DependentNameType::DependentNameType() : Type(TypeKind::DependentName) { } DependentNameType::~DependentNameType() {} PackExpansionType::PackExpansionType() : Type(TypeKind::PackExpansion) { } UnaryTransformType::UnaryTransformType() : Type(TypeKind::UnaryTransform) { } UnresolvedUsingType::UnresolvedUsingType() : Type(TypeKind::UnresolvedUsing) { } VectorType::VectorType() : Type(TypeKind::Vector) , numElements(0) { } BuiltinType::BuiltinType() : CppSharp::CppParser::AST::Type(TypeKind::Builtin) { } VTableComponent::VTableComponent() : offset(0) , declaration(0) { } // VTableLayout VTableLayout::VTableLayout() {} VTableLayout::VTableLayout(const VTableLayout& rhs) : Components(rhs.Components) { } VTableLayout::~VTableLayout() {} DEF_VECTOR(VTableLayout, VTableComponent, Components) VFTableInfo::VFTableInfo() : VBTableIndex(0) , VFPtrOffset(0) , VFPtrFullOffset(0) { } VFTableInfo::VFTableInfo(const VFTableInfo& rhs) : VBTableIndex(rhs.VBTableIndex) , VFPtrOffset(rhs.VFPtrOffset) , VFPtrFullOffset(rhs.VFPtrFullOffset) , layout(rhs.layout) { } LayoutField::LayoutField() : offset(0) , fieldPtr(0) { } LayoutField::LayoutField(const LayoutField& other) : offset(other.offset) , name(other.name) , qualifiedType(other.qualifiedType) , fieldPtr(other.fieldPtr) { } LayoutField::~LayoutField() {} LayoutBase::LayoutBase() : offset(0) , _class(0) { } LayoutBase::LayoutBase(const LayoutBase& other) : offset(other.offset) , _class(other._class) { } LayoutBase::~LayoutBase() {} ClassLayout::ClassLayout() : ABI(CppAbi::Itanium) , argABI(RecordArgABI::Default) , hasOwnVFPtr(false) , VBPtrOffset(0) , alignment(0) , size(0) , dataSize(0) { } DEF_VECTOR(ClassLayout, VFTableInfo, VFTables) DEF_VECTOR(ClassLayout, LayoutField, Fields) DEF_VECTOR(ClassLayout, LayoutBase, Bases) Declaration::Declaration(DeclarationKind kind) : kind(kind) , access(AccessSpecifier::Public) , _namespace(0) , location(0) , lineNumberStart(0) , lineNumberEnd(0) , comment(0) , isIncomplete(false) , isDependent(false) , isImplicit(false) , isInvalid(false) , isDeprecated(false) , completeDeclaration(0) , definitionOrder(0) , originalPtr(0) , alignAs(0) , maxFieldAlignment(0) { } Declaration::Declaration(const Declaration& rhs) : kind(rhs.kind) , access(rhs.access) , _namespace(rhs._namespace) , location(rhs.location.ID) , lineNumberStart(rhs.lineNumberStart) , lineNumberEnd(rhs.lineNumberEnd) , name(rhs.name) , comment(rhs.comment) , debugText(rhs.debugText) , isIncomplete(rhs.isIncomplete) , isDependent(rhs.isDependent) , isImplicit(rhs.isImplicit) , isInvalid(rhs.isInvalid) , isDeprecated(rhs.isDeprecated) , completeDeclaration(rhs.completeDeclaration) , definitionOrder(rhs.definitionOrder) , PreprocessedEntities(rhs.PreprocessedEntities) , originalPtr(rhs.originalPtr) { } Declaration::~Declaration() { } DEF_VECTOR(Declaration, PreprocessedEntity*, PreprocessedEntities) DEF_VECTOR(Declaration, Declaration*, Redeclarations) DeclarationContext::DeclarationContext(DeclarationKind kind) : Declaration(kind) , isAnonymous(false) { } DEF_VECTOR(DeclarationContext, Namespace*, Namespaces) DEF_VECTOR(DeclarationContext, Enumeration*, Enums) DEF_VECTOR(DeclarationContext, Function*, Functions) DEF_VECTOR(DeclarationContext, Class*, Classes) DEF_VECTOR(DeclarationContext, Template*, Templates) DEF_VECTOR(DeclarationContext, TypedefDecl*, Typedefs) DEF_VECTOR(DeclarationContext, TypeAlias*, TypeAliases) DEF_VECTOR(DeclarationContext, Variable*, Variables) DEF_VECTOR(DeclarationContext, Friend*, Friends) Declaration* DeclarationContext::FindAnonymous(const std::string& key) { auto it = anonymous.find(key); return (it != anonymous.end()) ? it->second : 0; } Namespace* DeclarationContext::FindNamespace(const std::string& Name) { auto namespaces = split(Name, "::"); return FindNamespace(namespaces); } Namespace* DeclarationContext::FindNamespace(const std::vector& Namespaces) { auto currentNamespace = this; for (auto I = Namespaces.begin(), E = Namespaces.end(); I != E; ++I) { auto& _namespace = *I; auto childNamespace = std::find_if(currentNamespace->Namespaces.begin(), currentNamespace->Namespaces.end(), [&](CppSharp::CppParser::AST::Namespace* ns) { return ns->name == _namespace; }); if (childNamespace == currentNamespace->Namespaces.end()) return nullptr; currentNamespace = *childNamespace; } return (CppSharp::CppParser::AST::Namespace*)currentNamespace; } Namespace* DeclarationContext::FindCreateNamespace(const std::string& Name) { auto _namespace = FindNamespace(Name); if (!_namespace) { _namespace = new Namespace(); _namespace->name = Name; _namespace->_namespace = this; Namespaces.push_back(_namespace); } return _namespace; } Class* DeclarationContext::FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete) { if (Name.empty()) return nullptr; auto entries = split(Name, "::"); if (entries.size() == 1) { auto _class = std::find_if(Classes.begin(), Classes.end(), [OriginalPtr, Name, IsComplete](Class* klass) { return (OriginalPtr && klass->originalPtr == OriginalPtr) || (klass->name == Name && klass->isIncomplete == !IsComplete); }); return _class != Classes.end() ? *_class : nullptr; } auto className = entries[entries.size() - 1]; std::vector namespaces; std::copy_n(entries.begin(), entries.size() - 1, std::back_inserter(namespaces)); auto _namespace = FindNamespace(namespaces); if (!_namespace) return nullptr; return _namespace->FindClass(OriginalPtr, className, IsComplete); } Class* DeclarationContext::CreateClass(const std::string& Name, bool IsComplete) { auto _class = new Class(); _class->name = Name; _class->_namespace = this; _class->isIncomplete = !IsComplete; return _class; } Class* DeclarationContext::FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete, bool Create) { auto _class = FindClass(OriginalPtr, Name, IsComplete); if (!_class) { if (Create) { _class = CreateClass(Name, IsComplete); Classes.push_back(_class); } return _class; } return _class; } Enumeration* DeclarationContext::FindEnum(const void* OriginalPtr) { auto foundEnum = std::find_if(Enums.begin(), Enums.end(), [&](Enumeration* enumeration) { return enumeration->originalPtr == OriginalPtr; }); if (foundEnum != Enums.end()) return *foundEnum; return nullptr; } Enumeration* DeclarationContext::FindEnum(const std::string& Name, bool Create) { auto entries = split(Name, "::"); if (entries.size() == 1) { auto foundEnum = std::find_if(Enums.begin(), Enums.end(), [&](Enumeration* _enum) { return _enum->name == Name; }); if (foundEnum != Enums.end()) return *foundEnum; if (!Create) return nullptr; auto _enum = new Enumeration(); _enum->name = Name; _enum->_namespace = this; Enums.push_back(_enum); return _enum; } auto enumName = entries[entries.size() - 1]; std::vector namespaces; std::copy_n(entries.begin(), entries.size() - 1, std::back_inserter(namespaces)); auto _namespace = FindNamespace(namespaces); if (!_namespace) return nullptr; return _namespace->FindEnum(enumName, Create); } Enumeration* DeclarationContext::FindEnumWithItem(const std::string& Name) { auto foundEnumIt = std::find_if(Enums.begin(), Enums.end(), [&](Enumeration* _enum) { return _enum->FindItemByName(Name) != nullptr; }); if (foundEnumIt != Enums.end()) return *foundEnumIt; for (auto it = Namespaces.begin(); it != Namespaces.end(); ++it) { auto foundEnum = (*it)->FindEnumWithItem(Name); if (foundEnum != nullptr) return foundEnum; } for (auto it = Classes.begin(); it != Classes.end(); ++it) { auto foundEnum = (*it)->FindEnumWithItem(Name); if (foundEnum != nullptr) return foundEnum; } return nullptr; } Function* DeclarationContext::FindFunction(const std::string& USR) { auto foundFunction = std::find_if(Functions.begin(), Functions.end(), [&](Function* func) { return func->USR == USR; }); if (foundFunction != Functions.end()) return *foundFunction; auto foundTemplate = std::find_if(Templates.begin(), Templates.end(), [&](Template* t) { return t->TemplatedDecl && t->TemplatedDecl->USR == USR; }); if (foundTemplate != Templates.end()) return static_cast((*foundTemplate)->TemplatedDecl); return nullptr; } TypedefDecl* DeclarationContext::FindTypedef(const std::string& Name, bool Create) { auto foundTypedef = std::find_if(Typedefs.begin(), Typedefs.end(), [&](TypedefDecl* tdef) { return tdef->name == Name; }); if (foundTypedef != Typedefs.end()) return *foundTypedef; if (!Create) return nullptr; auto tdef = new TypedefDecl(); tdef->name = Name; tdef->_namespace = this; return tdef; } TypeAlias* DeclarationContext::FindTypeAlias(const std::string& Name, bool Create) { auto foundTypeAlias = std::find_if(TypeAliases.begin(), TypeAliases.end(), [&](TypeAlias* talias) { return talias->name == Name; }); if (foundTypeAlias != TypeAliases.end()) return *foundTypeAlias; if (!Create) return nullptr; auto talias = new TypeAlias(); talias->name = Name; talias->_namespace = this; return talias; } Variable* DeclarationContext::FindVariable(const std::string& USR) { auto found = std::find_if(Variables.begin(), Variables.end(), [&](Variable* var) { return var->USR == USR; }); if (found != Variables.end()) return *found; return nullptr; } Friend* DeclarationContext::FindFriend(const std::string& USR) { auto found = std::find_if(Friends.begin(), Friends.end(), [&](Friend* var) { return var->USR == USR; }); if (found != Friends.end()) return *found; return nullptr; } TypedefNameDecl::TypedefNameDecl(DeclarationKind Kind) : Declaration(Kind) { } TypedefNameDecl::~TypedefNameDecl() {} TypedefDecl::TypedefDecl() : TypedefNameDecl(DeclarationKind::Typedef) { } TypedefDecl::~TypedefDecl() {} TypeAlias::TypeAlias() : TypedefNameDecl(DeclarationKind::TypeAlias) , describedAliasTemplate(0) { } TypeAlias::~TypeAlias() {} Friend::Friend() : CppSharp::CppParser::AST::Declaration(DeclarationKind::Friend) , declaration(0) { } Friend::~Friend() {} StatementObsolete::StatementObsolete(const std::string& str, StatementClassObsolete stmtClass, Declaration* decl) : string(str) , _class(stmtClass) , decl(decl) { } ExpressionObsolete::ExpressionObsolete(const std::string& str, StatementClassObsolete stmtClass, Declaration* decl) : StatementObsolete(str, stmtClass, decl) { } BinaryOperatorObsolete::BinaryOperatorObsolete(const std::string& str, ExpressionObsolete* lhs, ExpressionObsolete* rhs, const std::string& opcodeStr) : ExpressionObsolete(str, StatementClassObsolete::BinaryOperator) , LHS(lhs) , RHS(rhs) , opcodeStr(opcodeStr) { } BinaryOperatorObsolete::~BinaryOperatorObsolete() { deleteExpression(LHS); deleteExpression(RHS); } CallExprObsolete::CallExprObsolete(const std::string& str, Declaration* decl) : ExpressionObsolete(str, StatementClassObsolete::CallExprClass, decl) { } CallExprObsolete::~CallExprObsolete() { for (auto& arg : Arguments) deleteExpression(arg); } DEF_VECTOR(CallExprObsolete, ExpressionObsolete*, Arguments) CXXConstructExprObsolete::CXXConstructExprObsolete(const std::string& str, Declaration* decl) : ExpressionObsolete(str, StatementClassObsolete::CXXConstructExprClass, decl) { } CXXConstructExprObsolete::~CXXConstructExprObsolete() { for (auto& arg : Arguments) deleteExpression(arg); } DEF_VECTOR(CXXConstructExprObsolete, ExpressionObsolete*, Arguments) Parameter::Parameter() : Declaration(DeclarationKind::Parameter) , isIndirect(false) , hasDefaultValue(false) , defaultArgument(0) , defaultValue(0) { } Parameter::~Parameter() { deleteExpression(defaultArgument); } Function::Function() : DeclarationContext(DeclarationKind::Function) , isReturnIndirect(false) , isConstExpr(false) , isVariadic(false) , isInline(false) , isPure(false) , isDeleted(false) , isDefaulted(false) , friendKind(FriendKind::None) , operatorKind(CXXOperatorKind::None) , callingConvention(CallingConvention::Default) , specializationInfo(0) , instantiatedFrom(0) , bodyStmt(0) { } Function::~Function() {} DEF_VECTOR(Function, Parameter*, Parameters) Method::Method() : Function() , isVirtual(false) , isStatic(false) , isConst(false) , isExplicit(false) , isVolatile(false) , isDefaultConstructor(false) , isCopyConstructor(false) , isMoveConstructor(false) , refQualifier(RefQualifierKind::None) { kind = DeclarationKind::Method; } Method::~Method() {} DEF_VECTOR(Method, Method*, OverriddenMethods) // Enumeration Enumeration::Enumeration() : DeclarationContext(DeclarationKind::Enumeration) , modifiers((EnumModifiers)0) , type(0) , builtinType(0) { } Enumeration::~Enumeration() {} DEF_VECTOR(Enumeration, Enumeration::Item*, Items) Enumeration::Item::Item() : Declaration(DeclarationKind::EnumerationItem) { } Enumeration::Item::Item(const Item& rhs) : Declaration(rhs) , expression(rhs.expression) , value(rhs.value) { } Enumeration::Item::~Item() {} Enumeration::Item* Enumeration::FindItemByName(const std::string& Name) { auto foundEnumItem = std::find_if(Items.begin(), Items.end(), [&](Item* _item) { return _item->name == Name; }); if (foundEnumItem != Items.end()) return *foundEnumItem; return nullptr; } Variable::Variable() : Declaration(DeclarationKind::Variable) , isConstExpr(false) , initializer(0) { } Variable::~Variable() {} BaseClassSpecifier::BaseClassSpecifier() : type(0) , offset(0) { } Field::Field() : Declaration(DeclarationKind::Field) , _class(0) , isBitField(false) , bitWidth(0) { } Field::~Field() {} AccessSpecifierDecl::AccessSpecifierDecl() : Declaration(DeclarationKind::AccessSpecifier) { } AccessSpecifierDecl::~AccessSpecifierDecl() {} Class::Class() : DeclarationContext(DeclarationKind::Class) , isPOD(false) , isAbstract(false) , isUnion(false) , isDynamic(false) , isPolymorphic(false) , hasNonTrivialDefaultConstructor(false) , hasNonTrivialCopyConstructor(false) , hasNonTrivialDestructor(false) , isExternCContext(false) , isInjected(false) , layout(0) , tagKind(TagKind::Struct) { } Class::~Class() { if (layout) delete layout; } DEF_VECTOR(Class, BaseClassSpecifier*, Bases) DEF_VECTOR(Class, Field*, Fields) DEF_VECTOR(Class, Method*, Methods) DEF_VECTOR(Class, AccessSpecifierDecl*, Specifiers) Template::Template() : Declaration(DeclarationKind::Template) , TemplatedDecl(0) { } Template::Template(DeclarationKind kind) : Declaration(kind) , TemplatedDecl(0) { } DEF_VECTOR(Template, Declaration*, Parameters) TypeAliasTemplate::TypeAliasTemplate() : Template(DeclarationKind::TypeAliasTemplate) { } TypeAliasTemplate::~TypeAliasTemplate() {} ClassTemplate::ClassTemplate() : Template(DeclarationKind::ClassTemplate) { } ClassTemplate::~ClassTemplate() {} DEF_VECTOR(ClassTemplate, ClassTemplateSpecialization*, Specializations) ClassTemplateSpecialization::ClassTemplateSpecialization() : Class() , templatedDecl(0) { kind = DeclarationKind::ClassTemplateSpecialization; } ClassTemplateSpecialization::~ClassTemplateSpecialization() {} DEF_VECTOR(ClassTemplateSpecialization, TemplateArgument, Arguments) ClassTemplatePartialSpecialization::ClassTemplatePartialSpecialization() : ClassTemplateSpecialization() { kind = DeclarationKind::ClassTemplatePartialSpecialization; } ClassTemplatePartialSpecialization::~ClassTemplatePartialSpecialization() {} DEF_VECTOR(ClassTemplatePartialSpecialization, Declaration*, Parameters) FunctionTemplate::FunctionTemplate() : Template(DeclarationKind::FunctionTemplate) { } FunctionTemplate::~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(*foundSpec); return nullptr; } FunctionTemplateSpecialization::FunctionTemplateSpecialization() : _template(0) , specializedFunction(0) { } FunctionTemplateSpecialization::~FunctionTemplateSpecialization() { } DEF_VECTOR(FunctionTemplateSpecialization, TemplateArgument, Arguments) VarTemplate::VarTemplate() : Template(DeclarationKind::VarTemplate) { } VarTemplate::~VarTemplate() {} DEF_VECTOR(VarTemplate, VarTemplateSpecialization*, Specializations) VarTemplateSpecialization* VarTemplate::FindSpecialization(const std::string& usr) { auto foundSpec = std::find_if(Specializations.begin(), Specializations.end(), [&](VarTemplateSpecialization* cts) { return cts->USR == usr; }); if (foundSpec != Specializations.end()) return static_cast(*foundSpec); return nullptr; } VarTemplatePartialSpecialization* VarTemplate::FindPartialSpecialization(const std::string& usr) { auto foundSpec = FindSpecialization(usr); if (foundSpec != nullptr) return static_cast(foundSpec); return nullptr; } VarTemplateSpecialization::VarTemplateSpecialization() : Variable() , templatedDecl(0) { kind = DeclarationKind::VarTemplateSpecialization; } VarTemplateSpecialization::~VarTemplateSpecialization() {} DEF_VECTOR(VarTemplateSpecialization, TemplateArgument, Arguments) VarTemplatePartialSpecialization::VarTemplatePartialSpecialization() : VarTemplateSpecialization() { kind = DeclarationKind::VarTemplatePartialSpecialization; } VarTemplatePartialSpecialization::~VarTemplatePartialSpecialization() { } UnresolvedUsingTypename::UnresolvedUsingTypename() : Declaration(DeclarationKind::UnresolvedUsingTypename) { } UnresolvedUsingTypename::~UnresolvedUsingTypename() {} Namespace::Namespace() : DeclarationContext(DeclarationKind::Namespace) , isInline(false) { } Namespace::~Namespace() {} PreprocessedEntity::PreprocessedEntity() : macroLocation(AST::MacroLocation::Unknown) , originalPtr(0) , kind(DeclarationKind::PreprocessedEntity) { } MacroDefinition::MacroDefinition() : lineNumberStart(0) , lineNumberEnd(0) { kind = DeclarationKind::MacroDefinition; } MacroDefinition::~MacroDefinition() {} MacroExpansion::MacroExpansion() : definition(0) { kind = DeclarationKind::MacroExpansion; } MacroExpansion::~MacroExpansion() {} TranslationUnit::TranslationUnit() { kind = DeclarationKind::TranslationUnit; } TranslationUnit::~TranslationUnit() {} DEF_VECTOR(TranslationUnit, MacroDefinition*, Macros) NativeLibrary::NativeLibrary() : archType(AST::ArchType::UnknownArch) { } NativeLibrary::~NativeLibrary() {} // NativeLibrary DEF_VECTOR_STRING(NativeLibrary, Symbols) DEF_VECTOR_STRING(NativeLibrary, Dependencies) // ASTContext DEF_VECTOR(ASTContext, TranslationUnit*, TranslationUnits) ClassTemplateSpecialization* ClassTemplate::FindSpecialization(const std::string& usr) { auto foundSpec = std::find_if(Specializations.begin(), Specializations.end(), [&](ClassTemplateSpecialization* cts) { return cts->USR == usr; }); if (foundSpec != Specializations.end()) return static_cast(*foundSpec); return nullptr; } ClassTemplatePartialSpecialization* ClassTemplate::FindPartialSpecialization(const std::string& usr) { auto foundSpec = FindSpecialization(usr); if (foundSpec != nullptr) return static_cast(foundSpec); return nullptr; } ASTContext::ASTContext() {} ASTContext::~ASTContext() {} TranslationUnit* ASTContext::FindOrCreateModule(const std::string& File) { auto normalizedFile = normalizePath(File); auto existingUnit = std::find_if(TranslationUnits.begin(), TranslationUnits.end(), [&](TranslationUnit* unit) { return unit && unit->fileName == normalizedFile; }); if (existingUnit != TranslationUnits.end()) return *existingUnit; auto unit = new TranslationUnit(); unit->fileName = normalizedFile; TranslationUnits.push_back(unit); return unit; } // Comments Comment::Comment(CommentKind kind) : kind(kind) { } RawComment::RawComment() : fullCommentBlock(0) { } RawComment::~RawComment() { if (fullCommentBlock) delete fullCommentBlock; } FullComment::FullComment() : Comment(CommentKind::FullComment) { } FullComment::~FullComment() { for (auto& block : Blocks) { // HACK: see https://github.com/mono/CppSharp/issues/599 switch (block->kind) { case CommentKind::BlockCommandComment: delete static_cast(block); break; case CommentKind::ParamCommandComment: delete static_cast(block); break; case CommentKind::TParamCommandComment: delete static_cast(block); break; case CommentKind::VerbatimBlockComment: delete static_cast(block); break; case CommentKind::VerbatimLineComment: delete static_cast(block); break; case CommentKind::ParagraphComment: delete static_cast(block); break; default: delete block; break; } } } DEF_VECTOR(FullComment, BlockContentComment*, Blocks) BlockContentComment::BlockContentComment() : Comment(CommentKind::BlockContentComment) { } BlockContentComment::BlockContentComment(CommentKind Kind) : Comment(Kind) { } BlockCommandComment::Argument::Argument() {} BlockCommandComment::Argument::Argument(const Argument& rhs) : text(rhs.text) { } BlockCommandComment::Argument::~Argument() {} BlockCommandComment::BlockCommandComment() : BlockContentComment(CommentKind::BlockCommandComment) , commandId(0) , paragraphComment(0) { } BlockCommandComment::BlockCommandComment(CommentKind Kind) : BlockContentComment(Kind) , commandId(0) , paragraphComment(0) { } BlockCommandComment::~BlockCommandComment() { delete paragraphComment; } DEF_VECTOR(BlockCommandComment, BlockCommandComment::Argument, Arguments) ParamCommandComment::ParamCommandComment() : BlockCommandComment(CommentKind::ParamCommandComment) , direction(PassDirection::In) , paramIndex(0) { } TParamCommandComment::TParamCommandComment() : BlockCommandComment(CommentKind::TParamCommandComment) { } DEF_VECTOR(TParamCommandComment, unsigned, Position) VerbatimBlockComment::VerbatimBlockComment() : BlockCommandComment(CommentKind::VerbatimBlockComment) { } VerbatimBlockComment::~VerbatimBlockComment() { for (auto& line : Lines) delete line; } DEF_VECTOR(VerbatimBlockComment, VerbatimBlockLineComment*, Lines) VerbatimLineComment::VerbatimLineComment() : BlockCommandComment(CommentKind::VerbatimLineComment) { } ParagraphComment::ParagraphComment() : BlockContentComment(CommentKind::ParagraphComment) , isWhitespace(false) { } ParagraphComment::~ParagraphComment() { for (auto& content : Content) { // HACK: see https://github.com/mono/CppSharp/issues/599 switch (content->kind) { case CommentKind::InlineCommandComment: delete static_cast(content); break; case CommentKind::HTMLTagComment: delete static_cast(content); break; case CommentKind::HTMLStartTagComment: delete static_cast(content); break; case CommentKind::HTMLEndTagComment: delete static_cast(content); break; case CommentKind::TextComment: delete static_cast(content); break; default: delete content; break; } } } DEF_VECTOR(ParagraphComment, InlineContentComment*, Content) HTMLTagComment::HTMLTagComment() : InlineContentComment(CommentKind::HTMLTagComment) { } HTMLTagComment::HTMLTagComment(CommentKind Kind) : InlineContentComment(Kind) { } HTMLStartTagComment::Attribute::Attribute() {} HTMLStartTagComment::Attribute::Attribute(const Attribute& rhs) : name(rhs.name) , value(rhs.value) { } HTMLStartTagComment::Attribute::~Attribute() {} HTMLStartTagComment::HTMLStartTagComment() : HTMLTagComment(CommentKind::HTMLStartTagComment) { } DEF_VECTOR(HTMLStartTagComment, HTMLStartTagComment::Attribute, Attributes) HTMLEndTagComment::HTMLEndTagComment() : HTMLTagComment(CommentKind::HTMLEndTagComment) { } InlineContentComment::InlineContentComment() : Comment(CommentKind::InlineContentComment) , hasTrailingNewline(false) { } InlineContentComment::InlineContentComment(CommentKind Kind) : Comment(Kind) , hasTrailingNewline(false) { } TextComment::TextComment() : InlineContentComment(CommentKind::TextComment) { } InlineCommandComment::Argument::Argument() {} InlineCommandComment::Argument::Argument(const Argument& rhs) : text(rhs.text) { } InlineCommandComment::Argument::~Argument() {} InlineCommandComment::InlineCommandComment() : InlineContentComment(CommentKind::InlineCommandComment) , commandId(0) , commentRenderKind(RenderNormal) { } DEF_VECTOR(InlineCommandComment, InlineCommandComment::Argument, Arguments) VerbatimBlockLineComment::VerbatimBlockLineComment() : Comment(CommentKind::VerbatimBlockLineComment) { } }}} // namespace CppSharp::CppParser::AST