Skip to content

Commit 4a463c4

Browse files
committed
Big re-organisation
1 parent 288a06b commit 4a463c4

File tree

7 files changed

+141
-112
lines changed

7 files changed

+141
-112
lines changed

CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ set(LLVM_LINK_COMPONENTS support)
33
add_compile_options(-fexceptions)
44

55
add_clang_executable(scalaBindgen
6-
ScalaBindgen.cpp
7-
ScalaBindgen.h
6+
Main.cpp
7+
ScalaFrontend.h
8+
TreeVisitor.h
9+
TreeVisitor.cpp
10+
TreeConsumer.h
811
TypeTranslator.h
912
TypeTranslator.cpp
1013
HeaderManager.h

Main.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "ScalaFrontend.h"
2+
#include "Utils.h"
3+
4+
#define CATCH_CONFIG_RUNNER
5+
#include "catch/catch.hpp"
6+
7+
static llvm::cl::OptionCategory Category("Binding Generator");
8+
static llvm::cl::extrahelp CommonHelp(clang::tooling::CommonOptionsParser::HelpMessage);
9+
static llvm::cl::extrahelp MoreHelp("\nProduce Bindings for scala native. Please specify lib name wit parameter name\n");
10+
static llvm::cl::opt<std::string> LibName("name", llvm::cl::cat(Category));
11+
static llvm::cl::opt<std::string> StdHeaders("stdHeaders", llvm::cl::cat(Category));
12+
13+
14+
int main(int argc, char *argv[]) {
15+
16+
if(argc <= 1 ){
17+
18+
int result = Catch::Session().run( argc, argv );
19+
return result;
20+
21+
} else{
22+
23+
clang::tooling::CommonOptionsParser op(argc, (const char**)argv, Category);
24+
clang::tooling::ClangTool Tool(op.getCompilations(), op.getSourcePathList());
25+
26+
auto lib = LibName.getValue();
27+
if(lib == ""){
28+
llvm::errs() << "Error: Please specify the lib name using -name paramter\n";
29+
return -1;
30+
}
31+
32+
auto stdhead = StdHeaders.getValue();
33+
if(stdhead != ""){
34+
headerMan.LoadConfig(stdhead);
35+
}
36+
37+
declarations = "";
38+
enums = "";
39+
helpers = "";
40+
41+
int result = Tool.run(clang::tooling::newFrontendActionFactory<ScalaFrontendAction>().get());
42+
43+
llvm::outs() << "import scala.scalanative._\n"
44+
<< "import scala.scalanative.native.Nat._\n\n";
45+
46+
if(declarations != ""){
47+
llvm::outs() << "@native.link(\"" << lib << "\")\n"
48+
<< "@native.extern\n"
49+
<< "object " << lib << " {\n"
50+
<< declarations
51+
<< "}\n\n"
52+
<< "import " + lib + "._\n\n";
53+
}
54+
55+
if(enums != ""){
56+
llvm::outs() << "object " << lib << "Enums {\n"
57+
<< enums
58+
<< "}\n\n";
59+
}
60+
61+
if(helpers != ""){
62+
llvm::outs() << "object " << lib << "Helpers {\n"
63+
<< helpers
64+
<< "}\n\n";
65+
}
66+
67+
return result;
68+
}
69+
}

ScalaFrontend.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "TreeConsumer.h"
2+
3+
#include "clang/Driver/Options.h"
4+
#include "clang/Basic/LangOptions.h"
5+
#include "clang/AST/AST.h"
6+
#include "clang/AST/ASTContext.h"
7+
#include "clang/AST/ASTConsumer.h"
8+
#include "clang/AST/RecursiveASTVisitor.h"
9+
#include "clang/Frontend/ASTConsumers.h"
10+
#include "clang/Frontend/FrontendActions.h"
11+
#include "clang/Frontend/CompilerInstance.h"
12+
#include "clang/Tooling/CommonOptionsParser.h"
13+
#include "clang/Tooling/Tooling.h"
14+
#include "llvm/Support/CommandLine.h"
15+
16+
class ScalaFrontendAction : public clang::ASTFrontendAction {
17+
public:
18+
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &CI, clang::StringRef file) {
19+
return std::unique_ptr<clang::ASTConsumer>(new TreeConsumer(&CI)); // pass CI pointer to ASTConsumer
20+
}
21+
};

SimpleTypeTests.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#include "ScalaBindgen.h"
2-
1+
#include "ScalaFrontend.h"
32

