MCPcopy Create free account
hub / github.com/MikePopoloski/slang / getDim

Method getDim

source/ast/builtins/QueryFuncs.cpp:250–321  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

248 };
249
250 DimResult getDim(EvalContext& context, const Args& args) const {
251 if (!noHierarchical(context, *args[0]))
252 return {};
253
254 // If an index expression is provided, evaluate it. Otherwise default to 1.
255 ConstantValue iv;
256 int32_t index = 1;
257 if (args.size() > 1) {
258 iv = args[1]->eval(context);
259 if (!iv)
260 return {};
261
262 std::optional<int32_t> oi = iv.integer().as<int32_t>();
263 if (!oi || *oi <= 0)
264 return DimResult::OutOfRange();
265
266 index = *oi;
267 }
268
269 // Unwrap each dimension until we reach the right index.
270 const Type* type = args[0]->type;
271 for (int32_t i = 0; i < index - 1; i++) {
272 // If this is not an array, we have nothing to index into
273 // and the index we were provided is invalid.
274 if (!type->isArray())
275 return DimResult::OutOfRange();
276
277 type = type->getArrayElementType();
278 }
279
280 // We're pointing at the right dimension, so figure out its range.
281 // If fixed size, just return that range.
282 if (type->hasFixedRange() && !type->isScalar())
283 return type->getFixedRange();
284
285 // Otherwise, this had better be a dynamic array or string.
286 if (!type->isString() && !type->isUnpackedArray())
287 return DimResult::OutOfRange();
288
289 // This is a dynamically sized thing, so we need to evaluate the expression
290 // in order to know its current size. We can only do that if the index is 1
291 // because otherwise we won't know which subelement this refers to.
292 if (index != 1) {
293 context.addDiag(diag::DynamicDimensionIndex, args[0]->sourceRange)
294 << iv << args[1]->sourceRange;
295 return {};
296 }
297
298 // This only works on associative arrays if they have an integral index type.
299 const Type* indexType = nullptr;
300 if (type->isAssociativeArray()) {
301 indexType = type->getAssociativeIndexType();
302 if (!indexType || !indexType->isIntegral()) {
303 context.addDiag(diag::QueryOnAssociativeWildcard, args[0]->sourceRange) << name;
304 return {};
305 }
306 }
307

Callers

nothing calls this directly

Calls 11

DimResultClass · 0.85
isArrayMethod · 0.80
getArrayElementTypeMethod · 0.80
hasFixedRangeMethod · 0.80
getFixedRangeMethod · 0.80
isUnpackedArrayMethod · 0.80
isIntegralMethod · 0.80
strMethod · 0.80
sizeMethod · 0.45
evalMethod · 0.45

Tested by

no test coverage detected