From faded3801456ca94f9796f9d39db1fd4f41c7c4f Mon Sep 17 00:00:00 2001 From: triton Date: Mon, 21 Jan 2013 17:17:08 +0000 Subject: [PATCH] Keep the declaration order of classes and sort them before processing. This helps with some referencing order problems in the generated code. --- src/Bridge/Declaration.cs | 3 +++ src/Generator/CodeGenerator.cs | 13 +++++++++++++ src/Parser/Parser.cpp | 29 +++++++++++++++++++++++------ src/Parser/Parser.h | 6 ++++-- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/Bridge/Declaration.cs b/src/Bridge/Declaration.cs index ef989e21..83dfb928 100644 --- a/src/Bridge/Declaration.cs +++ b/src/Bridge/Declaration.cs @@ -66,6 +66,9 @@ namespace Cxxi // Keeps a reference to the complete version of this declaration. public Declaration CompleteDeclaration; + // Tracks the original declaration definition order. + public uint DefinitionOrder; + protected Declaration() { } diff --git a/src/Generator/CodeGenerator.cs b/src/Generator/CodeGenerator.cs index 58101ace..1b424bd7 100644 --- a/src/Generator/CodeGenerator.cs +++ b/src/Generator/CodeGenerator.cs @@ -62,6 +62,10 @@ namespace Cxxi typeDatabase = new TypeDatabase(); typeDatabase.SetupTypeMaps(); + // Sort the declarations to be in original order. + foreach (var unit in library.TranslationUnits) + SortDeclarations(unit); + if (transform != null) transform.Preprocess(new LibraryHelpers(library)); @@ -82,6 +86,15 @@ namespace Cxxi transform.Postprocess(new LibraryHelpers(library)); } + private static void SortDeclarations(Namespace @namespace) + { + @namespace.Classes.Sort((c, c1) => + (int) (c.DefinitionOrder - c1.DefinitionOrder)); + + foreach (var childNamespace in @namespace.Namespaces) + SortDeclarations(childNamespace); + } + public void GenerateCode() { if (library.TranslationUnits.Count <= 0) diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 87a73e77..662b9de9 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -24,7 +24,7 @@ //-----------------------------------// -Parser::Parser(ParserOptions^ Opts) : Lib(Opts->Library) +Parser::Parser(ParserOptions^ Opts) : Lib(Opts->Library), Index(0) { Setup(Opts); } @@ -1036,7 +1036,7 @@ void Parser::WalkAST() for(auto it = TU->decls_begin(); it != TU->decls_end(); ++it) { Decl* D = (*it); - WalkDeclaration(D); + WalkDeclarationDef(D); } } @@ -1174,8 +1174,15 @@ void Parser::HandleComments(clang::Decl* D, Cxxi::Declaration^ Decl) //-----------------------------------// -Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D, - clang::TypeLoc* TL, bool IgnoreSystemDecls) +Cxxi::Declaration^ Parser::WalkDeclarationDef(clang::Decl* D) +{ + return WalkDeclaration(D, 0, /*IgnoreSystemDecls=*/true, + /*CanBeDefinition=*/true); +} + +Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D, clang::TypeLoc* TL, + bool IgnoreSystemDecls, + bool CanBeDefinition) { using namespace clang; using namespace clix; @@ -1210,6 +1217,16 @@ Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D, auto Class = WalkRecordCXX(RD); HandleComments(RD, Class); + // We store a definition order index into the declarations. + // This is needed because declarations are added to their contexts as + // soon as they are referenced and we need to know the original order + // of the declarations. + + if (CanBeDefinition && Class->DefinitionOrder == 0) + { + Class->DefinitionOrder = Index++; + } + Decl = Class; break; @@ -1271,7 +1288,7 @@ Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D, for (auto it = LS->decls_begin(); it != LS->decls_end(); ++it) { clang::Decl* D = (*it); - Decl = WalkDeclaration(D); + Decl = WalkDeclarationDef(D); } break; @@ -1301,7 +1318,7 @@ Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D, for (auto it = ND->decls_begin(); it != ND->decls_end(); ++it) { clang::Decl* D = (*it); - Decl = WalkDeclaration(D); + Decl = WalkDeclarationDef(D); } break; diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 9ec3a8de..46eecc64 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -62,8 +62,9 @@ protected: // AST traversers void WalkAST(); void WalkMacros(clang::PreprocessingRecord* PR); - Cxxi::Declaration^ WalkDeclaration(clang::Decl* D, - clang::TypeLoc* = 0, bool IgnoreSystemDecls = true); + Cxxi::Declaration^ WalkDeclaration(clang::Decl* D, clang::TypeLoc* = 0, + bool IgnoreSystemDecls = true, bool CanBeDefinition = false); + Cxxi::Declaration^ WalkDeclarationDef(clang::Decl* D); Cxxi::Enumeration^ WalkEnum(clang::EnumDecl*); Cxxi::Function^ WalkFunction(clang::FunctionDecl*, bool IsDependent = false); Cxxi::Class^ WalkRecordCXX(clang::CXXRecordDecl*, bool IsDependent = false); @@ -88,6 +89,7 @@ protected: Cxxi::TranslationUnit^ GetModule(clang::SourceLocation Loc); Cxxi::Namespace^ GetNamespace(const clang::NamedDecl*); + int Index; gcroot Lib; llvm::OwningPtr C; clang::ASTContext* AST;