43
#include "clang/Tooling/Tooling.h"
54
#include "catch/catch.hpp"
@@ -10,7 +9,7 @@ std::string Translate(std::string code){
109
declarations = "";
1110
enums = "";
1211
helpers = "";
13-
auto* action = new ExampleFrontendAction;
12+
auto* action = new ScalaFrontendAction;
1413
clang::tooling::runToolOnCode(action, code, "input.h");
1514
return declarations;
1615
}

ScalaBindgen.h renamed to TreeConsumer.h

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,14 @@
1+
#pragma once
2+
3+
#include "TreeVisitor.h"
14
#include "Utils.h"
2-
#include "TypeTranslator.h"
3-
#include "HeaderManager.h"
45

5-
#include "clang/Driver/Options.h"
6-
#include "clang/Basic/LangOptions.h"
76
#include "clang/AST/AST.h"
87
#include "clang/AST/ASTContext.h"
98
#include "clang/AST/ASTConsumer.h"
109
#include "clang/AST/RecursiveASTVisitor.h"
1110
#include "clang/Frontend/ASTConsumers.h"
12-
#include "clang/Frontend/FrontendActions.h"
1311
#include "clang/Frontend/CompilerInstance.h"
14-
#include "clang/Tooling/CommonOptionsParser.h"
15-
#include "clang/Tooling/Tooling.h"
16-
#include "llvm/Support/CommandLine.h"
17-
18-
extern std::string declarations;
19-
extern std::string enums;
20-
extern std::string helpers;
21-
22-
class TreeVisitor : public clang::RecursiveASTVisitor<TreeVisitor> {
23-
private:
24-
clang::ASTContext* astContext;
25-
TypeTranslator typeTranslator;
26-
27-
public:
28-
explicit TreeVisitor(clang::CompilerInstance *CI) : astContext(&(CI->getASTContext())), typeTranslator(astContext) {}
29-
30-
virtual bool VisitFunctionDecl(clang::FunctionDecl *func);
31-
virtual bool VisitTypedefDecl(clang::TypedefDecl *tpdef);
32-
virtual bool VisitEnumDecl(clang::EnumDecl *enumdecl);
33-
virtual bool VisitRecordDecl(clang::RecordDecl *record);
34-
};
3512

3613
class TreeConsumer : public clang::ASTConsumer {
3714
private:
@@ -101,10 +78,3 @@ class TreeConsumer : public clang::ASTConsumer {
10178
}*/
10279

10380
};
104-
105-
class ExampleFrontendAction : public clang::ASTFrontendAction {
106-
public:
107-
virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &CI, clang::StringRef file) {
108-
return std::unique_ptr<clang::ASTConsumer>(new TreeConsumer(&CI)); // pass CI pointer to ASTConsumer
109-
}
110-
};

ScalaBindgen.cpp renamed to TreeVisitor.cpp

Lines changed: 8 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
1-
#include "ScalaBindgen.h"
2-
3-
#define CATCH_CONFIG_RUNNER
4-
#include "catch/catch.hpp"
5-
1+
#include "TreeVisitor.h"
2+
#include "Utils.h"
63

74
#define SCALA_NATIVE_MAX_STRUCT_FIELDS 22
85

9-
10-
static llvm::cl::OptionCategory Category("Binding Generator");
11-
static llvm::cl::extrahelp CommonHelp(clang::tooling::CommonOptionsParser::HelpMessage);
12-
static llvm::cl::extrahelp MoreHelp("\nProduce Bindings for scala native. Please specify lib name wit parameter name\n");
13-
static llvm::cl::opt<std::string> LibName("name", llvm::cl::cat(Category));
14-
static llvm::cl::opt<std::string> StdHeaders("stdHeaders", llvm::cl::cat(Category));
15-
16-
176
HeaderManager headerMan;
187

198
std::string declarations;
@@ -104,8 +93,10 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){
10493

10594
} else if (record->isStruct() && record->isThisDeclarationADefinition() && !record->isAnonymousStructOrUnion() && name != ""){
10695

96+
std::string newName = "struct_" + name;
97+
10798
//Replace "struct x" with struct_x in scala
108-
typeTranslator.AddTranslation("struct " + name, "struct_"+name);
99+
typeTranslator.AddTranslation("struct " + name, newName);
109100

110101
int fieldCnt = 0;
111102
std::string fields = "";
@@ -129,17 +120,17 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){
129120
}
130121

