From df61ea604195d24b8c56fd4ba8eb84dcaa4fd825 Mon Sep 17 00:00:00 2001 From: triton Date: Sun, 20 Jan 2013 13:51:31 +0000 Subject: [PATCH] Classes now try to keep accurate track if they were complete / forward referenced at the time of referencing. --- src/Bridge/Namespace.cs | 50 ++++++++++++++++++++++++++++++++++++----- src/Parser/Parser.cpp | 20 +++++------------ 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/Bridge/Namespace.cs b/src/Bridge/Namespace.cs index fe85213e..53ec632d 100644 --- a/src/Bridge/Namespace.cs +++ b/src/Bridge/Namespace.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; namespace Cxxi { @@ -99,17 +100,54 @@ namespace Cxxi return function; } - public Class FindClass(string name, bool createDecl = false) + Class CreateClass(string name, bool isComplete) + { + var @class = new Class + { + Name = name, + Namespace = this, + IsIncomplete = !isComplete + }; + + return @class; + } + + public Class FindClass(string name) { var @class = Classes.Find(e => e.Name.Equals(name)); + return @class; + } + + public Class FindClass(string name, bool isComplete, + bool createDecl = false) + { + var @class = FindClass(name); - if (@class == null && createDecl) + if (@class == null) { - @class = new Class {Name = name, Namespace = this}; - Classes.Add(@class); + if (createDecl) + { + @class = CreateClass(name, isComplete); + Classes.Add(@class); + } + + return @class; } - - return @class; + + if (@class.IsIncomplete == !isComplete) + return @class; + + var newClass = CreateClass(name, isComplete); + + // Replace the incomplete declaration with the complete one. + if (@class.IsIncomplete) + { + var index = Classes.FindIndex(c => c == @class); + @class.CompleteDeclaration = newClass; + Classes[index] = newClass; + } + + return newClass; } public ClassTemplate FindClassTemplate(string name) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 4cf5f2bc..d5741ce5 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -254,28 +254,20 @@ Cxxi::Class^ Parser::WalkRecordCXX(clang::CXXRecordDecl* Record, bool IsDependen return nullptr; } - if (Record->hasDefinition()) - Record = Record->getDefinition(); - auto NS = GetNamespace(Record); assert(NS && "Expected a valid namespace"); + bool isCompleteDefinition = Record->isCompleteDefinition(); auto Name = marshalString(GetTagDeclName(Record)); - auto RC = NS->FindClass(Name, /*Create=*/false); + auto RC = NS->FindClass(Name, isCompleteDefinition, /*Create=*/false); - if (RC && !RC->IsIncomplete) + if (RC) return RC; - if (!RC) - RC = NS->FindClass(Name, /*Create=*/true); - - if (!Record->hasDefinition()) - { - RC->IsIncomplete = true; - return RC; - } + RC = NS->FindClass(Name, isCompleteDefinition, /*Create=*/true); - RC->IsIncomplete = false; + if (!isCompleteDefinition) + return RC; RC->IsPOD = Record->isPOD(); RC->IsUnion = Record->isUnion();