Browse Source

Merge pull request #595 from ddobrev/master

Fixed a crash caused by deleting forward declarations other declarations might depend on
pull/605/head
João Matos 10 years ago
parent
commit
a8d1984cfd
  1. 3
      src/Core/Parser/ASTConverter.cs
  2. 35
      src/CppParser/AST.cpp
  3. 4
      src/CppParser/AST.h
  4. 15
      tests/Common/Common.h

3
src/Core/Parser/ASTConverter.cs

@ -835,7 +835,8 @@ namespace CppSharp
{ {
var decl = ctx.getClasses(i); var decl = ctx.getClasses(i);
var _decl = Visit(decl) as AST.Class; 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) for (uint i = 0; i < ctx.TemplatesCount; ++i)

35
src/CppParser/AST.cpp

@ -258,7 +258,7 @@ Namespace* DeclarationContext::FindCreateNamespace(const std::string& Name)
return _namespace; return _namespace;
} }
Class* DeclarationContext::FindClass(const std::string& Name) Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete)
{ {
if (Name.empty()) return nullptr; if (Name.empty()) return nullptr;
@ -267,7 +267,8 @@ Class* DeclarationContext::FindClass(const std::string& Name)
if (entries.size() == 1) if (entries.size() == 1)
{ {
auto _class = std::find_if(Classes.begin(), Classes.end(), 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; return _class != Classes.end() ? *_class : nullptr;
} }
@ -281,7 +282,7 @@ Class* DeclarationContext::FindClass(const std::string& Name)
if (!_namespace) if (!_namespace)
return nullptr; return nullptr;
return _namespace->FindClass(className); return _namespace->FindClass(className, IsComplete);
} }
Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete) Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete)
@ -297,7 +298,7 @@ Class* DeclarationContext::CreateClass(std::string Name, bool IsComplete)
Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete, Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete,
bool Create) bool Create)
{ {
auto _class = FindClass(Name); auto _class = FindClass(Name, IsComplete);
if (!_class) if (!_class)
{ {
@ -310,31 +311,7 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete,
return _class; return _class;
} }
if (!_class->IsIncomplete || !IsComplete) return _class;
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;
} }
Enumeration* DeclarationContext::FindEnum(void* OriginalPtr) Enumeration* DeclarationContext::FindEnum(void* OriginalPtr)

4
src/CppParser/AST.h

@ -433,9 +433,9 @@ public:
CS_IGNORE CppSharp::CppParser::AST::Namespace* FindCreateNamespace(const std::string& Name); CS_IGNORE CppSharp::CppParser::AST::Namespace* FindCreateNamespace(const std::string& Name);
CS_IGNORE Class* CreateClass(std::string Name, bool IsComplete); 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, 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 ClassTemplate* FindClassTemplate(const std::string& USR);
CS_IGNORE FunctionTemplate* FindFunctionTemplate(const std::string& USR); CS_IGNORE FunctionTemplate* FindFunctionTemplate(const std::string& USR);

15
tests/Common/Common.h

@ -1002,3 +1002,18 @@ void NonTrivialDtor::setDtorCalled(bool value)
{ {
dtorCalled = true; 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>();
}

Loading…
Cancel
Save