Home | History | Annotate | Line # | Download | only in elftosb2
      1 /*
      2  * File:	ElftosbAST.cpp
      3  *
      4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
      5  * See included license file for license details.
      6  */
      7 
      8 #include "ElftosbAST.h"
      9 #include <stdexcept>
     10 #include <math.h>
     11 #include <assert.h>
     12 #include "ElftosbErrors.h"
     13 #include "format_string.h"
     14 
     15 using namespace elftosb;
     16 
     17 #pragma mark = ASTNode =
     18 
     19 void ASTNode::printTree(int indent) const
     20 {
     21 	printIndent(indent);
     22 	printf("%s\n", nodeName().c_str());
     23 }
     24 
     25 void ASTNode::printIndent(int indent) const
     26 {
     27 	int i;
     28 	for (i=0; i<indent; ++i)
     29 	{
     30 		printf("   ");
     31 	}
     32 }
     33 
     34 void ASTNode::setLocation(token_loc_t & first, token_loc_t & last)
     35 {
     36 	m_location.m_firstLine = first.m_firstLine;
     37 	m_location.m_lastLine = last.m_lastLine;
     38 }
     39 
     40 void ASTNode::setLocation(ASTNode * first, ASTNode * last)
     41 {
     42 	m_location.m_firstLine = first->getLocation().m_firstLine;
     43 	m_location.m_lastLine = last->getLocation().m_lastLine;
     44 }
     45 
     46 #pragma mark = ListASTNode =
     47 
     48 ListASTNode::ListASTNode(const ListASTNode & other)
     49 :	ASTNode(other), m_list()
     50 {
     51 	// deep copy each item of the original's list
     52 	const_iterator it = other.begin();
     53 	for (; it != other.end(); ++it)
     54 	{
     55 		m_list.push_back((*it)->clone());
     56 	}
     57 }
     58 
     59 //! Deletes child node in the list.
     60 //!
     61 ListASTNode::~ListASTNode()
     62 {
     63 	iterator it = begin();
     64 	for (; it != end(); it++)
     65 	{
     66 		delete *it;
     67 	}
     68 }
     69 
     70 //! If \a node is NULL then the list is left unmodified.
     71 //!
     72 //! The list node's location is automatically updated after the node is added by a call
     73 //! to updateLocation().
     74 void ListASTNode::appendNode(ASTNode * node)
     75 {
     76 	if (node)
     77 	{
     78 		m_list.push_back(node);
     79 		updateLocation();
     80 	}
     81 }
     82 
     83 void ListASTNode::printTree(int indent) const
     84 {
     85 	ASTNode::printTree(indent);
     86 
     87 	int n = 0;
     88 	const_iterator it = begin();
     89 	for (; it != end(); it++, n++)
     90 	{
     91 		printIndent(indent + 1);
     92 		printf("%d:\n", n);
     93 		(*it)->printTree(indent + 2);
     94 	}
     95 }
     96 
     97 void ListASTNode::updateLocation()
     98 {
     99 	token_loc_t current = { 0 };
    100 	const_iterator it = begin();
    101 	for (; it != end(); it++)
    102 	{
    103 		const ASTNode * node = *it;
    104 		const token_loc_t & loc = node->getLocation();
    105 
    106 		// handle first node
    107 		if (current.m_firstLine == 0)
    108 		{
    109 			current = loc;
    110 			continue;
    111 		}
    112 
    113 		if (loc.m_firstLine < current.m_firstLine)
    114 		{
    115 			current.m_firstLine = loc.m_firstLine;
    116 		}
    117 
    118 		if (loc.m_lastLine > current.m_lastLine)
    119 		{
    120 			current.m_lastLine = loc.m_lastLine;
    121 		}
    122 	}
    123 
    124 	setLocation(current);
    125 }
    126 
    127 #pragma mark = CommandFileASTNode =
    128 
    129 CommandFileASTNode::CommandFileASTNode()
    130 :	ASTNode(), m_options(), m_constants(), m_sources(), m_sections()
    131 {
    132 }
    133 
    134 CommandFileASTNode::CommandFileASTNode(const CommandFileASTNode & other)
    135 :	ASTNode(other), m_options(), m_constants(), m_sources(), m_sections()
    136 {
    137 	m_options = dynamic_cast<ListASTNode*>(other.m_options->clone());
    138 	m_constants = dynamic_cast<ListASTNode*>(other.m_constants->clone());
    139 	m_sources = dynamic_cast<ListASTNode*>(other.m_sources->clone());
    140 	m_sections = dynamic_cast<ListASTNode*>(other.m_sections->clone());
    141 }
    142 
    143 void CommandFileASTNode::printTree(int indent) const
    144 {
    145 	ASTNode::printTree(indent);
    146 
    147 	printIndent(indent + 1);
    148 	printf("options:\n");
    149 	if (m_options) m_options->printTree(indent + 2);
    150 
    151 	printIndent(indent + 1);
    152 	printf("constants:\n");
    153 	if (m_constants) m_constants->printTree(indent + 2);
    154 
    155 	printIndent(indent + 1);
    156 	printf("sources:\n");
    157 	if (m_sources) m_sources->printTree(indent + 2);
    158 
    159 	printIndent(indent + 1);
    160 	printf("sections:\n");
    161 	if (m_sections) m_sections->printTree(indent + 2);
    162 }
    163 
    164 #pragma mark = ExprASTNode =
    165 
    166 int_size_t ExprASTNode::resultIntSize(int_size_t a, int_size_t b)
    167 {
    168 	int_size_t result;
    169 	switch (a)
    170 	{
    171 		case kWordSize:
    172 			result = kWordSize;
    173 			break;
    174 		case kHalfWordSize:
    175 			if (b == kWordSize)
    176 			{
    177 				result = kWordSize;
    178 			}
    179 			else
    180 			{
    181 				result = kHalfWordSize;
    182 			}
    183 			break;
    184 		case kByteSize:
    185 			if (b == kWordSize)
    186 			{
    187 				result = kWordSize;
    188 			}
    189 			else if (b == kHalfWordSize)
    190 			{
    191 				result = kHalfWordSize;
    192 			}
    193 			else
    194 			{
    195 				result = kByteSize;
    196 			}
    197 			break;
    198 	}
    199 
    200 	return result;
    201 }
    202 
    203 #pragma mark = IntConstExprASTNode =
    204 
    205 IntConstExprASTNode::IntConstExprASTNode(const IntConstExprASTNode & other)
    206 :	ExprASTNode(other), m_value(other.m_value), m_size(other.m_size)
    207 {
    208 }
    209 
    210 void IntConstExprASTNode::printTree(int indent) const
    211 {
    212 	printIndent(indent);
    213 	char sizeChar='?';
    214 	switch (m_size)
    215 	{
    216 		case kWordSize:
    217 			sizeChar = 'w';
    218 			break;
    219 		case kHalfWordSize:
    220 			sizeChar = 'h';
    221 			break;
    222 		case kByteSize:
    223 			sizeChar = 'b';
    224 			break;
    225 	}
    226 	printf("%s(%d:%c)\n", nodeName().c_str(), m_value, sizeChar);
    227 }
    228 
    229 #pragma mark = VariableExprASTNode =
    230 
    231 VariableExprASTNode::VariableExprASTNode(const VariableExprASTNode & other)
    232 :	ExprASTNode(other), m_variable()
    233 {
    234 	m_variable = new std::string(*other.m_variable);
    235 }
    236 
    237 void VariableExprASTNode::printTree(int indent) const
    238 {
    239 	printIndent(indent);
    240 	printf("%s(%s)\n", nodeName().c_str(), m_variable->c_str());
    241 }
    242 
    243 ExprASTNode * VariableExprASTNode::reduce(EvalContext & context)
    244 {
    245 	if (!context.isVariableDefined(*m_variable))
    246 	{
    247 		throw std::runtime_error(format_string("line %d: undefined variable '%s'", getFirstLine(), m_variable->c_str()));
    248 	}
    249 
    250 	uint32_t value = context.getVariableValue(*m_variable);
    251 	int_size_t size = context.getVariableSize(*m_variable);
    252 	return new IntConstExprASTNode(value, size);
    253 }
    254 
    255 #pragma mark = SymbolRefExprASTNode =
    256 
    257 SymbolRefExprASTNode::SymbolRefExprASTNode(const SymbolRefExprASTNode & other)
    258 :	ExprASTNode(other), m_symbol(NULL)
    259 {
    260 	if (other.m_symbol)
    261 	{
    262 		m_symbol = dynamic_cast<SymbolASTNode*>(other.m_symbol->clone());
    263 	}
    264 }
    265 
    266 void SymbolRefExprASTNode::printTree(int indent) const
    267 {
    268 }
    269 
    270 ExprASTNode * SymbolRefExprASTNode::reduce(EvalContext & context)
    271 {
    272 	EvalContext::SourceFileManager * manager = context.getSourceFileManager();
    273 	if (!manager)
    274 	{
    275 		throw std::runtime_error("no source manager available");
    276 	}
    277 
    278 	if (!m_symbol)
    279 	{
    280 		throw semantic_error("no symbol provided");
    281 	}
    282 
    283 	// Get the name of the symbol
    284 	std::string * symbolName = m_symbol->getSymbolName();
    285 //	if (!symbolName)
    286 //	{
    287 //		throw semantic_error(format_string("line %d: no symbol name provided", getFirstLine()));
    288 //	}
    289 
    290 	// Get the source file.
    291 	std::string * sourceName = m_symbol->getSource();
    292 	SourceFile * sourceFile;
    293 
    294 	if (sourceName)
    295 	{
    296 		sourceFile = manager->getSourceFile(*sourceName);
    297 		if (!sourceFile)
    298 		{
    299 			throw semantic_error(format_string("line %d: no source file named %s", getFirstLine(), sourceName->c_str()));
    300 		}
    301 	}
    302 	else
    303 	{
    304 		sourceFile = manager->getDefaultSourceFile();
    305 		if (!sourceFile)
    306 		{
    307 			throw semantic_error(format_string("line %d: no default source file is set", getFirstLine()));
    308 		}
    309 	}
    310 
    311 	// open the file if it hasn't already been
    312 	if (!sourceFile->isOpen())
    313 	{
    314 		sourceFile->open();
    315 	}
    316 
    317 	// Make sure the source file supports symbols before going any further
    318 	if (symbolName && !sourceFile->supportsNamedSymbols())
    319 	{
    320 		throw semantic_error(format_string("line %d: source file %s does not support symbols", getFirstLine(), sourceFile->getPath().c_str()));
    321 	}
    322 
    323     if (!symbolName && !sourceFile->hasEntryPoint())
    324     {
    325         throw semantic_error(format_string("line %d: source file %s does not have an entry point", getFirstLine(), sourceFile->getPath().c_str()));
    326     }
    327 
    328 	// Returns a const expr node with the symbol's value.
    329 	uint32_t value;
    330     if (symbolName)
    331     {
    332         value = sourceFile->getSymbolValue(*symbolName);
    333     }
    334     else
    335     {
    336         value = sourceFile->getEntryPointAddress();
    337     }
    338 	return new IntConstExprASTNode(value);
    339 }
    340 
    341 #pragma mark = NegativeExprASTNode =
    342 
    343 NegativeExprASTNode::NegativeExprASTNode(const NegativeExprASTNode & other)
    344 :	ExprASTNode(other), m_expr()
    345 {
    346 	m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
    347 }
    348 
    349 void NegativeExprASTNode::printTree(int indent) const
    350 {
    351 	ExprASTNode::printTree(indent);
    352 	if (m_expr) m_expr->printTree(indent + 1);
    353 }
    354 
    355 ExprASTNode * NegativeExprASTNode::reduce(EvalContext & context)
    356 {
    357 	if (!m_expr)
    358 	{
    359 		return this;
    360 	}
    361 
    362 	m_expr = m_expr->reduce(context);
    363 	IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get());
    364 	if (intConst)
    365 	{
    366 	    int32_t value = -(int32_t)intConst->getValue();
    367 		return new IntConstExprASTNode((uint32_t)value, intConst->getSize());
    368 	}
    369 	else
    370 	{
    371 		return this;
    372 	}
    373 }
    374 
    375 #pragma mark = BooleanNotExprASTNode =
    376 
    377 BooleanNotExprASTNode::BooleanNotExprASTNode(const BooleanNotExprASTNode & other)
    378 :	ExprASTNode(other), m_expr()
    379 {
    380 	m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
    381 }
    382 
    383 void BooleanNotExprASTNode::printTree(int indent) const
    384 {
    385 	ExprASTNode::printTree(indent);
    386 	if (m_expr) m_expr->printTree(indent + 1);
    387 }
    388 
    389 ExprASTNode * BooleanNotExprASTNode::reduce(EvalContext & context)
    390 {
    391 	if (!m_expr)
    392 	{
    393 		return this;
    394 	}
    395 
    396 	m_expr = m_expr->reduce(context);
    397 	IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get());
    398 	if (intConst)
    399 	{
    400 	    int32_t value = !((int32_t)intConst->getValue());
    401 		return new IntConstExprASTNode((uint32_t)value, intConst->getSize());
    402 	}
    403 	else
    404 	{
    405 		throw semantic_error(format_string("line %d: expression did not evaluate to an integer", m_expr->getFirstLine()));
    406 	}
    407 }
    408 
    409 #pragma mark = SourceFileFunctionASTNode =
    410 
    411 SourceFileFunctionASTNode::SourceFileFunctionASTNode(const SourceFileFunctionASTNode & other)
    412 :	ExprASTNode(other), m_functionName(), m_sourceFile()
    413 {
    414 	m_functionName = new std::string(*other.m_functionName);
    415 	m_sourceFile = new std::string(*other.m_sourceFile);
    416 }
    417 
    418 void SourceFileFunctionASTNode::printTree(int indent) const
    419 {
    420 	ExprASTNode::printTree(indent);
    421 	printIndent(indent+1);
    422 
    423 	// for some stupid reason the msft C++ compiler barfs on the following line if the ".get()" parts are remove,
    424 	// even though the first line of reduce() below has the same expression, just in parentheses. stupid compiler.
    425 	if (m_functionName.get() && m_sourceFile.get())
    426 	{
    427 		printf("%s ( %s )\n", m_functionName->c_str(), m_sourceFile->c_str());
    428 	}
    429 }
    430 
    431 ExprASTNode * SourceFileFunctionASTNode::reduce(EvalContext & context)
    432 {
    433 	if (!(m_functionName && m_sourceFile))
    434 	{
    435 		throw std::runtime_error("unset function name or source file");
    436 	}
    437 
    438 	// Get source file manager from evaluation context. This will be the
    439 	// conversion controller itself.
    440 	EvalContext::SourceFileManager * mgr = context.getSourceFileManager();
    441 	if (!mgr)
    442 	{
    443 		throw std::runtime_error("source file manager is not set");
    444 	}
    445 
    446 	// Perform function
    447 	uint32_t functionResult = 0;
    448 	if (*m_functionName == "exists")
    449 	{
    450 		functionResult = static_cast<uint32_t>(mgr->hasSourceFile(*m_sourceFile));
    451 	}
    452 
    453 	// Return function result as an expression node
    454 	return new IntConstExprASTNode(functionResult);
    455 }
    456 
    457 #pragma mark = DefinedOperatorASTNode =
    458 
    459 DefinedOperatorASTNode::DefinedOperatorASTNode(const DefinedOperatorASTNode & other)
    460 :	ExprASTNode(other), m_constantName()
    461 {
    462 	m_constantName = new std::string(*other.m_constantName);
    463 }
    464 
    465 void DefinedOperatorASTNode::printTree(int indent) const
    466 {
    467 	ExprASTNode::printTree(indent);
    468 	printIndent(indent+1);
    469 
    470 	if (m_constantName)
    471 	{
    472 		printf("defined ( %s )\n", m_constantName->c_str());
    473 	}
    474 }
    475 
    476 ExprASTNode * DefinedOperatorASTNode::reduce(EvalContext & context)
    477 {
    478 	assert(m_constantName);
    479 
    480 	// Return function result as an expression node
    481 	return new IntConstExprASTNode(context.isVariableDefined(m_constantName) ? 1 : 0);
    482 }
    483 
    484 #pragma mark = SizeofOperatorASTNode =
    485 
    486 SizeofOperatorASTNode::SizeofOperatorASTNode(const SizeofOperatorASTNode & other)
    487 :	ExprASTNode(other), m_constantName(), m_symbol()
    488 {
    489 	m_constantName = new std::string(*other.m_constantName);
    490 	m_symbol = dynamic_cast<SymbolASTNode*>(other.m_symbol->clone());
    491 }
    492 
    493 void SizeofOperatorASTNode::printTree(int indent) const
    494 {
    495 	ExprASTNode::printTree(indent);
    496 
    497 	printIndent(indent+1);
    498 
    499 	if (m_constantName)
    500 	{
    501 		printf("sizeof: %s\n", m_constantName->c_str());
    502 	}
    503 	else if (m_symbol)
    504 	{
    505 		printf("sizeof:\n");
    506 		m_symbol->printTree(indent + 2);
    507 	}
    508 }
    509 
    510 ExprASTNode * SizeofOperatorASTNode::reduce(EvalContext & context)
    511 {
    512 	// One or the other must be defined.
    513 	assert(m_constantName || m_symbol);
    514 
    515 	EvalContext::SourceFileManager * manager = context.getSourceFileManager();
    516 	assert(manager);
    517 
    518 	unsigned sizeInBytes = 0;
    519 	SourceFile * sourceFile;
    520 
    521 	if (m_symbol)
    522 	{
    523 		// Get the symbol name.
    524 		std::string * symbolName = m_symbol->getSymbolName();
    525 		assert(symbolName);
    526 
    527 		// Get the source file, using the default if one is not specified.
    528 		std::string * sourceName = m_symbol->getSource();
    529 		if (sourceName)
    530 		{
    531 			sourceFile = manager->getSourceFile(*sourceName);
    532 			if (!sourceFile)
    533 			{
    534 				throw semantic_error(format_string("line %d: invalid source file: %s", getFirstLine(), sourceName->c_str()));
    535 			}
    536 		}
    537 		else
    538 		{
    539 			sourceFile = manager->getDefaultSourceFile();
    540 			if (!sourceFile)
    541 			{
    542 				throw semantic_error(format_string("line %d: no default source file is set", getFirstLine()));
    543 			}
    544 		}
    545 
    546 		// Get the size of the symbol.
    547 		if (sourceFile->hasSymbol(*symbolName))
    548 		{
    549 			sizeInBytes = sourceFile->getSymbolSize(*symbolName);
    550 		}
    551 	}
    552 	else if (m_constantName)
    553 	{
    554 		// See if the "constant" is really a constant or if it's a source name.
    555 		if (manager->hasSourceFile(m_constantName))
    556 		{
    557 			sourceFile = manager->getSourceFile(m_constantName);
    558 			if (sourceFile)
    559 			{
    560 				sizeInBytes = sourceFile->getSize();
    561 			}
    562 		}
    563 		else
    564 		{
    565 			// Regular constant.
    566 			if (!context.isVariableDefined(*m_constantName))
    567 			{
    568 				throw semantic_error(format_string("line %d: cannot get size of undefined constant %s", getFirstLine(), m_constantName->c_str()));
    569 			}
    570 
    571 			int_size_t intSize = context.getVariableSize(*m_constantName);
    572 			switch (intSize)
    573 			{
    574 				case kWordSize:
    575 					sizeInBytes = sizeof(uint32_t);
    576 					break;
    577 				case kHalfWordSize:
    578 					sizeInBytes = sizeof(uint16_t);
    579 					break;
    580 				case kByteSize:
    581 					sizeInBytes = sizeof(uint8_t);
    582 					break;
    583 			}
    584 		}
    585 	}
    586 
    587 	// Return function result as an expression node
    588 	return new IntConstExprASTNode(sizeInBytes);
    589 }
    590 
    591 #pragma mark = BinaryOpExprASTNode =
    592 
    593 BinaryOpExprASTNode::BinaryOpExprASTNode(const BinaryOpExprASTNode & other)
    594 :	ExprASTNode(other), m_left(), m_op(other.m_op), m_right()
    595 {
    596 	m_left = dynamic_cast<ExprASTNode*>(other.m_left->clone());
    597 	m_right = dynamic_cast<ExprASTNode*>(other.m_right->clone());
    598 }
    599 
    600 void BinaryOpExprASTNode::printTree(int indent) const
    601 {
    602 	ExprASTNode::printTree(indent);
    603 
    604 	printIndent(indent + 1);
    605 	printf("left:\n");
    606 	if (m_left) m_left->printTree(indent + 2);
    607 
    608 	printIndent(indent + 1);
    609 	printf("op: %s\n", getOperatorName().c_str());
    610 
    611 	printIndent(indent + 1);
    612 	printf("right:\n");
    613 	if (m_right) m_right->printTree(indent + 2);
    614 }
    615 
    616 std::string BinaryOpExprASTNode::getOperatorName() const
    617 {
    618 	switch (m_op)
    619 	{
    620 		case kAdd:
    621 			return "+";
    622 		case kSubtract:
    623 			return "-";
    624 		case kMultiply:
    625 			return "*";
    626 		case kDivide:
    627 			return "/";
    628 		case kModulus:
    629 			return "%";
    630 		case kPower:
    631 			return "**";
    632 		case kBitwiseAnd:
    633 			return "&";
    634 		case kBitwiseOr:
    635 			return "|";
    636 		case kBitwiseXor:
    637 			return "^";
    638 		case kShiftLeft:
    639 			return "<<";
    640 		case kShiftRight:
    641 			return ">>";
    642 		case kLessThan:
    643 			return "<";
    644 		case kGreaterThan:
    645 			return ">";
    646 		case kLessThanEqual:
    647 			return "<=";
    648 		case kGreaterThanEqual:
    649 			return ">";
    650 		case kEqual:
    651 			return "==";
    652 		case kNotEqual:
    653 			return "!=";
    654 		case kBooleanAnd:
    655 			return "&&";
    656 		case kBooleanOr:
    657 			return "||";
    658 	}
    659 
    660 	return "???";
    661 }
    662 
    663 //! \todo Fix power operator under windows!!!
    664 //!
    665 ExprASTNode * BinaryOpExprASTNode::reduce(EvalContext & context)
    666 {
    667 	if (!m_left || !m_right)
    668 	{
    669 		return this;
    670 	}
    671 
    672 	IntConstExprASTNode * leftIntConst = NULL;
    673 	IntConstExprASTNode * rightIntConst = NULL;
    674 	uint32_t leftValue;
    675 	uint32_t rightValue;
    676 	uint32_t result = 0;
    677 
    678 	// Always reduce the left hand side.
    679 	m_left = m_left->reduce(context);
    680 	leftIntConst = dynamic_cast<IntConstExprASTNode*>(m_left.get());
    681 	if (!leftIntConst)
    682 	{
    683 		throw semantic_error(format_string("left hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str()));
    684 	}
    685 	leftValue = leftIntConst->getValue();
    686 
    687 	// Boolean && and || operators are handled separately so that we can perform
    688 	// short-circuit evaluation.
    689 	if (m_op == kBooleanAnd || m_op == kBooleanOr)
    690 	{
    691 		// Reduce right hand side only if required to evaluate the boolean operator.
    692 		if ((m_op == kBooleanAnd && leftValue != 0) || (m_op == kBooleanOr && leftValue == 0))
    693 		{
    694 			m_right = m_right->reduce(context);
    695 			rightIntConst = dynamic_cast<IntConstExprASTNode*>(m_right.get());
    696 			if (!rightIntConst)
    697 			{
    698 				throw semantic_error(format_string("right hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str()));
    699 			}
    700 			rightValue = rightIntConst->getValue();
    701 
    702 			// Perform the boolean operation.
    703 			switch (m_op)
    704 			{
    705 				case kBooleanAnd:
    706 					result = leftValue && rightValue;
    707 					break;
    708 
    709 				case kBooleanOr:
    710 					result = leftValue && rightValue;
    711 					break;
    712 			}
    713 		}
    714 		else if (m_op == kBooleanAnd)
    715 		{
    716 			// The left hand side is false, so the && operator's result must be false
    717 			// without regard to the right hand side.
    718 			result = 0;
    719 		}
    720 		else if (m_op == kBooleanOr)
    721 		{
    722 			// The left hand value is true so the || result is automatically true.
    723 			result = 1;
    724 		}
    725 	}
    726 	else
    727 	{
    728 		// Reduce right hand side always for most operators.
    729 		m_right = m_right->reduce(context);
    730 		rightIntConst = dynamic_cast<IntConstExprASTNode*>(m_right.get());
    731 		if (!rightIntConst)
    732 		{
    733 			throw semantic_error(format_string("right hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str()));
    734 		}
    735 		rightValue = rightIntConst->getValue();
    736 
    737 		switch (m_op)
    738 		{
    739 			case kAdd:
    740 				result = leftValue + rightValue;
    741 				break;
    742 			case kSubtract:
    743 				result = leftValue - rightValue;
    744 				break;
    745 			case kMultiply:
    746 				result = leftValue * rightValue;
    747 				break;
    748 			case kDivide:
    749 				result = leftValue / rightValue;
    750 				break;
    751 			case kModulus:
    752 				result = leftValue % rightValue;
    753 				break;
    754 			case kPower:
    755 			#ifdef WIN32
    756 				result = 0;
    757 			#else
    758 				result = lroundf(powf(float(leftValue), float(rightValue)));
    759 			#endif
    760 				break;
    761 			case kBitwiseAnd:
    762 				result = leftValue & rightValue;
    763 				break;
    764 			case kBitwiseOr:
    765 				result = leftValue | rightValue;
    766 				break;
    767 			case kBitwiseXor:
    768 				result = leftValue ^ rightValue;
    769 				break;
    770 			case kShiftLeft:
    771 				result = leftValue << rightValue;
    772 				break;
    773 			case kShiftRight:
    774 				result = leftValue >> rightValue;
    775 				break;
    776 			case kLessThan:
    777 				result = leftValue < rightValue;
    778 				break;
    779 			case kGreaterThan:
    780 				result = leftValue > rightValue;
    781 				break;
    782 			case kLessThanEqual:
    783 				result = leftValue <= rightValue;
    784 				break;
    785 			case kGreaterThanEqual:
    786 				result = leftValue >= rightValue;
    787 				break;
    788 			case kEqual:
    789 				result = leftValue == rightValue;
    790 				break;
    791 			case kNotEqual:
    792 				result = leftValue != rightValue;
    793 				break;
    794 		}
    795 	}
    796 
    797 	// Create the result value.
    798 	int_size_t resultSize;
    799 	if (leftIntConst && rightIntConst)
    800 	{
    801 		resultSize = resultIntSize(leftIntConst->getSize(), rightIntConst->getSize());
    802 	}
    803 	else if (leftIntConst)
    804 	{
    805 		resultSize = leftIntConst->getSize();
    806 	}
    807 	else
    808 	{
    809 		// This shouldn't really be possible, but just in case.
    810 		resultSize = kWordSize;
    811 	}
    812 	return new IntConstExprASTNode(result, resultSize);
    813 }
    814 
    815 #pragma mark = IntSizeExprASTNode =
    816 
    817 IntSizeExprASTNode::IntSizeExprASTNode(const IntSizeExprASTNode & other)
    818 :	ExprASTNode(other), m_expr(), m_size(other.m_size)
    819 {
    820 	m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
    821 }
    822 
    823 void IntSizeExprASTNode::printTree(int indent) const
    824 {
    825 	ExprASTNode::printTree(indent);
    826 
    827 	char sizeChar='?';
    828 	switch (m_size)
    829 	{
    830 		case kWordSize:
    831 			sizeChar = 'w';
    832 			break;
    833 		case kHalfWordSize:
    834 			sizeChar = 'h';
    835 			break;
    836 		case kByteSize:
    837 			sizeChar = 'b';
    838 			break;
    839 	}
    840 	printIndent(indent + 1);
    841 	printf("size: %c\n", sizeChar);
    842 
    843 	printIndent(indent + 1);
    844 	printf("expr:\n");
    845 	if (m_expr) m_expr->printTree(indent + 2);
    846 }
    847 
    848 ExprASTNode * IntSizeExprASTNode::reduce(EvalContext & context)
    849 {
    850 	if (!m_expr)
    851 	{
    852 		return this;
    853 	}
    854 
    855 	m_expr = m_expr->reduce(context);
    856 	IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get());
    857 	if (!intConst)
    858 	{
    859 		return this;
    860 	}
    861 
    862 	return new IntConstExprASTNode(intConst->getValue(), m_size);
    863 }
    864 
    865 #pragma mark = ExprConstASTNode =
    866 
    867 ExprConstASTNode::ExprConstASTNode(const ExprConstASTNode & other)
    868 :	ConstASTNode(other), m_expr()
    869 {
    870 	m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
    871 }
    872 
    873 void ExprConstASTNode::printTree(int indent) const
    874 {
    875 	ConstASTNode::printTree(indent);
    876 	if (m_expr) m_expr->printTree(indent + 1);
    877 }
    878 
    879 #pragma mark = StringConstASTNode =
    880 
    881 StringConstASTNode::StringConstASTNode(const StringConstASTNode & other)
    882 :	ConstASTNode(other), m_value()
    883 {
    884 	m_value = new std::string(other.m_value);
    885 }
    886 
    887 void StringConstASTNode::printTree(int indent) const
    888 {
    889 	printIndent(indent);
    890 	printf("%s(%s)\n", nodeName().c_str(), m_value->c_str());
    891 }
    892 
    893 #pragma mark = BlobConstASTNode =
    894 
    895 BlobConstASTNode::BlobConstASTNode(const BlobConstASTNode & other)
    896 :	ConstASTNode(other), m_blob()
    897 {
    898 	m_blob = new Blob(*other.m_blob);
    899 }
    900 
    901 void BlobConstASTNode::printTree(int indent) const
    902 {
    903 	printIndent(indent);
    904 
    905 	const uint8_t * dataPtr = m_blob->getData();
    906 	unsigned dataLen = m_blob->getLength();
    907 	printf("%s(%p:%d)\n", nodeName().c_str(), dataPtr, dataLen);
    908 }
    909 
    910 #pragma mark = IVTConstASTNode =
    911 
    912 IVTConstASTNode::IVTConstASTNode(const IVTConstASTNode & other)
    913 :	ConstASTNode(other), m_fields()
    914 {
    915 	m_fields = dynamic_cast<ListASTNode*>(other.m_fields->clone());
    916 }
    917 
    918 void IVTConstASTNode::printTree(int indent) const
    919 {
    920 	printIndent(indent);
    921 	printf("%s:\n", nodeName().c_str());
    922     if (m_fields)
    923     {
    924         m_fields->printTree(indent + 1);
    925     }
    926 }
    927 
    928 #pragma mark = AssignmentASTNode =
    929 
    930 AssignmentASTNode::AssignmentASTNode(const AssignmentASTNode & other)
    931 :	ASTNode(other), m_ident(), m_value()
    932 {
    933 	m_ident = new std::string(*other.m_ident);
    934 	m_value = dynamic_cast<ConstASTNode*>(other.m_value->clone());
    935 }
    936 
    937 void AssignmentASTNode::printTree(int indent) const
    938 {
    939 	printIndent(indent);
    940 	printf("%s(%s)\n", nodeName().c_str(), m_ident->c_str());
    941 
    942 	if (m_value) m_value->printTree(indent + 1);
    943 }
    944 
    945 #pragma mark = SourceDefASTNode =
    946 
    947 SourceDefASTNode::SourceDefASTNode(const SourceDefASTNode & other)
    948 :	ASTNode(other), m_name()
    949 {
    950 	m_name = new std::string(*other.m_name);
    951 }
    952 
    953 #pragma mark = PathSourceDefASTNode =
    954 
    955 PathSourceDefASTNode::PathSourceDefASTNode(const PathSourceDefASTNode & other)
    956 :	SourceDefASTNode(other), m_path()
    957 {
    958 	m_path = new std::string(*other.m_path);
    959 }
    960 
    961 void PathSourceDefASTNode::printTree(int indent) const
    962 {
    963 	SourceDefASTNode::printTree(indent);
    964 
    965 	printIndent(indent+1);
    966 	printf("path: %s\n", m_path->c_str());
    967 
    968 	printIndent(indent+1);
    969 	printf("attributes:\n");
    970 	if (m_attributes)
    971 	{
    972 		m_attributes->printTree(indent+2);
    973 	}
    974 }
    975 
    976 #pragma mark = ExternSourceDefASTNode =
    977 
    978 ExternSourceDefASTNode::ExternSourceDefASTNode(const ExternSourceDefASTNode & other)
    979 :	SourceDefASTNode(other), m_expr()
    980 {
    981 	m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
    982 }
    983 
    984 void ExternSourceDefASTNode::printTree(int indent) const
    985 {
    986 	SourceDefASTNode::printTree(indent);
    987 
    988 	printIndent(indent+1);
    989 	printf("expr:\n");
    990 	if (m_expr) m_expr->printTree(indent + 2);
    991 
    992 	printIndent(indent+1);
    993 	printf("attributes:\n");
    994 	if (m_attributes)
    995 	{
    996 		m_attributes->printTree(indent+2);
    997 	}
    998 }
    999 
   1000 #pragma mark = SectionContentsASTNode =
   1001 
   1002 SectionContentsASTNode::SectionContentsASTNode(const SectionContentsASTNode & other)
   1003 :	ASTNode(other), m_sectionExpr()
   1004 {
   1005 	m_sectionExpr = dynamic_cast<ExprASTNode*>(other.m_sectionExpr->clone());
   1006 }
   1007 
   1008 void SectionContentsASTNode::printTree(int indent) const
   1009 {
   1010 	ASTNode::printTree(indent);
   1011 
   1012 	printIndent(indent + 1);
   1013 	printf("section#:\n");
   1014 	if (m_sectionExpr) m_sectionExpr->printTree(indent + 2);
   1015 }
   1016 
   1017 #pragma mark = DataSectionContentsASTNode =
   1018 
   1019 DataSectionContentsASTNode::DataSectionContentsASTNode(const DataSectionContentsASTNode & other)
   1020 :	SectionContentsASTNode(other), m_contents()
   1021 {
   1022 	m_contents = dynamic_cast<ASTNode*>(other.m_contents->clone());
   1023 }
   1024 
   1025 void DataSectionContentsASTNode::printTree(int indent) const
   1026 {
   1027 	SectionContentsASTNode::printTree(indent);
   1028 
   1029 	if (m_contents)
   1030 	{
   1031 		m_contents->printTree(indent + 1);
   1032 	}
   1033 }
   1034 
   1035 #pragma mark = BootableSectionContentsASTNode =
   1036 
   1037 BootableSectionContentsASTNode::BootableSectionContentsASTNode(const BootableSectionContentsASTNode & other)
   1038 :	SectionContentsASTNode(other), m_statements()
   1039 {
   1040 	m_statements = dynamic_cast<ListASTNode*>(other.m_statements->clone());
   1041 }
   1042 
   1043 void BootableSectionContentsASTNode::printTree(int indent) const
   1044 {
   1045 	SectionContentsASTNode::printTree(indent);
   1046 
   1047 	printIndent(indent + 1);
   1048 	printf("statements:\n");
   1049 	if (m_statements) m_statements->printTree(indent + 2);
   1050 }
   1051 
   1052 #pragma mark = IfStatementASTNode =
   1053 
   1054 //! \warning Be careful; this method could enter an infinite loop if m_nextIf feeds
   1055 //!		back onto itself. m_nextIf must be NULL at some point down the next if list.
   1056 IfStatementASTNode::IfStatementASTNode(const IfStatementASTNode & other)
   1057 :	StatementASTNode(),
   1058 	m_conditionExpr(),
   1059 	m_ifStatements(),
   1060 	m_nextIf(),
   1061 	m_elseStatements()
   1062 {
   1063 	m_conditionExpr = dynamic_cast<ExprASTNode*>(other.m_conditionExpr->clone());
   1064 	m_ifStatements = dynamic_cast<ListASTNode*>(other.m_ifStatements->clone());
   1065 	m_nextIf = dynamic_cast<IfStatementASTNode*>(other.m_nextIf->clone());
   1066 	m_elseStatements = dynamic_cast<ListASTNode*>(other.m_elseStatements->clone());
   1067 }
   1068 
   1069 #pragma mark = ModeStatementASTNode =
   1070 
   1071 ModeStatementASTNode::ModeStatementASTNode(const ModeStatementASTNode & other)
   1072 :	StatementASTNode(other), m_modeExpr()
   1073 {
   1074 	m_modeExpr = dynamic_cast<ExprASTNode*>(other.m_modeExpr->clone());
   1075 }
   1076 
   1077 void ModeStatementASTNode::printTree(int indent) const
   1078 {
   1079 	StatementASTNode::printTree(indent);
   1080 	printIndent(indent + 1);
   1081 	printf("mode:\n");
   1082 	if (m_modeExpr) m_modeExpr->printTree(indent + 2);
   1083 }
   1084 
   1085 #pragma mark = MessageStatementASTNode =
   1086 
   1087 MessageStatementASTNode::MessageStatementASTNode(const MessageStatementASTNode & other)
   1088 :	StatementASTNode(other), m_type(other.m_type), m_message()
   1089 {
   1090 	m_message = new std::string(*other.m_message);
   1091 }
   1092 
   1093 void MessageStatementASTNode::printTree(int indent) const
   1094 {
   1095 	StatementASTNode::printTree(indent);
   1096 	printIndent(indent + 1);
   1097 	printf("%s: %s\n", getTypeName(), m_message->c_str());
   1098 }
   1099 
   1100 const char * MessageStatementASTNode::getTypeName() const
   1101 {
   1102 	switch (m_type)
   1103 	{
   1104 		case kInfo:
   1105 			return "info";
   1106 
   1107 		case kWarning:
   1108 			return "warning";
   1109 
   1110 		case kError:
   1111 			return "error";
   1112 	}
   1113 
   1114 	return "unknown";
   1115 }
   1116 
   1117 #pragma mark = LoadStatementASTNode =
   1118 
   1119 LoadStatementASTNode::LoadStatementASTNode(const LoadStatementASTNode & other)
   1120 :	StatementASTNode(other), m_data(), m_target(), m_isDCDLoad(other.m_isDCDLoad)
   1121 {
   1122 	m_data = other.m_data->clone();
   1123 	m_target = other.m_target->clone();
   1124 }
   1125 
   1126 void LoadStatementASTNode::printTree(int indent) const
   1127 {
   1128 	StatementASTNode::printTree(indent);
   1129 
   1130 	printIndent(indent + 1);
   1131 	printf("data:\n");
   1132 	if (m_data) m_data->printTree(indent + 2);
   1133 
   1134 	printIndent(indent + 1);
   1135 	printf("target:\n");
   1136 	if (m_target) m_target->printTree(indent + 2);
   1137 }
   1138 
   1139 #pragma mark = CallStatementASTNode =
   1140 
   1141 CallStatementASTNode::CallStatementASTNode(const CallStatementASTNode & other)
   1142 :	StatementASTNode(other), m_type(other.m_type), m_target(), m_arg()
   1143 {
   1144 	m_target = other.m_target->clone();
   1145 	m_arg = other.m_arg->clone();
   1146 }
   1147 
   1148 void CallStatementASTNode::printTree(int indent) const
   1149 {
   1150 	printIndent(indent);
   1151 	printf("%s(%s)%s\n", nodeName().c_str(), (m_type == kCallType ? "call" : "jump"), (m_isHAB ? "/HAB" : ""));
   1152 
   1153 	printIndent(indent + 1);
   1154 	printf("target:\n");
   1155 	if (m_target) m_target->printTree(indent + 2);
   1156 
   1157 	printIndent(indent + 1);
   1158 	printf("arg:\n");
   1159 	if (m_arg) m_arg->printTree(indent + 2);
   1160 }
   1161 
   1162 #pragma mark = SourceASTNode =
   1163 
   1164 SourceASTNode::SourceASTNode(const SourceASTNode & other)
   1165 :	ASTNode(other), m_name()
   1166 {
   1167 	m_name = new std::string(*other.m_name);
   1168 }
   1169 
   1170 void SourceASTNode::printTree(int indent) const
   1171 {
   1172 	printIndent(indent);
   1173 	printf("%s(%s)\n", nodeName().c_str(), m_name->c_str());
   1174 }
   1175 
   1176 #pragma mark = SectionMatchListASTNode =
   1177 
   1178 SectionMatchListASTNode::SectionMatchListASTNode(const SectionMatchListASTNode & other)
   1179 :	ASTNode(other), m_sections(), m_source()
   1180 {
   1181 	if (other.m_sections)
   1182 	{
   1183 		m_sections = dynamic_cast<ListASTNode *>(other.m_sections->clone());
   1184 	}
   1185 
   1186 	if (other.m_source)
   1187 	{
   1188 		m_source = new std::string(*other.m_source);
   1189 	}
   1190 }
   1191 
   1192 void SectionMatchListASTNode::printTree(int indent) const
   1193 {
   1194 	ASTNode::printTree(indent);
   1195 
   1196 	printIndent(indent+1);
   1197 	printf("sections:\n");
   1198 	if (m_sections)
   1199 	{
   1200 		m_sections->printTree(indent+2);
   1201 	}
   1202 
   1203 	printIndent(indent+1);
   1204 	printf("source: ");
   1205 	if (m_source)
   1206 	{
   1207 		printf("%s\n", m_source->c_str());
   1208 	}
   1209 	else
   1210 	{
   1211 		printf("\n");
   1212 	}
   1213 }
   1214 
   1215 #pragma mark = SectionASTNode =
   1216 
   1217 SectionASTNode::SectionASTNode(const SectionASTNode & other)
   1218 :	ASTNode(other), m_name(), m_source()
   1219 {
   1220 	m_action = other.m_action;
   1221 
   1222 	if (other.m_name)
   1223 	{
   1224 		m_name = new std::string(*other.m_name);
   1225 	}
   1226 
   1227 	if (other.m_source)
   1228 	{
   1229 		m_source = new std::string(*other.m_source);
   1230 	}
   1231 }
   1232 
   1233 void SectionASTNode::printTree(int indent) const
   1234 {
   1235 	printIndent(indent);
   1236 
   1237 	const char * actionName;
   1238 	switch (m_action)
   1239 	{
   1240 		case kInclude:
   1241 			actionName = "include";
   1242 			break;
   1243 		case kExclude:
   1244 			actionName = "exclude";
   1245 			break;
   1246 	}
   1247 
   1248 	if (m_source)
   1249 	{
   1250 		printf("%s(%s:%s:%s)\n", nodeName().c_str(), actionName, m_name->c_str(), m_source->c_str());
   1251 	}
   1252 	else
   1253 	{
   1254 		printf("%s(%s:%s)\n", nodeName().c_str(), actionName, m_name->c_str());
   1255 	}
   1256 }
   1257 
   1258 #pragma mark = SymbolASTNode =
   1259 
   1260 SymbolASTNode::SymbolASTNode(const SymbolASTNode & other)
   1261 :	ASTNode(other), m_symbol(), m_source()
   1262 {
   1263 	m_symbol = new std::string(*other.m_symbol);
   1264 	m_source = new std::string(*other.m_source);
   1265 }
   1266 
   1267 void SymbolASTNode::printTree(int indent) const
   1268 {
   1269 	printIndent(indent);
   1270 
   1271 	const char * symbol = NULL;
   1272 	if (m_symbol)
   1273 	{
   1274 		symbol = m_symbol->c_str();
   1275 	}
   1276 
   1277 	const char * source = NULL;
   1278 	if (m_source)
   1279 	{
   1280 		source = m_source->c_str();
   1281 	}
   1282 
   1283 	printf("%s(", nodeName().c_str());
   1284 	if (source)
   1285 	{
   1286 		printf("%s", source);
   1287 	}
   1288 	else
   1289 	{
   1290 		printf(".");
   1291 	}
   1292 	printf(":");
   1293 	if (symbol)
   1294 	{
   1295 		printf("%s", symbol);
   1296 	}
   1297 	else
   1298 	{
   1299 		printf(".");
   1300 	}
   1301 	printf(")\n");
   1302 }
   1303 
   1304 #pragma mark = AddressRangeASTNode =
   1305 
   1306 AddressRangeASTNode::AddressRangeASTNode(const AddressRangeASTNode & other)
   1307 :	ASTNode(other), m_begin(), m_end()
   1308 {
   1309 	m_begin = other.m_begin->clone();
   1310 	m_end = other.m_end->clone();
   1311 }
   1312 
   1313 void AddressRangeASTNode::printTree(int indent) const
   1314 {
   1315 	ASTNode::printTree(indent);
   1316 
   1317 	printIndent(indent + 1);
   1318 	printf("begin:\n");
   1319 	if (m_begin) m_begin->printTree(indent + 2);
   1320 
   1321 	printIndent(indent + 1);
   1322 	printf("end:\n");
   1323 	if (m_end) m_end->printTree(indent + 2);
   1324 }
   1325 
   1326 #pragma mark = FromStatementASTNode =
   1327 
   1328 FromStatementASTNode::FromStatementASTNode(std::string * source, ListASTNode * statements)
   1329 :	StatementASTNode(), m_source(source), m_statements(statements)
   1330 {
   1331 }
   1332 
   1333 FromStatementASTNode::FromStatementASTNode(const FromStatementASTNode & other)
   1334 :	StatementASTNode(), m_source(), m_statements()
   1335 {
   1336 	m_source = new std::string(*other.m_source);
   1337 	m_statements = dynamic_cast<ListASTNode*>(other.m_statements->clone());
   1338 }
   1339 
   1340 void FromStatementASTNode::printTree(int indent) const
   1341 {
   1342 	ASTNode::printTree(indent);
   1343 
   1344 	printIndent(indent + 1);
   1345 	printf("source: ");
   1346 	if (m_source) printf("%s\n", m_source->c_str());
   1347 
   1348 	printIndent(indent + 1);
   1349 	printf("statements:\n");
   1350 	if (m_statements) m_statements->printTree(indent + 2);
   1351 }
   1352 
   1353