From e7a5e8d198a238928eb832fb040c3854eb0b79b8 Mon Sep 17 00:00:00 2001 From: kornilova-l Date: Thu, 24 May 2018 13:22:47 +0300 Subject: [PATCH 1/4] Add struct alloc helper --- SimpleTypeTests.cpp | 13 +++++++++++++ TreeVisitor.cpp | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/SimpleTypeTests.cpp b/SimpleTypeTests.cpp index c118f3a..6fde0d3 100644 --- a/SimpleTypeTests.cpp +++ b/SimpleTypeTests.cpp @@ -66,6 +66,19 @@ TEST_CASE("struct pointer", "[Type]"){ REQUIRE(answ == Translate(code)); } +TEST_CASE("struct helper methods") { + std::string code = "struct listing { int a; int b; };"; + Translate(code); + std::string answ = "\timplicit class struct_listing_ops(val p: native.Ptr[struct_listing]) extends AnyVal {\n" + "\t\tdef a: native.CInt = !p._1\n" + "\t\tdef a_=(value: native.CInt):Unit = !p._1 = value\n" + "\t\tdef b: native.CInt = !p._2\n" + "\t\tdef b_=(value: native.CInt):Unit = !p._2 = value\n" + "\t}\n\n" + "\tdef struct_listing()(implicit z: native.Zone): native.Ptr[struct_listing] = native.alloc[struct_listing]\n\n"; + REQUIRE(answ == helpers); +} + TEST_CASE("func no args", "[Func]"){ std::string code = "int foo();"; std::string answ = "\tdef foo(): native.CInt = native.extern\n"; diff --git a/TreeVisitor.cpp b/TreeVisitor.cpp index 6d9880f..1c24884 100644 --- a/TreeVisitor.cpp +++ b/TreeVisitor.cpp @@ -112,7 +112,7 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){ helpers += helpersFunc; helpers += "\t}\n\n"; - return true; + return true; } else if (record->isStruct() && record->isThisDeclarationADefinition() && !record->isAnonymousStructOrUnion() && name != ""){ @@ -165,6 +165,8 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){ helpers += "\timplicit class " + newName + "_ops(val p: native.Ptr[struct_" + name + "]) extends AnyVal {\n"; helpers += helpersFunc; helpers += "\t}\n\n"; + + helpers += "\tdef " + newName + "()(implicit z: native.Zone): native.Ptr[" + newName + "] = native.alloc[" + newName + "]\n\n"; } return true; From e8b25d37abd69e2ceeea52b32063430a47e56d17 Mon Sep 17 00:00:00 2001 From: mrRosset Date: Sun, 27 May 2018 23:13:22 +0200 Subject: [PATCH 2/4] Try out cycle detection --- TreeVisitor.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/TreeVisitor.cpp b/TreeVisitor.cpp index 6d9880f..d577491 100644 --- a/TreeVisitor.cpp +++ b/TreeVisitor.cpp @@ -47,6 +47,17 @@ bool TreeVisitor::VisitTypedefDecl(clang::TypedefDecl *tpdef){ std::string name = tpdef->getName(); std::string tpe = typeTranslator.Translate(tpdef->getUnderlyingType()); declarations += "\ttype " + name + " = " + tpe + "\n"; + + cycleDetection.AddDependcy(name, tpdef->getUnderlyingType()); + if(cycleDetection.isCyclic(name)){ + llvm::errs() << "Error: " << name << " ic cyclic\n"; + llvm::errs() << name << "\n"; + for(auto& s : cycleDetection.dependencies[name]){ + llvm::errs() << "\t" << s << "\n"; + } + llvm::errs() << cycleDetection.isCyclic(name) << "\n"; + } + return true; } @@ -145,11 +156,16 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){ fields = fields.substr(0, fields.size()-2); } - //llvm::errs() << newName << "\n"; - //for(auto& s : cycleDetection.dependencies[newName]){ - // llvm::errs() << "\t" << s << "\n"; - //} - //llvm::errs() << cycleDetection.isCyclic(newName) << "\n"; + + + if(cycleDetection.isCyclic(newName)){ + llvm::errs() << "Error: " << newName << " ic cyclic\n"; + llvm::errs() << newName << "\n"; + for(auto& s : cycleDetection.dependencies[newName]){ + llvm::errs() << "\t" << s << "\n"; + } + llvm::errs() << cycleDetection.isCyclic(newName) << "\n"; + } if(fieldCnt < SCALA_NATIVE_MAX_STRUCT_FIELDS){ declarations += "\ttype " + newName + " = " + "native.CStruct" + std::to_string(fieldCnt) + "[" + fields + "]\n"; From 32431a033365732bceec17aa1e7371d247ecfd28 Mon Sep 17 00:00:00 2001 From: mrRosset Date: Sun, 27 May 2018 23:19:56 +0200 Subject: [PATCH 3/4] Fix import problems --- Main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Main.cpp b/Main.cpp index cefd659..9fe8272 100644 --- a/Main.cpp +++ b/Main.cpp @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) { } else { if(declarations != "" || enums != "") llvm::outs() << "import scala.scalanative._\n" + << "import scala.scalanative.native._\n" << "import scala.scalanative.native.Nat._\n\n"; if(declarations != ""){ From 83596534ca3f068ab7abb84ba04a2421715809fb Mon Sep 17 00:00:00 2001 From: mrRosset Date: Sun, 27 May 2018 23:53:56 +0200 Subject: [PATCH 4/4] Fix char array in struct --- Main.cpp | 9 +++++---- TypeTranslator.cpp | 8 ++++---- TypeTranslator.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Main.cpp b/Main.cpp index 9fe8272..b923002 100644 --- a/Main.cpp +++ b/Main.cpp @@ -4,8 +4,6 @@ #define CATCH_CONFIG_RUNNER #include "catch/catch.hpp" -#include - static llvm::cl::OptionCategory Category("Binding Generator"); static llvm::cl::extrahelp CommonHelp(clang::tooling::CommonOptionsParser::HelpMessage); static llvm::cl::extrahelp MoreHelp("\nProduce Bindings for scala native. Please specify lib name wit parameter name\n"); @@ -62,8 +60,11 @@ int main(int argc, char *argv[]) { << "@native.extern\n" << "object " << lib << " {\n" << declarations - << "}\n\n" - << "import " + lib + "._\n\n"; + << "}\n\n"; + } + + if(enums != "" || helpers != ""){ + llvm::outs() << "import " + lib + "._\n\n"; } if(enums != ""){ diff --git a/TypeTranslator.cpp b/TypeTranslator.cpp index 167148a..9adb21d 100644 --- a/TypeTranslator.cpp +++ b/TypeTranslator.cpp @@ -62,8 +62,7 @@ std::string TypeTranslator::TranslateFunctionPointer(const clang::QualType& qtpe } } -std::string TypeTranslator::TranslatePointer(const clang::PointerType* ptr, const std::string* avoid){ - const clang::QualType& pte = ptr->getPointeeType(); +std::string TypeTranslator::TranslatePointer(const clang::QualType& pte, const std::string* avoid){ if(pte->isBuiltinType()){ const clang::BuiltinType* as = pte->getAs(); @@ -147,7 +146,7 @@ std::string TypeTranslator::Translate(const clang::QualType& qtpe, const std::st return TranslateFunctionPointer(qtpe, avoid); } else if(tpe->isPointerType()){ - return TranslatePointer(tpe->getAs(), avoid); + return TranslatePointer(tpe->getAs()->getPointeeType(), avoid); } else if(qtpe->isStructureType() || qtpe->isUnionType()){ return TranslateStructOrUnion(qtpe); @@ -157,7 +156,8 @@ std::string TypeTranslator::Translate(const clang::QualType& qtpe, const std::st } else if(qtpe->isConstantArrayType()){ return TranslateConstantArray(ctx->getAsConstantArrayType(qtpe), avoid); - + } else if(qtpe->isArrayType()){ + return TranslatePointer(ctx->getAsArrayType(qtpe)->getElementType(), avoid); } else { auto found = typeMap.find(qtpe.getUnqualifiedType().getAsString()); diff --git a/TypeTranslator.h b/TypeTranslator.h index 2c2e58c..4084b86 100644 --- a/TypeTranslator.h +++ b/TypeTranslator.h @@ -21,7 +21,7 @@ class TypeTranslator { */ std::string Translate(const clang::QualType& tpe, const std::string* = nullptr); std::string TranslateFunctionPointer(const clang::QualType& qtpe, const std::string* avoid ); - std::string TranslatePointer(const clang::PointerType* ptr, const std::string* avoid ); + std::string TranslatePointer(const clang::QualType& pointee, const std::string* avoid); std::string TranslateStructOrUnion(const clang::QualType& qtpe); std::string TranslateEnum(const clang::QualType& qtpe); std::string TranslateConstantArray(const clang::ConstantArrayType* ar, const std::string* avoid );