| 3616 | } |
| 3617 | |
| 3618 | void CGenerator::scanStructForAnnotations(StructType *currentStructType, bool isFunction) |
| 3619 | { |
| 3620 | // go trough all structure members |
| 3621 | for (StructMember *structMember : currentStructType->getMembers()) |
| 3622 | { |
| 3623 | DataType *memberType = structMember->getDataType()->getTrueDataType(); |
| 3624 | /* Check non-encapsulated discriminated unions. */ |
| 3625 | // looking for references |
| 3626 | Annotation *lengthAnn = findAnnotation(structMember, LENGTH_ANNOTATION); |
| 3627 | Annotation *maxLengthAnn = findAnnotation(structMember, MAX_LENGTH_ANNOTATION); |
| 3628 | if (lengthAnn) |
| 3629 | { |
| 3630 | checkIfAnnValueIsIntNumberOrIntType(lengthAnn, currentStructType); |
| 3631 | |
| 3632 | if (lengthAnn->getValueObject()->getType() != kIntegerValue) |
| 3633 | { |
| 3634 | StructMember *structMemberRef = NULL; |
| 3635 | |
| 3636 | // search in structure scope for member referenced with annotation |
| 3637 | Symbol *symbol = |
| 3638 | currentStructType->getScope().getSymbol(lengthAnn->getValueObject()->toString(), false); |
| 3639 | if (symbol) |
| 3640 | { |
| 3641 | structMemberRef = dynamic_cast<StructMember *>(symbol); |
| 3642 | assert(structMemberRef); |
| 3643 | } |
| 3644 | |
| 3645 | // Verify both the data and length members are the same direction. |
| 3646 | if (!isFunction && structMemberRef && structMember->getDirection() != structMemberRef->getDirection()) |
| 3647 | { |
| 3648 | throw semantic_error( |
| 3649 | format_string("orig line %d, ref line %d: The parameter named by a length annotation must be " |
| 3650 | "the same direction as the data parameter.", |
| 3651 | lengthAnn->getLocation().m_firstLine, structMember->getLocation().m_firstLine)); |
| 3652 | } |
| 3653 | // Verify using max_length annotation when referenced variable is out. |
| 3654 | else if (isFunction && structMemberRef && |
| 3655 | structMemberRef->getDirection() == param_direction_t::kOutDirection && |
| 3656 | !findAnnotation(structMember, MAX_LENGTH_ANNOTATION)) |
| 3657 | { |
| 3658 | throw semantic_error( |
| 3659 | format_string("orig line %d, ref line %d: The out parameter with set length annotation " |
| 3660 | "must have also set max_length annotation", |
| 3661 | lengthAnn->getLocation().m_firstLine, structMember->getLocation().m_firstLine)); |
| 3662 | } |
| 3663 | // Verify using max_length annotation when referenced variable is inout. |
| 3664 | else if (isFunction && structMemberRef && |
| 3665 | structMember->getDirection() == param_direction_t::kInoutDirection && |
| 3666 | structMemberRef->getDirection() == param_direction_t::kInoutDirection && |
| 3667 | !findAnnotation(structMember, MAX_LENGTH_ANNOTATION)) |
| 3668 | { |
| 3669 | throw semantic_error( |
| 3670 | format_string("orig line %d, ref line %d: The inout parameter named by a length annotation " |
| 3671 | "must have set max_length annotation", |
| 3672 | lengthAnn->getLocation().m_firstLine, structMember->getLocation().m_firstLine)); |
| 3673 | } |
| 3674 | } |
| 3675 |
nothing calls this directly
no test coverage detected