|
12 | 12 | #include <libasr/pass/intrinsic_array_function_registry.h>
|
13 | 13 | #include <lc/clang_ast_to_asr.h>
|
14 | 14 |
|
| 15 | +#include <set> |
| 16 | + |
15 | 17 | namespace LCompilers {
|
16 | 18 |
|
17 | 19 | enum SpecialFunc {
|
@@ -176,6 +178,7 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
|
176 | 178 | std::map<SymbolTable*, std::vector<ASR::symbol_t*>> scope2enums;
|
177 | 179 | clang::ForStmt* for_loop;
|
178 | 180 | bool inside_loop;
|
| 181 | + std::set<ASR::symbol_t*> read_only_symbols; |
179 | 182 |
|
180 | 183 | explicit ClangASTtoASRVisitor(clang::ASTContext *Context_,
|
181 | 184 | Allocator& al_, ASR::asr_t*& tu_):
|
@@ -1585,6 +1588,8 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
|
1585 | 1588 | ASR::cast_kindType::ListToArray) {
|
1586 | 1589 | throw std::runtime_error("First argument of Kokkos::mdspan "
|
1587 | 1590 | "constructor should be a call to std::vector::data() function.");
|
| 1591 | + } else { |
| 1592 | + mark_as_read_only(list_to_array); |
1588 | 1593 | }
|
1589 | 1594 | if( ASRUtils::extract_n_dims_from_ttype(constructor_type) != x->getNumArgs() - 1 ) {
|
1590 | 1595 | throw std::runtime_error("Shape provided in the constructor "
|
@@ -2139,13 +2144,123 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
|
2139 | 2144 | }
|
2140 | 2145 | }
|
2141 | 2146 |
|
| 2147 | + void mark_as_read_only(ASR::symbol_t* symbol) { |
| 2148 | + read_only_symbols.insert(ASRUtils::symbol_get_past_external(symbol)); |
| 2149 | + } |
| 2150 | + |
| 2151 | + void mark_as_read_only(ASR::expr_t* list_to_array, bool root=true) { |
| 2152 | + ASR::expr_t* expr = list_to_array; |
| 2153 | + if( root ) { |
| 2154 | + if( !ASR::is_a<ASR::Cast_t>(*list_to_array) ) { |
| 2155 | + return ; |
| 2156 | + } |
| 2157 | + ASR::Cast_t* cast_t = ASR::down_cast<ASR::Cast_t>(list_to_array); |
| 2158 | + if( cast_t->m_kind != ASR::cast_kindType::ListToArray ) { |
| 2159 | + return ; |
| 2160 | + } |
| 2161 | + |
| 2162 | + expr = cast_t->m_arg; |
| 2163 | + } |
| 2164 | + |
| 2165 | + switch( expr->type ) { |
| 2166 | + case ASR::exprType::Var: { |
| 2167 | + ASR::Var_t* var_t = ASR::down_cast<ASR::Var_t>(expr); |
| 2168 | + return mark_as_read_only(var_t->m_v); |
| 2169 | + } |
| 2170 | + case ASR::exprType::ListItem: { |
| 2171 | + ASR::ListItem_t* list_item_t = ASR::down_cast<ASR::ListItem_t>(expr); |
| 2172 | + return mark_as_read_only(list_item_t->m_a, false); |
| 2173 | + } |
| 2174 | + case ASR::exprType::ListSection: { |
| 2175 | + ASR::ListSection_t* list_section_t = ASR::down_cast<ASR::ListSection_t>(expr); |
| 2176 | + return mark_as_read_only(list_section_t->m_a, false); |
| 2177 | + } |
| 2178 | + case ASR::exprType::StructInstanceMember: { |
| 2179 | + ASR::StructInstanceMember_t* struct_instance_member_t = ASR::down_cast<ASR::StructInstanceMember_t>(expr); |
| 2180 | + return mark_as_read_only(struct_instance_member_t->m_m); |
| 2181 | + } |
| 2182 | + case ASR::exprType::StructStaticMember: { |
| 2183 | + ASR::StructStaticMember_t* struct_static_member_t = ASR::down_cast<ASR::StructStaticMember_t>(expr); |
| 2184 | + return mark_as_read_only(struct_static_member_t->m_m); |
| 2185 | + } |
| 2186 | + case ASR::exprType::EnumStaticMember: { |
| 2187 | + ASR::EnumStaticMember_t* enum_static_member_t = ASR::down_cast<ASR::EnumStaticMember_t>(expr); |
| 2188 | + return mark_as_read_only(enum_static_member_t->m_m); |
| 2189 | + } |
| 2190 | + case ASR::exprType::UnionInstanceMember: { |
| 2191 | + ASR::UnionInstanceMember_t* union_instance_member_t = ASR::down_cast<ASR::UnionInstanceMember_t>(expr); |
| 2192 | + return mark_as_read_only(union_instance_member_t->m_m); |
| 2193 | + } |
| 2194 | + default: { |
| 2195 | + throw std::runtime_error("ASRUtils::exprType::" + std::to_string(expr->type) + |
| 2196 | + " is not handled yet in is_read_only method."); |
| 2197 | + } |
| 2198 | + } |
| 2199 | + } |
| 2200 | + |
| 2201 | + bool is_read_only(ASR::symbol_t* symbol, std::string& symbol_name) { |
| 2202 | + if( read_only_symbols.find(ASRUtils::symbol_get_past_external(symbol)) != |
| 2203 | + read_only_symbols.end() ) { |
| 2204 | + symbol_name = ASRUtils::symbol_name(ASRUtils::symbol_get_past_external(symbol)); |
| 2205 | + return true; |
| 2206 | + } |
| 2207 | + return false; |
| 2208 | + } |
| 2209 | + |
| 2210 | + bool is_read_only(ASR::expr_t* expr, std::string& symbol_name) { |
| 2211 | + switch( expr->type ) { |
| 2212 | + case ASR::exprType::Var: { |
| 2213 | + ASR::Var_t* var_t = ASR::down_cast<ASR::Var_t>(expr); |
| 2214 | + return is_read_only(var_t->m_v, symbol_name); |
| 2215 | + } |
| 2216 | + case ASR::exprType::ListItem: { |
| 2217 | + ASR::ListItem_t* list_item_t = ASR::down_cast<ASR::ListItem_t>(expr); |
| 2218 | + return is_read_only(list_item_t->m_a, symbol_name); |
| 2219 | + } |
| 2220 | + case ASR::exprType::ArrayItem: { |
| 2221 | + ASR::ArrayItem_t* array_item_t = ASR::down_cast<ASR::ArrayItem_t>(expr); |
| 2222 | + return is_read_only(array_item_t->m_v, symbol_name); |
| 2223 | + } |
| 2224 | + case ASR::exprType::ListSection: { |
| 2225 | + ASR::ListSection_t* list_section_t = ASR::down_cast<ASR::ListSection_t>(expr); |
| 2226 | + return is_read_only(list_section_t->m_a, symbol_name); |
| 2227 | + } |
| 2228 | + case ASR::exprType::StructInstanceMember: { |
| 2229 | + ASR::StructInstanceMember_t* struct_instance_member_t = ASR::down_cast<ASR::StructInstanceMember_t>(expr); |
| 2230 | + return is_read_only(struct_instance_member_t->m_m, symbol_name); |
| 2231 | + } |
| 2232 | + case ASR::exprType::StructStaticMember: { |
| 2233 | + ASR::StructStaticMember_t* struct_static_member_t = ASR::down_cast<ASR::StructStaticMember_t>(expr); |
| 2234 | + return is_read_only(struct_static_member_t->m_m, symbol_name); |
| 2235 | + } |
| 2236 | + case ASR::exprType::EnumStaticMember: { |
| 2237 | + ASR::EnumStaticMember_t* enum_static_member_t = ASR::down_cast<ASR::EnumStaticMember_t>(expr); |
| 2238 | + return is_read_only(enum_static_member_t->m_m, symbol_name); |
| 2239 | + } |
| 2240 | + case ASR::exprType::UnionInstanceMember: { |
| 2241 | + ASR::UnionInstanceMember_t* union_instance_member_t = ASR::down_cast<ASR::UnionInstanceMember_t>(expr); |
| 2242 | + return is_read_only(union_instance_member_t->m_m, symbol_name); |
| 2243 | + } |
| 2244 | + default: { |
| 2245 | + throw std::runtime_error("ASRUtils::exprType::" + std::to_string(expr->type) + |
| 2246 | + " is not handled yet in is_read_only method."); |
| 2247 | + } |
| 2248 | + } |
| 2249 | + return false; |
| 2250 | + } |
| 2251 | + |
2142 | 2252 | bool TraverseBinaryOperator(clang::BinaryOperator *x) {
|
2143 | 2253 | clang::BinaryOperatorKind op = x->getOpcode();
|
2144 | 2254 | TraverseStmt(x->getLHS());
|
2145 | 2255 | ASR::expr_t* x_lhs = ASRUtils::EXPR(tmp.get());
|
2146 | 2256 | TraverseStmt(x->getRHS());
|
2147 | 2257 | ASR::expr_t* x_rhs = ASRUtils::EXPR(tmp.get());
|
2148 | 2258 | if( op == clang::BO_Assign ) {
|
| 2259 | + std::string symbol_name = ""; |
| 2260 | + if( is_read_only(x_lhs, symbol_name) ) { |
| 2261 | + std::cerr << symbol_name + " is marked as read only." << std::endl; |
| 2262 | + exit(EXIT_FAILURE); |
| 2263 | + } |
2149 | 2264 | cast_helper(x_lhs, x_rhs, true);
|
2150 | 2265 | ASRUtils::make_ArrayBroadcast_t_util(al, Lloc(x), x_lhs, x_rhs);
|
2151 | 2266 | tmp = ASR::make_Assignment_t(al, Lloc(x), x_lhs, x_rhs, nullptr);
|
|
0 commit comments