Browse Source

Keep the declaration order of classes and sort them before processing. This helps with some referencing order problems in the generated code.

pull/1/head
triton 13 years ago
parent
commit
faded38014
  1. 3
      src/Bridge/Declaration.cs
  2. 13
      src/Generator/CodeGenerator.cs
  3. 29
      src/Parser/Parser.cpp
  4. 6
      src/Parser/Parser.h

3
src/Bridge/Declaration.cs

@ -66,6 +66,9 @@ namespace Cxxi
// Keeps a reference to the complete version of this declaration. // Keeps a reference to the complete version of this declaration.
public Declaration CompleteDeclaration; public Declaration CompleteDeclaration;
// Tracks the original declaration definition order.
public uint DefinitionOrder;
protected Declaration() protected Declaration()
{ {
} }

13
src/Generator/CodeGenerator.cs

@ -62,6 +62,10 @@ namespace Cxxi
typeDatabase = new TypeDatabase(); typeDatabase = new TypeDatabase();
typeDatabase.SetupTypeMaps(); typeDatabase.SetupTypeMaps();
// Sort the declarations to be in original order.
foreach (var unit in library.TranslationUnits)
SortDeclarations(unit);
if (transform != null) if (transform != null)
transform.Preprocess(new LibraryHelpers(library)); transform.Preprocess(new LibraryHelpers(library));
@ -82,6 +86,15 @@ namespace Cxxi
transform.Postprocess(new LibraryHelpers(library)); 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() public void GenerateCode()
{ {
if (library.TranslationUnits.Count <= 0) if (library.TranslationUnits.Count <= 0)

29
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); Setup(Opts);
} }
@ -1036,7 +1036,7 @@ void Parser::WalkAST()
for(auto it = TU->decls_begin(); it != TU->decls_end(); ++it) for(auto it = TU->decls_begin(); it != TU->decls_end(); ++it)
{ {
Decl* D = (*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, Cxxi::Declaration^ Parser::WalkDeclarationDef(clang::Decl* D)
clang::TypeLoc* TL, bool IgnoreSystemDecls) {
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 clang;
using namespace clix; using namespace clix;
@ -1210,6 +1217,16 @@ Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D,
auto Class = WalkRecordCXX(RD); auto Class = WalkRecordCXX(RD);
HandleComments(RD, Class); 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; Decl = Class;
break; break;
@ -1271,7 +1288,7 @@ Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D,
for (auto it = LS->decls_begin(); it != LS->decls_end(); ++it) for (auto it = LS->decls_begin(); it != LS->decls_end(); ++it)
{ {
clang::Decl* D = (*it); clang::Decl* D = (*it);
Decl = WalkDeclaration(D); Decl = WalkDeclarationDef(D);
} }
break; break;
@ -1301,7 +1318,7 @@ Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D,
for (auto it = ND->decls_begin(); it != ND->decls_end(); ++it) for (auto it = ND->decls_begin(); it != ND->decls_end(); ++it)
{ {
clang::Decl* D = (*it); clang::Decl* D = (*it);
Decl = WalkDeclaration(D); Decl = WalkDeclarationDef(D);
} }
break; break;

6
src/Parser/Parser.h

@ -62,8 +62,9 @@ protected:
// AST traversers // AST traversers
void WalkAST(); void WalkAST();
void WalkMacros(clang::PreprocessingRecord* PR); void WalkMacros(clang::PreprocessingRecord* PR);
Cxxi::Declaration^ WalkDeclaration(clang::Decl* D, Cxxi::Declaration^ WalkDeclaration(clang::Decl* D, clang::TypeLoc* = 0,
clang::TypeLoc* = 0, bool IgnoreSystemDecls = true); bool IgnoreSystemDecls = true, bool CanBeDefinition = false);
Cxxi::Declaration^ WalkDeclarationDef(clang::Decl* D);
Cxxi::Enumeration^ WalkEnum(clang::EnumDecl*); Cxxi::Enumeration^ WalkEnum(clang::EnumDecl*);
Cxxi::Function^ WalkFunction(clang::FunctionDecl*, bool IsDependent = false); Cxxi::Function^ WalkFunction(clang::FunctionDecl*, bool IsDependent = false);
Cxxi::Class^ WalkRecordCXX(clang::CXXRecordDecl*, bool IsDependent = false); Cxxi::Class^ WalkRecordCXX(clang::CXXRecordDecl*, bool IsDependent = false);
@ -88,6 +89,7 @@ protected:
Cxxi::TranslationUnit^ GetModule(clang::SourceLocation Loc); Cxxi::TranslationUnit^ GetModule(clang::SourceLocation Loc);
Cxxi::Namespace^ GetNamespace(const clang::NamedDecl*); Cxxi::Namespace^ GetNamespace(const clang::NamedDecl*);
int Index;
gcroot<Cxxi::Library^> Lib; gcroot<Cxxi::Library^> Lib;
llvm::OwningPtr<clang::CompilerInstance> C; llvm::OwningPtr<clang::CompilerInstance> C;
clang::ASTContext* AST; clang::ASTContext* AST;

Loading…
Cancel
Save