diff --git a/regression/verilog/preprocessor/file1.desc b/regression/verilog/preprocessor/file1.desc new file mode 100644 index 00000000..9087c3a4 --- /dev/null +++ b/regression/verilog/preprocessor/file1.desc @@ -0,0 +1,8 @@ +CORE +file1.v +--preprocess +^ "file1\.v", 4\);$ +^EXIT=0$ +^SIGNAL=0$ +-- +^PREPROCESSING FAILED$ diff --git a/regression/verilog/preprocessor/file1.v b/regression/verilog/preprocessor/file1.v new file mode 100644 index 00000000..df6def09 --- /dev/null +++ b/regression/verilog/preprocessor/file1.v @@ -0,0 +1,6 @@ +module main; + + initial $display("Internal error: null handle at %s, line %d.", + `__FILE__, `__LINE__); + +endmodule diff --git a/src/verilog/expr2verilog.cpp b/src/verilog/expr2verilog.cpp index dfa72fe2..4138f591 100644 --- a/src/verilog/expr2verilog.cpp +++ b/src/verilog/expr2verilog.cpp @@ -27,6 +27,59 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +std::string verilog_string_literal(const std::string &src) +{ + std::string dest; + + dest = '"'; + + for(auto &ch : src) + { + // Follows Table Table 5-1 in 1800-2017. + switch(ch) + { + case '\n': + dest += "\\n"; + break; + case '\t': + dest += "\\t"; + break; + case '\\': + dest += "\\\\"; + break; + case '"': + dest += "\\\""; + break; + case '\v': + dest += "\\v"; + break; + case '\f': + dest += "\\f"; + break; + case '\a': + dest += "\\a"; + break; + default: + if( + (unsigned(ch) >= ' ' && unsigned(ch) <= 126) || + (unsigned(ch) >= 128 && unsigned(ch) <= 254)) + { + dest += ch; + } + else + { + std::ostringstream oss; + oss << "\\x" << std::setw(2) << std::setfill('0') << std::hex << ch; + dest += oss.str(); + } + } + } + + dest += '"'; + + return dest; +} + /*******************************************************************\ Function: expr2verilogt::convert_if @@ -1214,51 +1267,7 @@ expr2verilogt::resultt expr2verilogt::convert_constant( } else if(type.id() == ID_string) { - dest = '"'; - - for(auto &ch : id2string(src.get_value())) - { - // Follows Table Table 5-1 in 1800-2017. - switch(ch) - { - case '\n': - dest += "\\n"; - break; - case '\t': - dest += "\\t"; - break; - case '\\': - dest += "\\\\"; - break; - case '"': - dest += "\\\""; - break; - case '\v': - dest += "\\v"; - break; - case '\f': - dest += "\\f"; - break; - case '\a': - dest += "\\a"; - break; - default: - if( - (unsigned(ch) >= ' ' && unsigned(ch) <= 126) || - (unsigned(ch) >= 128 && unsigned(ch) <= 254)) - { - dest += ch; - } - else - { - std::ostringstream oss; - oss << "\\x" << std::setw(2) << std::setfill('0') << std::hex << ch; - dest += oss.str(); - } - } - } - - dest += '"'; + dest = verilog_string_literal(id2string(src.get_value())); } else if(type.id() == ID_verilog_chandle || type.id() == ID_verilog_event) { diff --git a/src/verilog/expr2verilog.h b/src/verilog/expr2verilog.h index a0af8062..62c41d0f 100644 --- a/src/verilog/expr2verilog.h +++ b/src/verilog/expr2verilog.h @@ -10,3 +10,5 @@ Author: Daniel Kroening, kroening@kroening.com std::string expr2verilog(const exprt &, const namespacet &); std::string type2verilog(const typet &, const namespacet &); + +std::string verilog_string_literal(const std::string &); diff --git a/src/verilog/verilog_preprocessor.cpp b/src/verilog/verilog_preprocessor.cpp index 19700ce1..11d9558a 100644 --- a/src/verilog/verilog_preprocessor.cpp +++ b/src/verilog/verilog_preprocessor.cpp @@ -11,6 +11,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include "expr2verilog.h" #include "verilog_preprocessor_error.h" #include @@ -672,6 +673,18 @@ void verilog_preprocessort::directive() break; } } + else if(text == "__FILE__") + { + // 1800 2017 22.13 + // String literal + out << verilog_string_literal(context().filename_as_string()); + } + else if(text == "__LINE__") + { + // 1800 2017 22.13 + // decimal number + out << tokenizer().line_no(); + } else { // check defines