Skip to content

Commit 3fcefdc

Browse files
committed
Add a simple cycle detection system
1 parent 85a51bd commit 3fcefdc

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_clang_executable(scalaBindgen
1212
TypeTranslator.cpp
1313
HeaderManager.h
1414
HeaderManager.cpp
15+
CycleDetection.h
1516
Utils.h
1617
catch/catch.hpp
1718
SimpleTypeTests.cpp

CycleDetection.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
3+
#include "TypeTranslator.h"
4+
5+
#include <string>
6+
#include <map>
7+
#include <set>
8+
9+
class CycleDetection {
10+
private:
11+
TypeTranslator& tpeTransl;
12+
13+
bool contains(std::string& k){
14+
return !!dependencies.count(k);
15+
}
16+
17+
public:
18+
std::map<std::string, std::set<std::string> > dependencies;
19+
CycleDetection(TypeTranslator& tpeTransl_) : tpeTransl(tpeTransl_), dependencies{} {}
20+
21+
22+
void AddDependcy(std::string name, const clang::QualType& qtpe){
23+
24+
//TODO: function pointer
25+
26+
if(qtpe->isPointerType()){
27+
const clang::PointerType* ptr = qtpe.getTypePtr()->getAs<clang::PointerType>();
28+
AddDependcy(name, ptr->getPointeeType());
29+
return;
30+
}
31+
32+
std::string qtpeString = tpeTransl.Translate(qtpe);
33+
34+
//Add the dependence of qtpe
35+
if(contains(qtpeString)){
36+
dependencies[name].insert(dependencies[qtpeString].begin(), dependencies[qtpeString].end());
37+
}
38+
39+
dependencies[name].insert(qtpeString);
40+
}
41+
42+
43+
bool isCyclic(std::string& name){
44+
if(contains(name)){
45+
if(dependencies[name].count(name) != 0){
46+
return true;
47+
}
48+
}
49+
return false;
50+
}
51+
};

TreeVisitor.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,15 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){
128128
for(const clang::FieldDecl* field : record->fields()){
129129
std::string fname = handleReservedWords(field->getNameAsString());
130130
std::string ftype = typeTranslator.Translate(field->getType(), &name);
131-
132131
fields += ftype + ", ";
133-
if(name != ""){
132+
133+
if(fname != ""){
134134
helpersFunc += "\t\tdef " + fname + ": " + ftype + " = !p._" + std::to_string(fieldCnt + 1) + "\n";
135135
helpersFunc += "\t\tdef " + fname + "_=(value: " + ftype + "):Unit = !p._" + std::to_string(fieldCnt + 1) + " = value\n";
136136
}
137+
138+
cycleDetection.AddDependcy(newName, field->getType());
139+
137140
fieldCnt++;
138141
}
139142

@@ -142,6 +145,12 @@ bool TreeVisitor::VisitRecordDecl(clang::RecordDecl *record){
142145
fields = fields.substr(0, fields.size()-2);
143146
}
144147

148+
//llvm::errs() << newName << "\n";
149+
//for(auto& s : cycleDetection.dependencies[newName]){
150+
// llvm::errs() << "\t" << s << "\n";
151+
//}
152+
//llvm::errs() << cycleDetection.isCyclic(newName) << "\n";
153+
145154
if(fieldCnt < SCALA_NATIVE_MAX_STRUCT_FIELDS){
146155
declarations += "\ttype " + newName + " = " + "native.CStruct" + std::to_string(fieldCnt) + "[" + fields + "]\n";
147156
} else {

TreeVisitor.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "HeaderManager.h"
4+
#include "CycleDetection.h"
45
#include "TypeTranslator.h"
56

67
#include "clang/Driver/Options.h"
@@ -23,9 +24,11 @@ class TreeVisitor : public clang::RecursiveASTVisitor<TreeVisitor> {
2324
private:
2425
clang::ASTContext* astContext;
2526
TypeTranslator typeTranslator;
27+
CycleDetection cycleDetection;
28+
2629

2730
public:
28-
explicit TreeVisitor(clang::CompilerInstance *CI) : astContext(&(CI->getASTContext())), typeTranslator(astContext) {}
31+
explicit TreeVisitor(clang::CompilerInstance *CI) : astContext(&(CI->getASTContext())), typeTranslator(astContext), cycleDetection(typeTranslator) {}
2932

3033
virtual bool VisitFunctionDecl(clang::FunctionDecl *func);
3134
virtual bool VisitTypedefDecl(clang::TypedefDecl *tpdef);

0 commit comments

Comments
 (0)