//! Takes an AST node subclass and returns an appropriate DataTarget object that contains //! the same information. Supported AST node types are: //! - SymbolASTNode //! - NaturalLocationASTNode //! - AddressRangeASTNode //! //! \exception elftosb::semantic_error Thrown if a semantic problem is found with //! the target node. DataTarget * ConversionController::createTargetFromNode(ASTNode * targetNode) { assert(targetNode); DataTarget * target = NULL; SymbolASTNode * symbolNode; NaturalLocationASTNode * naturalNode; AddressRangeASTNode * addressNode; if (symbolNode = dynamic_cast<SymbolASTNode*>(targetNode)) { SourceFile * sourceFile = getSourceFromName(symbolNode->getSource(), symbolNode->getFirstLine()); std::string * symbolName = symbolNode->getSymbolName(); // symbol name is optional if (symbolName) { if (!sourceFile->supportsNamedSymbols()) { throw std::runtime_error(format_string("line %d: source does not support symbols", symbolNode->getFirstLine())); } target = sourceFile->createDataTargetForSymbol(*symbolName); if (!target) { throw std::runtime_error(format_string("line %d: source does not have a symbol with that name", symbolNode->getFirstLine())); } } else { // no symbol name was specified so use entry point target = sourceFile->createDataTargetForEntryPoint(); if (!target) { throw std::runtime_error(format_string("line %d: source does not have an entry point", symbolNode->getFirstLine())); } } } else if (naturalNode = dynamic_cast<NaturalLocationASTNode*>(targetNode)) { // the target is the source's natural location target = new NaturalDataTarget(); } else if (addressNode = dynamic_cast<AddressRangeASTNode*>(targetNode)) { // evaluate begin address ExprASTNode * beginExpr = dynamic_cast<ExprASTNode*>(addressNode->getBegin()); if (!beginExpr) { throw semantic_error("address range must always have a beginning expression"); } IntConstExprASTNode * beginIntExpr = dynamic_cast<IntConstExprASTNode*>(beginExpr->reduce(m_context)); if (!beginIntExpr) { throw semantic_error("address range begin did not evaluate to an integer"); } uint32_t beginAddress = static_cast<uint32_t>(beginIntExpr->getValue()); // evaluate end address ExprASTNode * endExpr = dynamic_cast<ExprASTNode*>(addressNode->getEnd()); uint32_t endAddress = 0; bool hasEndAddress = false; if (endExpr) { IntConstExprASTNode * endIntExpr = dynamic_cast<IntConstExprASTNode*>(endExpr->reduce(m_context)); if (!endIntExpr) { throw semantic_error("address range end did not evaluate to an integer"); } endAddress = static_cast<uint32_t>(endIntExpr->getValue()); hasEndAddress = true; } // create target if (hasEndAddress) { target = new ConstantDataTarget(beginAddress, endAddress); } else { target = new ConstantDataTarget(beginAddress); } } else { throw semantic_error("unexpected load target node type"); } return target; }