├── .gitignore ├── examples ├── adder.c ├── filter.c ├── for_if.c ├── filter.v ├── subset_sum.c ├── subset_sum.v ├── small_tsp.c ├── max_cut.c ├── max_cut.v └── map_color.c ├── README.md ├── Makefile ├── LICENSE.md └── src └── rewritersample.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /examples/adder.c: -------------------------------------------------------------------------------- 1 | int adder(int in1 , int in2) 2 | { 3 | return in1+in2; 4 | } 5 | -------------------------------------------------------------------------------- /examples/filter.c: -------------------------------------------------------------------------------- 1 | int dummy (int a) 2 | { 3 | register int val; 4 | int i; 5 | val = 0; 6 | for (i = 0; i < 4; i++) 7 | { 8 | val += a; 9 | } 10 | return val; 11 | } 12 | -------------------------------------------------------------------------------- /examples/for_if.c: -------------------------------------------------------------------------------- 1 | int for_if(int in1 , int in2) 2 | { 3 | int arr[5]; 4 | int total; 5 | int reg_i; 6 | for(reg_i = 0; reg_i<5; reg_i=reg_i+1) 7 | { 8 | arr[reg_i]=reg_i; 9 | } 10 | bool check; 11 | check = (in1>in2); 12 | if(check) 13 | { 14 | total = arr[0] + arr[1] + arr[2] + arr[3] + arr[4]; 15 | } 16 | else 17 | { 18 | total = in1 + in2; 19 | } 20 | return total; 21 | } 22 | -------------------------------------------------------------------------------- /examples/filter.v: -------------------------------------------------------------------------------- 1 | /* DWave-c2v: source to source translation of C-code to verilog-code compliant with edif2qmasm using clang tools */ 2 | 3 | // Begin conversion of 'dummy' to Verilog 4 | module dummy ( 5 | input [4:0] a, 6 | output [4:0] result ) 7 | ; 8 | wire [4:0] i; 9 | reg [4:0] val; 10 | always@* 11 | begin 12 | val = 0; 13 | for (i = 0; i < 4; i++) 14 | begin 15 | val += a; 16 | end 17 | result = val; 18 | end 19 | endmodule 20 | // End of 'dummy' 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | C-to-D-Wave 2 | =========== 3 | 4 | Description 5 | ----------- 6 | 7 | This program compiles C programs, written using a very small subset of C, to a form suitable for running on a D-Wave quantum annealer by translating through Verilog to D-Wave APIs. 8 | 9 | Status 10 | ------ 11 | 12 | The code is still pre-alpha and should therefore be considered unfit for human consumption. 13 | 14 | License 15 | ------- 16 | 17 | BSD 3-Clause Clear. See [LICENSE.md](LICENSE.md) for the full text. 18 | 19 | Triad National Security, LLC owns the copyright to C-to-D-Wave (identified internally as C18102). 20 | -------------------------------------------------------------------------------- /examples/subset_sum.c: -------------------------------------------------------------------------------- 1 | bool partial_sum(int a , int b , int c , int psum) 2 | { 3 | bool valid[2]; 4 | int arr[4]; 5 | int sum; 6 | int reg_i; 7 | bool ch1; 8 | bool ch2; 9 | bool ch3; 10 | //initialize the array 11 | for (reg_i=0;reg_i<4;reg_i++) 12 | { 13 | arr[reg_i]=reg_i; 14 | } 15 | sum = arr[a] + arr[b] + arr[c]; 16 | if((sum == psum) && a<4 && b<4 && c<4) 17 | valid[0] = 1; 18 | else 19 | valid[0] = 0; 20 | 21 | ch1 = a !=b ? 1 : (a !=0 ? 1 : 0); 22 | ch2 = a !=c ? 1 : (a !=0 ? 1 : 0); 23 | ch3 = c !=b ? 1 : (a !=0 ? 1 : 0); 24 | 25 | if(valid[0] && ch1 && ch2 && ch3) 26 | { 27 | valid[1] = 1; 28 | } 29 | else 30 | { 31 | valid[1] = 0; 32 | } 33 | return valid[1]; 34 | } 35 | -------------------------------------------------------------------------------- /examples/subset_sum.v: -------------------------------------------------------------------------------- 1 | /* DWave-c2v: source to source translation of C-code to verilog-code compliant with edif2qmasm using clang tools */ 2 | 3 | // Begin conversion of 'partial_sum' to Verilog 4 | module partial_sum( 5 | input [4:0] a , 6 | input [4:0] b , 7 | input [4:0] c , 8 | input [4:0] psum, 9 | output result ) 10 | ; 11 | wire ch3; 12 | wire ch2; 13 | wire ch1; 14 | wire [4:0] reg_i; 15 | wire [4:0] sum; 16 | wire [4:0] arr [3:0]; 17 | wire valid [1:0]; 18 | always@* 19 | begin 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | //initialize the array 28 | for (reg_i=0;reg_i<4;reg_i= reg_i + 1) 29 | begin 30 | arr[reg_i]=reg_i; 31 | end 32 | sum = arr[a] + arr[b] + arr[c]; 33 | if((sum == psum) && a<4 && b<4 && c<4) 34 | begin 35 | valid[0] = 1; 36 | end 37 | else 38 | begin 39 | valid[0] = 0; 40 | end 41 | 42 | ch1 = a !=b ? 1 : (a !=0 ? 1 : 0); 43 | ch2 = a !=c ? 1 : (a !=0 ? 1 : 0); 44 | ch3 = c !=b ? 1 : (a !=0 ? 1 : 0); 45 | 46 | if(valid[0] && ch1 && ch2 && ch3) 47 | begin 48 | valid[1] = 1; 49 | end 50 | else 51 | begin 52 | valid[1] = 0; 53 | end 54 | result = valid[1]; 55 | end 56 | endmodule 57 | // End of 'partial_sum' 58 | 59 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ##################################### 2 | # Build the C-to-Verilog translator # 3 | ##################################### 4 | 5 | LLVM_CXXFLAGS = $(shell llvm-config --cxxflags) 6 | LLVM_LDFLAGS = $(shell llvm-config --ldflags --libs --system-libs) 7 | 8 | CLANG_LIBS = \ 9 | -Wl,--start-group \ 10 | -lclangAST \ 11 | -lclangASTMatchers \ 12 | -lclangAnalysis \ 13 | -lclangBasic \ 14 | -lclangDriver \ 15 | -lclangEdit \ 16 | -lclangFrontend \ 17 | -lclangFrontendTool \ 18 | -lclangLex \ 19 | -lclangParse \ 20 | -lclangSema \ 21 | -lclangEdit \ 22 | -lclangRewrite \ 23 | -lclangRewriteFrontend \ 24 | -lclangStaticAnalyzerFrontend \ 25 | -lclangStaticAnalyzerCheckers \ 26 | -lclangStaticAnalyzerCore \ 27 | -lclangCrossTU \ 28 | -lclangIndex \ 29 | -lclangSerialization \ 30 | -lclangToolingCore \ 31 | -lclangTooling \ 32 | -lclangFormat \ 33 | -Wl,--end-group 34 | 35 | SRCDIR = src 36 | BUILDDIR = build 37 | 38 | .PHONY: all 39 | 40 | all: $(BUILDDIR)/rewritersample 41 | 42 | .PHONY: make_builddir 43 | 44 | make_builddir: 45 | @test -d $(BUILDDIR) || mkdir $(BUILDDIR) 46 | 47 | $(BUILDDIR)/rewritersample: make_builddir $(SRCDIR)/rewritersample.cpp 48 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) \ 49 | $(SRCDIR)/rewritersample.cpp \ 50 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 51 | 52 | .PHONY: clean 53 | 54 | clean: 55 | $(RM) -r $(BUILDDIR) 56 | -------------------------------------------------------------------------------- /examples/small_tsp.c: -------------------------------------------------------------------------------- 1 | /* Travelling Salesman Problem (decision version) 2 | 3 | The Travelling Salesman decision problem is: 4 | "Given a weighted graph (G) and an integereger (tspdsist), Is there a round trip hamiltonian path cost at least (tspdist) in (G)?" 5 | We solve this for the following, hard-wired graph (inside edge weights are for clockwise path, outside weights are for counter clockwise path) 6 | The output is the order of cities to be visited, where each city i.e a=>3 means that city 'a' is the third city to be visited. 7 | 8 | A 9 | 3_/ | 10 | 1 /1 | 11 | S----C 1|1 12 | \_1 | 13 | 2\ | 14 | B 15 | 16 | Author: Mohamed Hassan 17 | */ 18 | 19 | bool TSP (int a, int b, int c, int tspdist) 20 | { 21 | bool valid; 22 | int arr_s [4]; 23 | int arr_a [4]; 24 | int arr_b [4]; 25 | int arr_c [4]; 26 | 27 | 28 | //starting city S costs 29 | arr_s[0] = 31; 30 | arr_s[1] = 31; 31 | arr_s[2] = 31; 32 | arr_s[3] = 1; 33 | //City A costs 34 | arr_a[0] = 31; 35 | arr_a[1] = 31; 36 | arr_a[2] = 1; 37 | arr_a[3] = 1; 38 | //City B costs 39 | arr_b[0] = 31; 40 | arr_b[1] = 1; 41 | arr_b[2] = 31; 42 | arr_b[3] = 2; 43 | //City C costs 44 | arr_c[0] = 1; 45 | arr_c[1] = 3; 46 | arr_c[2] = 1; 47 | arr_c[3] = 31; 48 | 49 | int totcost; 50 | totcost = arr_s[3] + arr_a[a] + arr_b[b] + arr_c[c]; 51 | 52 | 53 | if(totcost 0 && b > 0 && c > 0 && a < 4 && b < 4 && c < 4 && a != b && a != c && c != b) 54 | { 55 | valid = 1; 56 | } 57 | else 58 | { 59 | valid = 0; 60 | } 61 | return valid; 62 | } 63 | -------------------------------------------------------------------------------- /examples/max_cut.c: -------------------------------------------------------------------------------- 1 | bool max_cut (bool a,bool b,bool c,bool d,bool e) 2 | { 3 | register bool valid; 4 | int cut; 5 | register int reg_temp; 6 | register int reg_i; 7 | register int reg_j; 8 | register int reg_x; 9 | register int reg_y; 10 | register int reg_z; 11 | register bool shit; 12 | register bool shittt; 13 | bool shit1; 14 | bool shit2; 15 | register bool shit3; 16 | 17 | 18 | valid=0; 19 | cut = 4; 20 | reg_temp = 0; 21 | reg_temp /= cut; 22 | //bool in_val[5]; 23 | //bool arr[5][5]; 24 | //take input colors in an array of integers; this is step won't be necessary once we can support input arrays 25 | in_val[0] = a; 26 | in_val[1] = b; 27 | in_val[2] = c; 28 | in_val[3] = d; 29 | in_val[4] = e; 30 | 31 | 32 | 33 | //initialize the 2d array with the connectivity between cities 34 | //zero out the rest of the 2d array 35 | for (reg_i=0; reg_i < 5; reg_i++) 36 | { 37 | for(reg_j = 0; reg_j < 5; reg_j = reg_j + 1) 38 | { 39 | if((reg_i==0 && reg_j==1) || (reg_i==0 && reg_j==2) || (reg_i==0 && reg_j==3) || (reg_i==1 && reg_j==0) || (reg_i==1 && reg_j==4) || (reg_i==2 && reg_j==0) || (reg_i==2 && reg_j==3) || (reg_i==3 && reg_j==0) || (reg_i==3 && reg_j==2) || (reg_i==3 && reg_j==4) || (reg_i==4 && reg_j==1) || (reg_i==4 && reg_j==3)) 40 | { 41 | arr[reg_i][reg_j] = 1; 42 | } 43 | else 44 | { 45 | arr[reg_i][reg_j] = 0; 46 | } 47 | } 48 | } 49 | 50 | //iterate on nodes 51 | for (int reg_x = 0 ; reg_x < 5 ; reg_x = reg_x + 1) 52 | { 53 | for (int reg_y = 0 ; reg_y < 5 ; reg_y = reg_y + 1) 54 | { 55 | //if a city is assigned a color greater than the number of colors, then invalidate that input 56 | //if cities are connected and have same color, then invalidate the repective input 57 | if( (arr[reg_x][reg_y] == 1) && (in_val[reg_x] != in_val[reg_y]) ) 58 | { 59 | reg_temp=reg_temp+1; 60 | } 61 | } 62 | } 63 | if(reg_temp>=2*cut) 64 | { 65 | valid = 1; 66 | } 67 | else 68 | { 69 | valid = 0; 70 | } 71 | return valid; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This software is open source software available under the BSD-3 Clear license. 2 | 3 | Copyright © 2018 Triad National Security, LLC. 4 | All rights reserved. 5 | 6 | This software was produced under U.S. Government contract 89233218CNA000001 at Los Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC for the U.S. Department of Energy/National Nuclear Security Administration. The U.S. Government has rights to use, reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR TRIAD NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to produce derivative works, such modified software should be clearly marked, so as not to confuse it with the version available from LANL. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Triad, LLC, Los Alamos National Laboratory, LANL, the U.S. Government, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 15 | 16 | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 | -------------------------------------------------------------------------------- /examples/max_cut.v: -------------------------------------------------------------------------------- 1 | /* DWave-c2v: source to source translation of C-code to verilog-code compliant with edif2qmasm using clang tools */ 2 | 3 | // Begin conversion of 'max_cut' to Verilog 4 | module max_cut ( 5 | input a, 6 | input b, 7 | input c, 8 | input d, 9 | input e, 10 | output result ) 11 | ; 12 | reg shit3; 13 | wire shit2; 14 | wire shit1; 15 | reg shittt; 16 | reg shit; 17 | reg [4:0] reg_z; 18 | reg [4:0] reg_y; 19 | reg [4:0] reg_x; 20 | reg [4:0] reg_j; 21 | reg [4:0] reg_i; 22 | reg [4:0] reg_temp; 23 | wire [4:0] cut; 24 | reg valid; 25 | always@* 26 | begin 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | valid=0; 43 | cut = 4; 44 | reg_temp = 0; 45 | reg_temp = reg_temp / cut; 46 | //bool in_val[5]; 47 | //bool arr[5][5]; 48 | //take input colors in an array of integers; this is step won't be necessary once we can support input arrays 49 | in_val[0] = a; 50 | in_val[1] = b; 51 | in_val[2] = c; 52 | in_val[3] = d; 53 | in_val[4] = e; 54 | 55 | 56 | 57 | //initialize the 2d array with the connectivity between cities 58 | //zero out the rest of the 2d array 59 | for (reg_i=0; reg_i < 5; reg_i= reg_i + 1) 60 | begin 61 | for(reg_j = 0; reg_j < 5; reg_j = reg_j + 1) 62 | begin 63 | if((reg_i==0 && reg_j==1) || (reg_i==0 && reg_j==2) || (reg_i==0 && reg_j==3) || (reg_i==1 && reg_j==0) || (reg_i==1 && reg_j==4) || (reg_i==2 && reg_j==0) || (reg_i==2 && reg_j==3) || (reg_i==3 && reg_j==0) || (reg_i==3 && reg_j==2) || (reg_i==3 && reg_j==4) || (reg_i==4 && reg_j==1) || (reg_i==4 && reg_j==3)) 64 | begin 65 | arr[reg_i][reg_j] = 1; 66 | end 67 | else 68 | begin 69 | arr[reg_i][reg_j] = 0; 70 | end 71 | end 72 | end 73 | 74 | //iterate on nodes 75 | for ( reg_x = 0 ; reg_x < 5 ; reg_x = reg_x + 1) 76 | begin 77 | for ( reg_y = 0 ; reg_y < 5 ; reg_y = reg_y + 1) 78 | begin 79 | //if a city is assigned a color greater than the number of colors, then invalidate that input 80 | //if cities are connected and have same color, then invalidate the repective input 81 | if( (arr[reg_x][reg_y] == 1) && (in_val[reg_x] != in_val[reg_y]) ) 82 | begin 83 | reg_temp=reg_temp+1; 84 | end 85 | end 86 | end 87 | if(reg_temp>=2*cut) 88 | begin 89 | valid = 1; 90 | end 91 | else 92 | begin 93 | valid = 0; 94 | end 95 | result = valid; 96 | end 97 | endmodule 98 | // End of 'max_cut' 99 | 100 | 101 | -------------------------------------------------------------------------------- /examples/map_color.c: -------------------------------------------------------------------------------- 1 | /* 2 | Map of canada.............. 3 | 4 | NL=>0-----connected to ON(1),PE(5) 5 | ON=>1-----connected to NL(0),MB(2),QC(6) 6 | MB=>2-----connected to ON(1),SK(3),NU(7) 7 | SK=>3-----connected to MB(2),AB(4),NT(8) 8 | AB=>4-----connected to SK(3),NT(8),BC(11) 9 | PE=>5-----connected to NL(0),QC(6) 10 | QC=>6-----connected to ON(1),PE(5),NU(7),NB(9) 11 | NU=>7-----connected to MB(2),QC(6),NT(8),NS(10) 12 | NT=>8-----connected to SK(3),AB(4),NU(7),NS(10),BC(11),YT(12) 13 | NB=>9-----connected to QC(6),NS(10) 14 | NS=>10-----connected to NU(7),NT(8),NB(9) 15 | BC=>11-----connected to AB(4),NT(8),YT(12) 16 | YT=>12-----connected to NT(8),BC(11) 17 | 18 | arr[0][1] = 1; 19 | arr[0][5] = 1; 20 | 21 | arr[1][0] = 1; 22 | arr[1][2] = 1; 23 | arr[1][6] = 1; 24 | 25 | arr[2][1] = 1; 26 | arr[2][3] = 1; 27 | arr[2][7] = 1; 28 | 29 | arr[3][2] = 1; 30 | arr[3][4] = 1; 31 | arr[3][8] = 1; 32 | 33 | arr[4][3] = 1; 34 | arr[4][8] = 1; 35 | 36 | arr[5][0] = 1; 37 | arr[5][6] = 1; 38 | 39 | arr[6][1] = 1; 40 | arr[6][5] = 1; 41 | arr[6][7] = 1; 42 | arr[6][9] = 1; 43 | 44 | 45 | arr[7][2] = 1; 46 | arr[7][6] = 1; 47 | arr[7][8] = 1; 48 | 49 | arr[8][3] = 1; 50 | arr[8][4] = 1; 51 | arr[8][7] = 1; 52 | 53 | arr[9][6] = 1; 54 | 55 | */ 56 | 57 | bool map_color (int NL,int ON,int MB,int SK,int AB,int PE,int QC,int NU,int NT,int NB) 58 | { 59 | bool reg_valid; 60 | int in_val[10]; 61 | bool arr[10][10]; 62 | bool check[10][10]; 63 | 64 | int reg_a; 65 | int reg_b; 66 | int reg_i; 67 | int reg_j; 68 | int reg_x; 69 | int reg_y; 70 | 71 | int colors; 72 | 73 | colors = 4; 74 | 75 | 76 | 77 | //take input colors in an array of integers; this is step won't be necessary once we can support input arrays 78 | in_val[0] = NL; 79 | in_val[1] = ON; 80 | in_val[2] = MB; 81 | in_val[3] = SK; 82 | in_val[4] = AB; 83 | in_val[5] = PE; 84 | in_val[6] = QC; 85 | in_val[7] = NU; 86 | in_val[8] = NT; 87 | in_val[9] = NB; 88 | 89 | 90 | //initialize the 2d array with the connectivity between cities 91 | 92 | 93 | //zero out the rest of the 2d array 94 | for (int reg_i=0; reg_i < 10; reg_i = reg_i + 1) 95 | { 96 | for(int reg_j = 0; reg_j < 10; reg_j = reg_j + 1) 97 | { 98 | if((reg_i==0 && reg_j==1) || (reg_i==0 && reg_j==5) || (reg_i==1 && reg_j==0) || (reg_i==1 && reg_j==2) || (reg_i==1 && reg_j==6) || (reg_i==2 && reg_j==1) || (reg_i==2 && reg_j==3) || (reg_i==2 && reg_j==7) || (reg_i==3 && reg_j==2) || (reg_i==3 && reg_j==4) || (reg_i==3 && reg_j==8) || (reg_i==4 && reg_j==3) || (reg_i==4 && reg_j==8) || (reg_i==5 && reg_j==0) || (reg_i==5 && reg_j==6) || (reg_i==6 && reg_j==1) || (reg_i==6 && reg_j==5) || (reg_i==6 && reg_j==7) || (reg_i==6 && reg_j==9) || (reg_i==7 && reg_j==2) || (reg_i==7 && reg_j==6) || (reg_i==7 && reg_j==8) || (reg_i==8 && reg_j==3) || (reg_i==8 && reg_j==4) || (reg_i==8 && reg_j==7) || (reg_i==9 && reg_j==6)) 99 | { 100 | arr[reg_i][reg_j] = 1; 101 | } 102 | else 103 | { 104 | arr[reg_i][reg_j] = 0; 105 | } 106 | } 107 | } 108 | 109 | //iterate on cities 110 | for (int reg_x = 0 ; reg_x < 10 ; reg_x = reg_x + 1) 111 | { 112 | for (int reg_y = 0 ; reg_y < 10 ; reg_y = reg_y + 1) 113 | { 114 | //if reg_a city is assigned reg_a color greater than the number of colors, then invalidate that input 115 | //if cities are connected and have same color, then invalidate the repective input 116 | if(((arr[reg_x][reg_y] == 1) && (in_val[reg_x] == in_val[reg_y])) || (in_val[reg_x] > colors) || (in_val[reg_y] > colors)) 117 | { 118 | check[reg_x][reg_y] = 0; 119 | } 120 | else 121 | { 122 | check[reg_x][reg_y] = 1; 123 | } 124 | } 125 | } 126 | for (reg_a=0;reg_a<10;reg_a=reg_a+1) 127 | { 128 | for (reg_b=0;reg_b<10;reg_b=reg_b+1) 129 | { 130 | reg_valid = reg_valid && check[reg_a][reg_b]; 131 | } 132 | } 133 | return reg_valid; 134 | } 135 | 136 | -------------------------------------------------------------------------------- /src/rewritersample.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "clang/AST/ASTConsumer.h" 7 | #include "clang/AST/RecursiveASTVisitor.h" 8 | #include "clang/Basic/Diagnostic.h" 9 | #include "clang/Basic/FileManager.h" 10 | #include "clang/Basic/SourceManager.h" 11 | #include "clang/Basic/TargetInfo.h" 12 | #include "clang/Basic/TargetOptions.h" 13 | #include "clang/Frontend/CompilerInstance.h" 14 | #include "clang/Lex/Preprocessor.h" 15 | #include "clang/Parse/ParseAST.h" 16 | #include "clang/Rewrite/Core/Rewriter.h" 17 | #include "clang/Rewrite/Frontend/Rewriters.h" 18 | #include "llvm/Support/Host.h" 19 | #include "llvm/Support/raw_ostream.h" 20 | 21 | using namespace clang; 22 | 23 | class MyASTVisitor : public RecursiveASTVisitor { 24 | public: 25 | MyASTVisitor(Rewriter &R, CompilerInstance *CI) : TheRewriter(R), astContext(&(CI->getASTContext())) {} 26 | 27 | 28 | //#### check if the variable declaration is preceeded by a for stmt. If yes then genvar will take car of the variable declaration 29 | bool checkfor(const Stmt *D) 30 | { 31 | //get parents 32 | const auto& parents = astContext->getParents(*D); 33 | if ( parents.empty() ) { 34 | llvm::errs() << "Can not find parent\n"; 35 | return false; 36 | } 37 | //llvm::errs() << "find parent size=" << parents.size() << "\n"; 38 | const Stmt *ST = parents[0].get(); 39 | if (isa(ST)) 40 | { 41 | //llvm::errs() << "declaration in for loop " << "\n"; 42 | return true; 43 | } 44 | else 45 | return false; 46 | } 47 | 48 | //#### InstrumentStmt - Add braces to line of code 49 | void InstrumentStmt(Stmt *s) 50 | { 51 | //instrument if or else body start 52 | SourceLocation ST = s->getLocStart(); 53 | int offset1 = Lexer::MeasureTokenLength(ST, TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()); 54 | SourceLocation END = s->getLocEnd(); 55 | int offset2 = Lexer::MeasureTokenLength(END, TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()); 56 | if(isa(s)) 57 | { 58 | TheRewriter.RemoveText(ST,offset1); 59 | TheRewriter.InsertText(ST, "begin", true, true); 60 | TheRewriter.RemoveText(END,offset2); 61 | TheRewriter.InsertText(END, "end", true, true); 62 | } 63 | else 64 | { 65 | TheRewriter.InsertText(ST, "begin\n", true, true); 66 | END = END.getLocWithOffset(offset2+1); 67 | TheRewriter.InsertText(END, "\nend", true, true); 68 | } 69 | 70 | } 71 | 72 | //#### InstrumentFor - Add the for loop generator code 73 | void InstrumentFor(Stmt *s, ForStmt *f) 74 | { 75 | //get for body starting location 76 | SourceLocation ST = s->getLocStart(); 77 | int offset1 = Lexer::MeasureTokenLength(ST, TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()); 78 | //instrument body start 79 | TheRewriter.RemoveText(ST,offset1); 80 | TheRewriter.InsertText(ST, "begin", true, true); 81 | //get for body end location 82 | SourceLocation END = s->getLocEnd(); 83 | //int offset = Lexer::MeasureTokenLength(END, TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()) + 1; 84 | int offset2 = Lexer::MeasureTokenLength(END, TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()); 85 | //instrument body end 86 | //SourceLocation END1 = END.getLocWithOffset(offset); 87 | TheRewriter.RemoveText(END,offset2); 88 | //TheRewriter.InsertText(END, "end \nendgenerate\n", true, true); 89 | TheRewriter.InsertText(END, "end", true, true); 90 | 91 | //start the genvar attribute 92 | /*char gen[256]; 93 | std::string var; 94 | const DeclStmt *DS = dyn_cast(f->getInit()); 95 | 96 | for (auto *DI : DS->decls()) 97 | { 98 | VarDecl *VD = dyn_cast(DI); 99 | if (VD) 100 | { 101 | //llvm::errs() << "varrrrrrrr " << VD->getDeclName().getAsString() << "\n"; 102 | var = VD->getDeclName().getAsString(); 103 | } 104 | } 105 | 106 | sprintf(gen,"genvar %s;\ngenerate\n",var.c_str()); 107 | 108 | SourceLocation FT = f->getLocStart(); 109 | TheRewriter.InsertText(FT, gen,true,true);*/ 110 | 111 | } 112 | 113 | //#### check all children of the if stmt to look for variables to add to the always @ block 114 | void checkif(Stmt *If) 115 | { 116 | for (auto *DI : If->children()) 117 | { 118 | //Stmt *st = dyn_cast(DI); 119 | if(DI!=NULL){ 120 | if(isa(DI)) 121 | { 122 | DeclRefExpr *DRE = dyn_cast(DI); 123 | //llvm::errs() << "if statment variable " << DRE->getNameInfo().getName().getAsString() <<"\n"; 124 | if(!DRE->getType()->isArrayType()) 125 | { 126 | add_always(DRE->getNameInfo().getName().getAsString()); 127 | } 128 | } 129 | checkif(DI); 130 | } 131 | } 132 | } 133 | 134 | //#### if variable not present in the list of parameters of the always @ add it to always_params array 135 | void add_always(std::string strin) 136 | { 137 | bool found = false; 138 | for (int i=0;igetParents(*D); 176 | if ( parents.empty() ) { 177 | llvm::errs() << "Can not find parent\n"; 178 | return false; 179 | } 180 | //llvm::errs() << "find parent size=" << parents.size() << "\n"; 181 | const Stmt *ST = parents[0].get(); 182 | if(ST!=NULL) 183 | { 184 | if (isa(ST)) 185 | { 186 | //llvm::errs() << "declaration in for loop " << "\n"; 187 | check = true; 188 | } 189 | else 190 | { 191 | check = inalways(ST); 192 | } 193 | } 194 | return check; 195 | } 196 | 197 | //#### Override Binary Operator expressions 198 | bool VisitBinaryOperator(BinaryOperator *E) 199 | { 200 | /*const auto& parents = astContext->getParents(*E); 201 | const Stmt *ST = parents[0].get(); 202 | if(!inalways(ST) && !isa(ST)) 203 | { 204 | if( E->getOpcode() == BO_Assign ) 205 | { 206 | SourceLocation loc = E->getLocStart(); 207 | TheRewriter.InsertText(loc, "assign ", true, true); 208 | } 209 | }*/ 210 | std::string varname; 211 | char rep[256]; 212 | if (DeclRefExpr *DRE = dyn_cast(E->getLHS())) 213 | { 214 | if (VarDecl *VD = dyn_cast(DRE->getDecl())) 215 | { 216 | varname = VD->getQualifiedNameAsString(); 217 | } 218 | } 219 | 220 | 221 | if( E->getOpcode() == BO_MulAssign ) 222 | { 223 | sprintf(rep,"= %s *",varname.c_str()); 224 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 225 | } 226 | else if( E->getOpcode() == BO_DivAssign ) 227 | { 228 | sprintf(rep,"= %s /",varname.c_str()); 229 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 230 | } 231 | else if( E->getOpcode() == BO_RemAssign ) 232 | { 233 | sprintf(rep,"= %s %%",varname.c_str()); 234 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 235 | } 236 | else if( E->getOpcode() == BO_AddAssign ) 237 | { 238 | sprintf(rep,"= %s +",varname.c_str()); 239 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 240 | } 241 | else if( E->getOpcode() == BO_SubAssign ) 242 | { 243 | sprintf(rep,"= %s -",varname.c_str()); 244 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 245 | } 246 | else if( E->getOpcode() == BO_AndAssign ) 247 | { 248 | sprintf(rep,"= %s &",varname.c_str()); 249 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 250 | } 251 | else if( E->getOpcode() == BO_XorAssign ) 252 | { 253 | sprintf(rep,"= %s ^",varname.c_str()); 254 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 255 | } 256 | else if( E->getOpcode() == BO_OrAssign ) 257 | { 258 | sprintf(rep,"= %s |",varname.c_str()); 259 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(),rep); 260 | } 261 | 262 | 263 | 264 | 265 | return true; 266 | } 267 | 268 | //#### Override Binary Operator expressions 269 | bool VisitUnaryOperator(UnaryOperator *E) 270 | { 271 | std::string varname; 272 | char rep[256]; 273 | if (DeclRefExpr *DRE = dyn_cast(E->getSubExpr())) 274 | { 275 | if (VarDecl *VD = dyn_cast(DRE->getDecl())) 276 | { 277 | varname = VD->getQualifiedNameAsString(); 278 | } 279 | } 280 | 281 | 282 | if( E->getOpcode() == UO_PostInc ) 283 | { 284 | sprintf(rep,"= %s + 1",varname.c_str()); 285 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr(UO_PostInc).size(),rep); 286 | } 287 | else if( E->getOpcode() == UO_PostDec ) 288 | { 289 | sprintf(rep,"= %s - 1",varname.c_str()); 290 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr(UO_PostDec).size(),rep); 291 | } 292 | else if( E->getOpcode() == UO_PreInc ) 293 | { 294 | sprintf(rep,"= %s + 1",varname.c_str()); 295 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr(UO_PreInc).size(),rep); 296 | } 297 | else if( E->getOpcode() == UO_PreDec ) 298 | { 299 | sprintf(rep,"= %s - 1",varname.c_str()); 300 | TheRewriter.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr(UO_PreDec).size(),rep); 301 | } 302 | 303 | 304 | 305 | return true; 306 | } 307 | 308 | 309 | 310 | //#### Override variable declaration to insert verilog syntax 311 | bool VisitVarDecl(VarDecl *V) 312 | { 313 | //clang::Rewriter::RewriteOptions opts = clang::Rewriter::RewriteOptions(); 314 | //opts.RemoveLineIfEmpty =1; 315 | 316 | SourceLocation end = V->getLocEnd(); 317 | int offset = Lexer::MeasureTokenLength(end, TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()); 318 | SourceLocation semicol = end.getLocWithOffset(offset); 319 | SourceLocation start = V->getLocStart(); 320 | 321 | if(!isa(V)) 322 | { 323 | 324 | 325 | const auto& parents = astContext->getParents(*V); 326 | const Stmt *ST = parents[0].get(); 327 | //const DeclStmt *DS = cast(ST); 328 | if (checkfor(ST)) 329 | { 330 | QualType qin = V->getType(); 331 | SourceLocation paramloc = V->getLocStart(); 332 | TheRewriter.RemoveText(paramloc,qin.getAsString().size()); 333 | } 334 | else 335 | { 336 | char rep[256]; 337 | QualType vtype = V->getType(); 338 | 339 | if (vtype->isArrayType()) 340 | { 341 | ConstantArrayType const *ArrayTy = dyn_cast(V->getType().getTypePtr()); 342 | if (ArrayTy->getElementType()->isBooleanType()) 343 | { 344 | if(V->getStorageClass() == SC_Register) 345 | { 346 | sprintf(rep,"reg %s [%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1); 347 | } 348 | else 349 | { 350 | sprintf(rep,"wire %s [%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1); 351 | } 352 | SourceRange stmtrange = SourceRange(start,end); 353 | TheRewriter.RemoveText(semicol,1); 354 | TheRewriter.RemoveText(stmtrange); 355 | 356 | SourceLocation temp = moving_start; 357 | TheRewriter.InsertTextBefore(temp, rep); 358 | } 359 | else 360 | if (ArrayTy->getElementType()->isIntegerType()) 361 | { 362 | if(V->getStorageClass() == SC_Register) 363 | { 364 | sprintf(rep,"reg [4:0] %s [%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1); 365 | } 366 | else 367 | { 368 | sprintf(rep,"wire [4:0] %s [%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1); 369 | } 370 | SourceRange stmtrange = SourceRange(start,end); 371 | TheRewriter.RemoveText(semicol,1); 372 | TheRewriter.RemoveText(stmtrange); 373 | 374 | SourceLocation temp = moving_start; 375 | TheRewriter.InsertTextBefore(temp, rep); 376 | } 377 | else 378 | if (ArrayTy->getElementType()->isArrayType()) 379 | { 380 | ConstantArrayType const *Array2Ty = dyn_cast(ArrayTy->getElementType().getTypePtr()); 381 | if (Array2Ty->getElementType()->isBooleanType()) 382 | { 383 | if(V->getStorageClass() == SC_Register) 384 | { 385 | sprintf(rep,"reg %s [%ld:0][%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1,Array2Ty->getSize().getSExtValue()-1); 386 | } 387 | else 388 | { 389 | sprintf(rep,"wire %s [%ld:0][%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1,Array2Ty->getSize().getSExtValue()-1); 390 | } 391 | SourceRange stmtrange = SourceRange(start,end); 392 | TheRewriter.RemoveText(semicol,1); 393 | TheRewriter.RemoveText(stmtrange); 394 | 395 | SourceLocation temp = moving_start; 396 | TheRewriter.InsertTextBefore(temp, rep); 397 | } 398 | else 399 | if (Array2Ty->getElementType()->isIntegerType()) 400 | { 401 | if(V->getStorageClass() == SC_Register) 402 | { 403 | sprintf(rep,"reg [4:0] %s [%ld:0][%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1,Array2Ty->getSize().getSExtValue()-1); 404 | } 405 | else 406 | { 407 | sprintf(rep,"wire [4:0] %s [%ld:0][%ld:0];\n",V->getDeclName().getAsString().data(),ArrayTy->getSize().getSExtValue()-1,Array2Ty->getSize().getSExtValue()-1); 408 | } 409 | SourceRange stmtrange = SourceRange(start,end); 410 | TheRewriter.RemoveText(semicol,1); 411 | TheRewriter.RemoveText(stmtrange); 412 | 413 | SourceLocation temp = moving_start; 414 | TheRewriter.InsertTextBefore(temp, rep); 415 | } 416 | } 417 | else 418 | llvm::errs() << "error in array type \n"; 419 | 420 | 421 | } 422 | else 423 | { 424 | if (vtype->isBooleanType()) 425 | { 426 | if(V->getStorageClass() == SC_Register) 427 | { 428 | sprintf(rep,"reg %s;\n",V->getDeclName().getAsString().data()); 429 | } 430 | else 431 | { 432 | sprintf(rep,"wire %s;\n",V->getDeclName().getAsString().data()); 433 | } 434 | SourceRange stmtrange = SourceRange(start,end); 435 | TheRewriter.RemoveText(semicol,1); 436 | TheRewriter.RemoveText(stmtrange); 437 | 438 | SourceLocation temp = moving_start; 439 | TheRewriter.InsertTextBefore(temp, rep); 440 | } 441 | else 442 | if (vtype->isIntegerType()) 443 | {//std::string name = V->getDeclName().getAsString().data(); 444 | if(V->getStorageClass() == SC_Register) 445 | { 446 | sprintf(rep,"reg [4:0] %s;\n",V->getDeclName().getAsString().data()); 447 | } 448 | else 449 | { 450 | sprintf(rep,"wire [4:0] %s;\n",V->getDeclName().getAsString().data()); 451 | } 452 | SourceRange stmtrange = SourceRange(start,end); 453 | TheRewriter.RemoveText(semicol,1); 454 | TheRewriter.RemoveText(stmtrange); 455 | 456 | SourceLocation temp = moving_start; 457 | TheRewriter.InsertTextBefore(temp, rep); 458 | 459 | } 460 | else 461 | llvm::errs() << "error in input param \n"; 462 | 463 | } 464 | } 465 | } 466 | return true; 467 | } 468 | 469 | 470 | bool VisitStmt(Stmt *s) 471 | { 472 | if (isa(s)) 473 | { 474 | // Cast s to IfStmt to access the then and else clauses 475 | IfStmt *If = cast(s); 476 | //checkif(s); 477 | //TheRewriter.InsertText(s->getLocStart(),get_always(),true,true); 478 | //int offset = Lexer::MeasureTokenLength(s->getLocEnd(), TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()); 479 | //TheRewriter.InsertText(s->getLocEnd().getLocWithOffset(offset),"\nend",true,true); 480 | 481 | Stmt *TH = If->getThen(); 482 | 483 | // Add braces if needed to then clause 484 | InstrumentStmt(TH); 485 | 486 | Stmt *EL = If->getElse(); 487 | if (EL) 488 | { 489 | // Add braces if needed to else clause 490 | InstrumentStmt(EL); 491 | } 492 | } 493 | else 494 | if (isa(s)) 495 | { 496 | WhileStmt *While = cast(s); 497 | Stmt *BODY = While->getBody(); 498 | InstrumentStmt(BODY); 499 | } 500 | else 501 | if (isa(s)) 502 | { 503 | ForStmt *For = cast(s); 504 | Stmt *BODY = For->getBody(); 505 | InstrumentFor(BODY,For); 506 | } 507 | else 508 | if (isa(s)) 509 | { 510 | TheRewriter.ReplaceText(s->getLocStart(), 6,"result = "); 511 | //TheRewriter.ReplaceText(s->getLocStart(), 6,"result = "); 512 | } 513 | 514 | return true; 515 | } 516 | 517 | bool VisitFunctionDecl(FunctionDecl *f) 518 | { 519 | 520 | if (f->hasBody()) 521 | { 522 | 523 | SourceRange sr = f->getSourceRange(); 524 | Stmt *s = f->getBody(); 525 | 526 | QualType q = f->getReturnType(); 527 | const Type *typ = q.getTypePtr(); 528 | char fd[256]; 529 | 530 | std::string args_in; 531 | char param_in[10][256]; 532 | //write input ports definitoins 533 | for(int i=0;i<(int)f->getNumParams();i++) 534 | { 535 | args_in = f->parameters()[i]->getQualifiedNameAsString(); 536 | //llvm::errs() << "params(" << i << ") is " << args[i] << "\n"; 537 | QualType qin = f->parameters()[i]->getType(); 538 | 539 | 540 | //const Type *typin = qin.getTypePtr(); 541 | if (qin->isBooleanType()) 542 | { 543 | sprintf(param_in[i],"\n input %s",args_in.data()); 544 | SourceLocation paramloc = f->parameters()[i]->getLocStart(); 545 | TheRewriter.RemoveText(paramloc,qin.getAsString().size()-1); 546 | TheRewriter.ReplaceText(paramloc, f->parameters()[i]->getQualifiedNameAsString().size()+1, param_in[i]); 547 | } 548 | else 549 | if (qin->isIntegerType()) 550 | { 551 | sprintf(param_in[i],"\n input [4:0] %s",args_in.data()); 552 | SourceLocation paramloc = f->parameters()[i]->getLocStart(); 553 | TheRewriter.RemoveText(paramloc,qin.getAsString().size()); 554 | TheRewriter.ReplaceText(paramloc, f->parameters()[i]->getQualifiedNameAsString().size()+1, param_in[i]); 555 | } 556 | else 557 | llvm::errs() << "error in input param--not supported yet \n"; 558 | 559 | 560 | } 561 | SourceLocation param_out_loc = f->parameters()[f->getNumParams()-1]->getLocEnd().getLocWithOffset(f->parameters()[f->getNumParams()-1]->getQualifiedNameAsString().size()); 562 | 563 | 564 | if (typ->isBooleanType()) 565 | sprintf(fd, ",\n output result "); 566 | else 567 | if (typ->isIntegerType()) 568 | sprintf(fd, ",\n output [4:0] result "); 569 | else 570 | sprintf(fd, "\n error in output param \n"); 571 | SourceLocation ENDf = s->getLocStart(); 572 | int offsett = Lexer::MeasureTokenLength(ENDf,TheRewriter.getSourceMgr(),TheRewriter.getLangOpts()) + 1; 573 | TheRewriter.ReplaceText(ENDf,offsett,";\n"); 574 | moving_start = s->getLocStart().getLocWithOffset(offsett); 575 | SourceLocation temp = moving_start; 576 | TheRewriter.InsertText(temp,"always@*\nbegin\n"); 577 | 578 | //write output port definition 579 | TheRewriter.InsertText(param_out_loc, fd, true, true); 580 | //TheRewriter.InsertText(ENDf, fd, true, true); 581 | 582 | // Get name of function 583 | DeclarationNameInfo dni = f->getNameInfo(); 584 | DeclarationName dn = dni.getName(); 585 | std::string fname = dn.getAsString(); 586 | 587 | // Point to start of function declaration 588 | SourceLocation ST = sr.getBegin(); 589 | 590 | // Add comment 591 | char fc[256]; 592 | sprintf(fc, "// Begin conversion of '%s' to Verilog \n", fname.data()); 593 | TheRewriter.InsertText(ST, fc, true, true); 594 | TheRewriter.ReplaceText(ST, q.getAsString().size(),""); 595 | TheRewriter.ReplaceText(f->getNameInfo().getLocStart(), fname.size(), "module "+fname); 596 | 597 | if (f->isMain()) 598 | llvm::errs() << "Found main()\n"; 599 | 600 | SourceLocation END1 = s->getLocEnd(); 601 | //int offsett1 = Lexer::MeasureTokenLength(END1,TheRewriter.getSourceMgr(),TheRewriter.getLangOpts()) + 1; 602 | TheRewriter.ReplaceText(END1,offsett,"end\nendmodule\n"); 603 | 604 | SourceLocation END = s->getLocEnd().getLocWithOffset(1); 605 | sprintf(fc, "\n// End of '%s'\n", fname.data()); 606 | TheRewriter.InsertText(END, fc, true, true); 607 | } 608 | 609 | return true; 610 | } 611 | 612 | private: 613 | Rewriter &TheRewriter; 614 | ASTContext *astContext; 615 | std::string always_params[20]; 616 | int counter = 0; 617 | SourceLocation moving_start; 618 | }; 619 | 620 | 621 | class MyASTConsumer : public ASTConsumer { 622 | public: 623 | MyASTConsumer(Rewriter &R, CompilerInstance *CI) : Visitor(R,CI) {} 624 | 625 | virtual bool HandleTopLevelDecl(DeclGroupRef DR) { 626 | for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) 627 | Visitor.TraverseDecl(*b); 628 | return true; 629 | } 630 | 631 | private: 632 | MyASTVisitor Visitor; 633 | }; 634 | 635 | int main(int argc, char *argv[]) { 636 | if (argc != 2) { 637 | llvm::errs() << "Usage: rewritersample \n"; 638 | return 1; 639 | } 640 | 641 | 642 | CompilerInstance TheCompInst; 643 | TheCompInst.createDiagnostics(); 644 | 645 | LangOptions &lo = TheCompInst.getLangOpts(); 646 | lo.GNUMode = 1; 647 | lo.CXXExceptions = 1; 648 | lo.RTTI = 1; 649 | lo.Bool = 1; 650 | lo.CPlusPlus = 1; 651 | 652 | 653 | auto TO = std::make_shared(); 654 | TO->Triple = llvm::sys::getDefaultTargetTriple(); 655 | TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO); 656 | TheCompInst.setTarget(TI); 657 | 658 | TheCompInst.createFileManager(); 659 | FileManager &FileMgr = TheCompInst.getFileManager(); 660 | TheCompInst.createSourceManager(FileMgr); 661 | SourceManager &SourceMgr = TheCompInst.getSourceManager(); 662 | TheCompInst.createPreprocessor(TU_Module); 663 | TheCompInst.createASTContext(); 664 | 665 | Rewriter TheRewriter; 666 | TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts()); 667 | 668 | const FileEntry *FileIn = FileMgr.getFile(argv[1]); 669 | SourceMgr.setMainFileID(SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User)); 670 | TheCompInst.getDiagnosticClient().BeginSourceFile(TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor()); 671 | 672 | 673 | 674 | MyASTConsumer TheConsumer(TheRewriter, &TheCompInst); 675 | 676 | ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext()); 677 | 678 | const RewriteBuffer *RewriteBuf = TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID()); 679 | //llvm::outs() << std::string(RewriteBuf->begin(), RewriteBuf->end()); 680 | 681 | std::string fileName(argv[1]); 682 | std::string outName (fileName); 683 | size_t ext = outName.rfind("."); 684 | if (ext == std::string::npos) 685 | ext = outName.length(); 686 | outName = outName.substr(0,ext); 687 | outName.insert(ext, ".v"); 688 | llvm::errs() << "Output to: " << outName << "\n"; 689 | std::error_code OutErrorInfo; 690 | llvm::raw_fd_ostream outFile(llvm::StringRef(outName), OutErrorInfo, llvm::sys::fs::F_None); 691 | outFile << "/* DWave-c2v: source to source translation of C-code to verilog-code compliant with edif2qmasm using clang tools */\n\n"; 692 | outFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 693 | outFile.close(); 694 | return 0; 695 | } 696 | --------------------------------------------------------------------------------