Skip to content

Commit

Permalink
Merge pull request mono#595 from ddobrev/master
Browse files Browse the repository at this point in the history
 Fixed a crash caused by deleting forward declarations other declarations might depend on
  • Loading branch information
tritao committed Jan 11, 2016
2 parents 998f844 + b60de16 commit a8d1984
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 32 deletions.
3 changes: 2 additions & 1 deletion src/Core/Parser/ASTConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,8 @@ void VisitDeclContext(DeclarationContext ctx, AST.DeclarationContext _ctx)
{
var decl = ctx.getClasses(i);
var _decl = Visit(decl) as AST.Class;
_ctx.Classes.Add(_decl);
if (!_decl.IsIncomplete)
_ctx.Classes.Add(_decl);
}

for (uint i = 0; i < ctx.TemplatesCount; ++i)
Expand Down
35 changes: 6 additions & 29 deletions src/CppParser/AST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ Namespace* DeclarationContext::FindCreateNamespace(const std::string& Name)
return _namespace;
}

Class* DeclarationContext::FindClass(const std::string& Name)
Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete)
{
if (Name.empty()) return nullptr;

Expand All @@ -267,7 +267,8 @@ Class* DeclarationContext::FindClass(const std::string& Name)
if (entries.size() == 1)
{
auto _class = std::find_if(Classes.begin(), Classes.end(),
[&](Class* klass) { return klass->Name == Name; });
[&](Class* klass) { return klass->Name == Name &&
(!klass->IsIncomplete || !IsComplete); });

return _class != Classes.end() ? *_class : nullptr;
}
Expand All @@ -281,7 +282,7 @@ Class* DeclarationContext::FindClass(const std::string& Name)
if (!_namespace)
return nullptr;

return _namespace->FindClass(className);
return _namespace->FindClass(className, IsComplete);
}

Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete)
Expand All @@ -297,7 +298,7 @@ Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete)
Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete,
bool Create)
{
auto _class = FindClass(Name);
auto _class = FindClass(Name, IsComplete);

if (!_class)
{
Expand All @@ -310,31 +311,7 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete,
return _class;
}

if (!_class->IsIncomplete || !IsComplete)
return _class;

if (!Create)
return nullptr;

auto newClass = CreateClass(Name, IsComplete);

// Replace the incomplete declaration with the complete one.
if (_class->IsIncomplete)
{
bool Found = false;
std::replace_if(Classes.begin(), Classes.end(),
[&](Class* klass)
{
Found |= (klass == _class);
return klass == _class;
}, newClass);
if (Found)
delete _class;
else
_class->CompleteDeclaration = newClass;
}

return newClass;
return _class;
}

Enumeration* DeclarationContext::FindEnum(void* OriginalPtr)
Expand Down
4 changes: 2 additions & 2 deletions src/CppParser/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,9 @@ class CS_API DeclarationContext : public Declaration
CS_IGNORE CppSharp::CppParser::AST::Namespace* FindCreateNamespace(const std::string& Name);

CS_IGNORE Class* CreateClass(std::string Name, bool IsComplete);
CS_IGNORE Class* FindClass(const std::string& Name);
CS_IGNORE Class* FindClass(const std::string& Name, bool IsComplete);
CS_IGNORE Class* FindClass(const std::string& Name, bool IsComplete,
bool Create = false);
bool Create);

CS_IGNORE ClassTemplate* FindClassTemplate(const std::string& USR);
CS_IGNORE FunctionTemplate* FindFunctionTemplate(const std::string& USR);
Expand Down
15 changes: 15 additions & 0 deletions tests/Common/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1002,3 +1002,18 @@ void NonTrivialDtor::setDtorCalled(bool value)
{
dtorCalled = true;
}

template <class T> class ForwardedTemplate;

ForwardedTemplate<int> returnsForwardedTemplate();

template <class T> class ForwardedTemplate
{
ForwardedTemplate<T> functionInForwardedTemplate() const;
};

template <class T>
ForwardedTemplate<T> ForwardedTemplate<T>::functionInForwardedTemplate() const
{
return ForwardedTemplate<T>();
}

0 comments on commit a8d1984

Please sign in to comment.