131122
if(fieldCnt < SCALA_NATIVE_MAX_STRUCT_FIELDS){
132-
declarations += "\ttype struct_" + name + " = " + "native.CStruct" + std::to_string(fieldCnt) + "[" + fields + "]\n";
123+
declarations += "\ttype " + newName + " = " + "native.CStruct" + std::to_string(fieldCnt) + "[" + fields + "]\n";
133124
} else {
134125
//There is no easy way to represent it as a struct in scala native, have to represent it as an array and then
135126
//Add helpers to help with it's manipulation
136127
uint64_t size = astContext->getTypeSize(record->getTypeForDecl());
137-
declarations += "\ttype struct_" + name + " = " + "native.CArray[Byte, " + uint64ToScalaNat(size) + "]\n";
128+
declarations += "\ttype " + newName + " = " + "native.CArray[Byte, " + uint64ToScalaNat(size) + "]\n";
138129
}
139130

140131
//Create helpers in an implicit class
141132
if(fieldCnt > 0 && fieldCnt < SCALA_NATIVE_MAX_STRUCT_FIELDS){
142-
helpers += "\timplicit class struct_" + name + "_ops(val p: native.Ptr[struct_" + name + "]) extends AnyVal {\n";
133+
helpers += "\timplicit class " + newName + "_ops(val p: native.Ptr[struct_" + name + "]) extends AnyVal {\n";
143134
helpers += helpersFunc;
144135
helpers += "\t}\n\n";
145136
}
@@ -148,60 +139,3 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){
148139
}
149140
return false;
150141
}
151-
152-
int main(int argc, char *argv[]) {
153-
154-
if(argc <= 1 ){
155-
156-
int result = Catch::Session().run( argc, argv );
157-
return result;
158-
159-
} else{
160-
161-
clang::tooling::CommonOptionsParser op(argc, (const char**)argv, Category);
162-
clang::tooling::ClangTool Tool(op.getCompilations(), op.getSourcePathList());
163-
164-
auto lib = LibName.getValue();
165-
if(lib == ""){
166-
llvm::errs() << "Error: Please specify the lib name using -name paramter\n";
167-
return -1;
168-
}
169-
170-
auto stdhead = StdHeaders.getValue();
171-
if(stdhead != ""){
172-
headerMan.LoadConfig(stdhead);
173-
}
174-
175-
declarations = "";
176-
enums = "";
177-
helpers = "";
178-
179-
int result = Tool.run(clang::tooling::newFrontendActionFactory<ExampleFrontendAction>().get());
180-
181-
llvm::outs() << "import scala.scalanative._\n"
182-
<< "import scala.scalanative.native.Nat._\n\n";
183-
184-
if(declarations != ""){
185-
llvm::outs() << "@native.link(\"" << lib << "\")\n"
186-
<< "@native.extern\n"
187-
<< "object " << lib << " {\n"
188-
<< declarations
189-
<< "}\n\n"
190-
<< "import " + lib + "._\n\n";
191-
}
192-
193-
if(enums != ""){
194-
llvm::outs() << "object " << lib << "Enums {\n"
195-
<< enums
196-
<< "}\n\n";
197-
}
198-
199-
if(helpers != ""){
200-
llvm::outs() << "object " << lib << "Helpers {\n"
201-
<< helpers
202-
<< "}\n\n";
203-
}
204-
205-
return result;
206-
}
207-
}

TreeVisitor.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#pragma once
2+
3+
#include "HeaderManager.h"
4+
#include "TypeTranslator.h"
5+
6+
#include "clang/Driver/Options.h"
7+
#include "clang/Basic/LangOptions.h"
8+
#include "clang/AST/AST.h"
9+
#include "clang/AST/ASTContext.h"
10+
#include "clang/AST/ASTConsumer.h"
11+
#include "clang/AST/RecursiveASTVisitor.h"
12+
#include "clang/Frontend/ASTConsumers.h"
13+
#include "clang/Frontend/CompilerInstance.h"
14+
15+
extern HeaderManager headerMan;
16+
17+
extern std::string declarations;
18+
extern std::string enums;
19+
extern std::string helpers;
20+
21+
class TreeVisitor : public clang::RecursiveASTVisitor<TreeVisitor> {
22+
private:
23+
clang::ASTContext* astContext;
24+
TypeTranslator typeTranslator;
25+
26+
public:
27+
explicit TreeVisitor(clang::CompilerInstance *CI) : astContext(&(CI->getASTContext())), typeTranslator(astContext) {}
28+
29+
virtual bool VisitFunctionDecl(clang::FunctionDecl *func);
30+
virtual bool VisitTypedefDecl(clang::TypedefDecl *tpdef);
31+
virtual bool VisitEnumDecl(clang::EnumDecl *enumdecl);
32+
virtual bool VisitRecordDecl(clang::RecordDecl *record);
33+
};

0 commit comments

Comments
 (0)