@Override public AddressValue addressValue(ExpressionNode lhs) throws SyntaxException { if (lhs instanceof IdentifierExpressionNode) { Entity entity = ((IdentifierExpressionNode) lhs).getIdentifier().getEntity(); EntityKind kind = entity.getEntityKind(); if (kind == EntityKind.VARIABLE) { return variableReference((Variable) entity); } else if (kind == EntityKind.FUNCTION) { return functionReference((Function) entity); } else { throw error("Operand of & not variable or function identifier", lhs); } } else if (lhs instanceof DotNode) { AddressValue structureOrUnionReference = addressValue(((DotNode) lhs).getStructure()); Field field = (Field) ((DotNode) lhs).getFieldName().getEntity(); return memberReference(structureOrUnionReference, field); } else if (lhs instanceof OperatorNode) { OperatorNode opNode = (OperatorNode) lhs; Operator operator = ((OperatorNode) lhs).getOperator(); if (operator == Operator.SUBSCRIPT) { AddressValue arrayReference = addressValue(opNode.getArgument(0)); Value index = evaluate(opNode.getArgument(1)); return arrayElementReference(arrayReference, index); } else if (operator == Operator.DEREFERENCE) { return (AddressValue) evaluate(opNode.getArgument(0)); } } throw error("Cannot take address of expression", lhs); }
/** * Evaluates a constant expression. * * <p>Should apply conversions to result. * * @param expr * @return * @throws SyntaxException * @throws UnsourcedException if expr is not a constant expression */ private Value evaluateHelper(ExpressionNode expr) throws SyntaxException, UnsourcedException { if (expr instanceof AlignOfNode) { return alignofValue(((AlignOfNode) expr).getArgument().getType()); } else if (expr instanceof ArrowNode) { ArrowNode arrowNode = (ArrowNode) expr; ExpressionNode structOrUnionPointer = arrowNode.getStructurePointer(); IdentifierNode fieldIdentifier = arrowNode.getFieldName(); Field field = (Field) fieldIdentifier.getEntity(); Value structOrUnionValue = evaluateDereference(structOrUnionPointer); return evaluateMemberAccess(structOrUnionValue, field); } else if (expr instanceof CastNode) { CastNode castNode = (CastNode) expr; return evaluateCast(castNode.getCastType().getType(), evaluate(castNode.getArgument())); } else if (expr instanceof CharacterConstantNode) { return ((CharacterConstantNode) expr).getConstantValue(); } else if (expr instanceof CompoundLiteralNode) { return evaluateCompoundLiteral((CompoundLiteralNode) expr); } else if (expr instanceof ConstantNode) { return ((ConstantNode) expr).getConstantValue(); } else if (expr instanceof DotNode) { DotNode dotNode = (DotNode) expr; ExpressionNode structOrUnion = dotNode.getStructure(); IdentifierNode fieldIdentifier = dotNode.getFieldName(); Field field = (Field) fieldIdentifier.getEntity(); Value structOrUnionValue = evaluate(structOrUnion); return evaluateMemberAccess(structOrUnionValue, field); } else if (expr instanceof OperatorNode) { OperatorNode opNode = (OperatorNode) expr; Operator operator = opNode.getOperator(); if (operator == Operator.ADDRESSOF) return addressValue(opNode.getArgument(0)); else { // evaluate arguments and call apply int numArgs = opNode.getNumberOfArguments(); Value[] argValues = new Value[numArgs]; Type type = expr.getInitialType(); for (int i = 0; i < numArgs; i++) { ExpressionNode arg = opNode.getArgument(i); Value argValue = evaluate(arg); argValues[i] = applyConversions(arg, argValue); } return apply(type, operator, argValues); } } else if (expr instanceof SizeofNode) { return sizeofValue((((SizeofNode) expr).getArgument()).getType()); } else if (expr instanceof StringLiteralNode) { return ((StringLiteralNode) expr).getConstantValue(); } else if (expr instanceof EnumerationConstantNode) { IdentifierNode identNode = ((EnumerationConstantNode) expr).getName(); Entity entity = identNode.getEntity(); if (entity.getEntityKind() == EntityKind.ENUMERATOR) { return ((Enumerator) entity).getValue(); } return null; } return null; }