1/*
2 * File:	ElftosbAST.h
3 *
4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5 * See included license file for license details.
6 */
7#if !defined(_ElftosbAST_h_)
8#define _ElftosbAST_h_
9
10#include "stdafx.h"
11#include <string>
12#include <list>
13#include "smart_ptr.h"
14#include "EvalContext.h"
15
16namespace elftosb
17{
18
19// forward reference
20class SymbolASTNode;
21
22/*!
23 * \brief Token location in the source file.
24 */
25struct token_loc_t
26{
27	int m_firstLine;	//!< Starting line of the token.
28	int m_lastLine;		//!< Ending line of the token.
29};
30
31/*!
32 * \brief The base class for all AST node classes.
33 */
34class ASTNode
35{
36public:
37	//! \brief Default constructor.
38	ASTNode() : m_parent(0) {}
39
40	//! \brief Constructor taking a parent node.
41	ASTNode(ASTNode * parent) : m_parent(parent) {}
42
43	//! \brief Copy constructor.
44	ASTNode(const ASTNode & other) : m_parent(other.m_parent) {}
45
46	//! \brief Destructor.
47	virtual ~ASTNode() {}
48
49	//! \brief Returns an exact duplicate of this object.
50	virtual ASTNode * clone() const = 0;
51
52	//! \brief Returns the name of the object's class.
53	virtual std::string nodeName() const { return "ASTNode"; }
54
55	//! \name Parents
56	//@{
57	virtual ASTNode * getParent() const { return m_parent; }
58	virtual void setParent(ASTNode * newParent) { m_parent = newParent; }
59	//@}
60
61	//! \name Tree printing
62	//@{
63	virtual void printTree() const { printTree(0); }
64	virtual void printTree(int indent) const;
65	//@}
66
67	//! \name Location
68	//@{
69	virtual void setLocation(token_loc_t & loc) { m_location = loc; }
70	virtual void setLocation(token_loc_t & first, token_loc_t & last);
71	virtual void setLocation(ASTNode * loc) { setLocation(loc->getLocation()); }
72	virtual void setLocation(ASTNode * first, ASTNode * last);
73
74	virtual token_loc_t & getLocation() { return m_location; }
75	virtual const token_loc_t & getLocation() const { return m_location; }
76
77	virtual int getFirstLine() { return m_location.m_firstLine; }
78	virtual int getLastLine() { return m_location.m_lastLine; }
79	//@}
80
81protected:
82	ASTNode * m_parent;	//!< Pointer to parent node of this object. May be NULL.
83	token_loc_t m_location;	//!< Location of this node in the source file.
84
85	//! \brief Prints \a indent number of spaces.
86	void printIndent(int indent) const;
87};
88
89/*!
90 * \brief AST node that contains other AST nodes.
91 *
92 * Unlike other AST nodes, the location of a ListASTNode is computed dynamically
93 * based on the nodes in its list. Or mostly dynamic at least. The updateLocation()
94 * method is used to force the list object to recalculate its beginning and ending
95 * line numbers.
96 *
97 * \todo Figure out why it crashes in the destructor when the
98 *       ast_list_t type is a list of smart_ptr<ASTNode>.
99 */
100class ListASTNode : public ASTNode
101{
102public:
103	typedef std::list< /*smart_ptr<ASTNode>*/ ASTNode * > ast_list_t;
104	typedef ast_list_t::iterator iterator;
105	typedef ast_list_t::const_iterator const_iterator;
106
107public:
108	ListASTNode() {}
109
110	ListASTNode(const ListASTNode & other);
111
112	virtual ~ListASTNode();
113
114	virtual ASTNode * clone() const { return new ListASTNode(*this); }
115
116	virtual std::string nodeName() const { return "ListASTNode"; }
117
118	virtual void printTree(int indent) const;
119
120	//! \name List operations
121	//@{
122	//! \brief Adds \a node to the end of the ordered list of child nodes.
123	virtual void appendNode(ASTNode * node);
124
125	//! \brief Returns the number of nodes in this list.
126	virtual unsigned nodeCount() const { return static_cast<unsigned>(m_list.size()); }
127	//@}
128
129	//! \name Node iterators
130	//@{
131	inline iterator begin() { return m_list.begin(); }
132	inline iterator end() { return m_list.end(); }
133
134	inline const_iterator begin() const { return m_list.begin(); }
135	inline const_iterator end() const { return m_list.end(); }
136	//@}
137
138	//! \name Location
139	//@{
140	virtual void updateLocation();
141	//@}
142
143protected:
144	ast_list_t m_list;	//!< Ordered list of child nodes.
145};
146
147/*!
148 *
149 */
150class OptionsBlockASTNode : public ASTNode
151{
152public:
153	OptionsBlockASTNode(ListASTNode * options) : ASTNode(), m_options(options) {}
154
155	inline ListASTNode * getOptions() { return m_options; }
156
157	virtual ASTNode * clone() const { return NULL; }
158
159protected:
160	smart_ptr<ListASTNode> m_options;
161};
162
163/*!
164 *
165 */
166class ConstantsBlockASTNode : public ASTNode
167{
168public:
169	ConstantsBlockASTNode(ListASTNode * constants) : ASTNode(), m_constants(constants) {}
170
171	inline ListASTNode * getConstants() { return m_constants; }
172
173	virtual ASTNode * clone() const { return NULL; }
174
175protected:
176	smart_ptr<ListASTNode> m_constants;
177};
178
179/*!
180 *
181 */
182class SourcesBlockASTNode : public ASTNode
183{
184public:
185	SourcesBlockASTNode(ListASTNode * sources) : ASTNode(), m_sources(sources) {}
186
187	inline ListASTNode * getSources() { return m_sources; }
188
189	virtual ASTNode * clone() const { return NULL; }
190
191protected:
192	smart_ptr<ListASTNode> m_sources;
193};
194
195/*!
196 * \brief Root node for the entire file.
197 */
198class CommandFileASTNode : public ASTNode
199{
200public:
201	CommandFileASTNode();
202	CommandFileASTNode(const CommandFileASTNode & other);
203
204	virtual std::string nodeName() const { return "CommandFileASTNode"; }
205
206	virtual ASTNode * clone() const { return new CommandFileASTNode(*this); }
207
208	virtual void printTree(int indent) const;
209
210	inline void setBlocks(ListASTNode * blocks) { m_blocks = blocks; }
211	inline void setOptions(ListASTNode * options) { m_options = options; }
212	inline void setConstants(ListASTNode * constants) { m_constants = constants; }
213	inline void setSources(ListASTNode * sources) { m_sources = sources; }
214	inline void setSections(ListASTNode * sections) { m_sections = sections; }
215
216	inline ListASTNode * getBlocks() { return m_blocks; }
217	inline ListASTNode * getOptions() { return m_options; }
218	inline ListASTNode * getConstants() { return m_constants; }
219	inline ListASTNode * getSources() { return m_sources; }
220	inline ListASTNode * getSections() { return m_sections; }
221
222protected:
223	smart_ptr<ListASTNode> m_blocks;
224	smart_ptr<ListASTNode> m_options;
225	smart_ptr<ListASTNode> m_constants;
226	smart_ptr<ListASTNode> m_sources;
227	smart_ptr<ListASTNode> m_sections;
228};
229
230/*!
231 * \brief Abstract base class for all expression AST nodes.
232 */
233class ExprASTNode : public ASTNode
234{
235public:
236	ExprASTNode() : ASTNode() {}
237	ExprASTNode(const ExprASTNode & other) : ASTNode(other) {}
238
239	virtual std::string nodeName() const { return "ExprASTNode"; }
240
241	//! \brief Evaluate the expression and produce a result node to replace this one.
242	//!
243	//! The default implementation simply return this node unmodified. This
244	//! method is responsible for deleting any nodes that are no longer needed.
245	//! (?) how to delete this?
246	virtual ExprASTNode * reduce(EvalContext & context) { return this; }
247
248	int_size_t resultIntSize(int_size_t a, int_size_t b);
249};
250
251/*!
252 *
253 */
254class IntConstExprASTNode : public ExprASTNode
255{
256public:
257	IntConstExprASTNode(uint32_t value, int_size_t size=kWordSize)
258	:	ExprASTNode(), m_value(value), m_size(size)
259	{
260	}
261
262	IntConstExprASTNode(const IntConstExprASTNode & other);
263
264	virtual std::string nodeName() const { return "IntConstExprASTNode"; }
265
266	virtual ASTNode * clone() const { return new IntConstExprASTNode(*this); }
267
268	virtual void printTree(int indent) const;
269
270	uint32_t getValue() const { return m_value; }
271	int_size_t getSize() const { return m_size; }
272
273protected:
274	uint32_t m_value;
275	int_size_t m_size;
276};
277
278/*!
279 *
280 */
281class VariableExprASTNode : public ExprASTNode
282{
283public:
284	VariableExprASTNode(std::string * name) : ExprASTNode(), m_variable(name) {}
285	VariableExprASTNode(const VariableExprASTNode & other);
286
287	inline std::string * getVariableName() { return m_variable; }
288
289	virtual ASTNode * clone() const { return new VariableExprASTNode(*this); }
290
291	virtual std::string nodeName() const { return "VariableExprASTNode"; }
292
293	virtual void printTree(int indent) const;
294
295	virtual ExprASTNode * reduce(EvalContext & context);
296
297protected:
298	smart_ptr<std::string> m_variable;
299};
300
301/*!
302 * \brief Expression node for a symbol reference.
303 *
304 * The symbol evaluates to its address.
305 */
306class SymbolRefExprASTNode : public ExprASTNode
307{
308public:
309	SymbolRefExprASTNode(SymbolASTNode * sym) : ExprASTNode(), m_symbol(sym) {}
310	SymbolRefExprASTNode(const SymbolRefExprASTNode & other);
311
312	virtual ASTNode * clone() const { return new SymbolRefExprASTNode(*this); }
313
314	virtual std::string nodeName() const { return "SymbolRefExprASTNode"; }
315
316	virtual void printTree(int indent) const;
317
318	virtual ExprASTNode * reduce(EvalContext & context);
319
320protected:
321	SymbolASTNode * m_symbol;
322};
323
324/*!
325 * \brief Negates an expression.
326 */
327class NegativeExprASTNode : public ExprASTNode
328{
329public:
330	NegativeExprASTNode(ExprASTNode * expr) : ExprASTNode(), m_expr(expr) {}
331	NegativeExprASTNode(const NegativeExprASTNode & other);
332
333	virtual ASTNode * clone() const { return new NegativeExprASTNode(*this); }
334
335	virtual std::string nodeName() const { return "NegativeExprASTNode"; }
336
337	virtual void printTree(int indent) const;
338
339	virtual ExprASTNode * reduce(EvalContext & context);
340
341	ExprASTNode * getExpr() { return m_expr; }
342
343protected:
344	smart_ptr<ExprASTNode> m_expr;
345};
346
347/*!
348 * \brief Performa a boolean inversion.
349 */
350class BooleanNotExprASTNode : public ExprASTNode
351{
352public:
353	BooleanNotExprASTNode(ExprASTNode * expr) : ExprASTNode(), m_expr(expr) {}
354	BooleanNotExprASTNode(const BooleanNotExprASTNode & other);
355
356	virtual ASTNode * clone() const { return new BooleanNotExprASTNode(*this); }
357
358	virtual std::string nodeName() const { return "BooleanNotExprASTNode"; }
359
360	virtual void printTree(int indent) const;
361
362	virtual ExprASTNode * reduce(EvalContext & context);
363
364	ExprASTNode * getExpr() { return m_expr; }
365
366protected:
367	smart_ptr<ExprASTNode> m_expr;
368};
369
370/*!
371 * \brief Calls a built-in function with a source as the parameter.
372 */
373class SourceFileFunctionASTNode : public ExprASTNode
374{
375public:
376	SourceFileFunctionASTNode(std::string * functionName, std::string * sourceFileName) : ExprASTNode(), m_functionName(functionName), m_sourceFile(sourceFileName) {}
377	SourceFileFunctionASTNode(const SourceFileFunctionASTNode & other);
378
379	virtual ASTNode * clone() const { return new SourceFileFunctionASTNode(*this); }
380
381	virtual std::string nodeName() const { return "SourceFileFunctionASTNode"; }
382
383	virtual void printTree(int indent) const;
384
385	virtual ExprASTNode * reduce(EvalContext & context);
386
387	std::string * getFunctionName() { return m_functionName; }
388	std::string * getSourceFile() { return m_sourceFile; }
389
390protected:
391	smart_ptr<std::string> m_functionName;
392	smart_ptr<std::string> m_sourceFile;
393};
394
395/*!
396 * \brief Returns true or false depending on whether a constant is defined.
397 */
398class DefinedOperatorASTNode : public ExprASTNode
399{
400public:
401	DefinedOperatorASTNode(std::string * constantName) : ExprASTNode(), m_constantName(constantName) {}
402	DefinedOperatorASTNode(const DefinedOperatorASTNode & other);
403
404	virtual ASTNode * clone() const { return new DefinedOperatorASTNode(*this); }
405
406	virtual std::string nodeName() const { return "DefinedOperatorASTNode"; }
407
408	virtual void printTree(int indent) const;
409
410	virtual ExprASTNode * reduce(EvalContext & context);
411
412	std::string * getConstantName() { return m_constantName; }
413
414protected:
415	smart_ptr<std::string> m_constantName;	//!< Name of the constant.
416};
417
418class SymbolASTNode;
419
420/*!
421 * \brief Returns an integer that is the size in bytes of the operand.
422 */
423class SizeofOperatorASTNode : public ExprASTNode
424{
425public:
426	SizeofOperatorASTNode(std::string * constantName) : ExprASTNode(), m_constantName(constantName), m_symbol() {}
427	SizeofOperatorASTNode(SymbolASTNode * symbol) : ExprASTNode(), m_constantName(), m_symbol(symbol) {}
428	SizeofOperatorASTNode(const SizeofOperatorASTNode & other);
429
430	virtual ASTNode * clone() const { return new SizeofOperatorASTNode(*this); }
431
432	virtual std::string nodeName() const { return "SizeofOperatorASTNode"; }
433
434	virtual void printTree(int indent) const;
435
436	virtual ExprASTNode * reduce(EvalContext & context);
437
438	std::string * getConstantName() { return m_constantName; }
439	SymbolASTNode * getSymbol() { return m_symbol; }
440
441protected:
442	smart_ptr<std::string> m_constantName;	//!< Name of the constant.
443	smart_ptr<SymbolASTNode> m_symbol;	//!< Symbol reference. If this is non-NULL then the constant name is used instead.
444};
445
446/*!
447 *
448 */
449class BinaryOpExprASTNode : public ExprASTNode
450{
451public:
452	enum operator_t
453	{
454		kAdd,
455		kSubtract,
456		kMultiply,
457		kDivide,
458		kModulus,
459		kPower,
460		kBitwiseAnd,
461		kBitwiseOr,
462		kBitwiseXor,
463		kShiftLeft,
464		kShiftRight,
465		kLessThan,
466		kGreaterThan,
467		kLessThanEqual,
468		kGreaterThanEqual,
469		kEqual,
470		kNotEqual,
471		kBooleanAnd,
472		kBooleanOr
473	};
474
475	BinaryOpExprASTNode(ExprASTNode * left, operator_t op, ExprASTNode * right)
476	:	ExprASTNode(), m_left(left), m_op(op), m_right(right)
477	{
478	}
479
480	BinaryOpExprASTNode(const BinaryOpExprASTNode & other);
481
482	virtual ASTNode * clone() const { return new BinaryOpExprASTNode(*this); }
483
484	virtual std::string nodeName() const { return "BinaryOpExprASTNode"; }
485
486	virtual void printTree(int indent) const;
487
488	virtual ExprASTNode * reduce(EvalContext & context);
489
490	ExprASTNode * getLeftExpr() { return m_left; }
491	ExprASTNode * getRightExpr() { return m_right; }
492	operator_t getOp() const { return m_op; }
493
494protected:
495	smart_ptr<ExprASTNode> m_left;
496	smart_ptr<ExprASTNode> m_right;
497	operator_t m_op;
498
499	std::string getOperatorName() const;
500};
501
502/*!
503 * \brief Negates an expression.
504 */
505class IntSizeExprASTNode : public ExprASTNode
506{
507public:
508	IntSizeExprASTNode(ExprASTNode * expr, int_size_t intSize) : ExprASTNode(), m_expr(expr), m_size(intSize) {}
509	IntSizeExprASTNode(const IntSizeExprASTNode & other);
510
511	virtual ASTNode * clone() const { return new IntSizeExprASTNode(*this); }
512
513	virtual std::string nodeName() const { return "IntSizeExprASTNode"; }
514
515	virtual void printTree(int indent) const;
516
517	virtual ExprASTNode * reduce(EvalContext & context);
518
519	ExprASTNode * getExpr() { return m_expr; }
520	int_size_t getIntSize() { return m_size; }
521
522protected:
523	smart_ptr<ExprASTNode> m_expr;
524	int_size_t m_size;
525};
526
527/*!
528 * Base class for const AST nodes.
529 */
530class ConstASTNode : public ASTNode
531{
532public:
533	ConstASTNode() : ASTNode() {}
534	ConstASTNode(const ConstASTNode & other) : ASTNode(other) {}
535
536protected:
537};
538
539/*!
540 *
541 */
542class ExprConstASTNode : public ConstASTNode
543{
544public:
545	ExprConstASTNode(ExprASTNode * expr) : ConstASTNode(), m_expr(expr) {}
546	ExprConstASTNode(const ExprConstASTNode & other);
547
548	virtual ASTNode * clone() const { return new ExprConstASTNode(*this); }
549
550	virtual std::string nodeName() const { return "ExprConstASTNode"; }
551
552	virtual void printTree(int indent) const;
553
554	ExprASTNode * getExpr() { return m_expr; }
555
556protected:
557	smart_ptr<ExprASTNode> m_expr;
558};
559
560/*!
561 *
562 */
563class StringConstASTNode : public ConstASTNode
564{
565public:
566	StringConstASTNode(std::string * value) : ConstASTNode(), m_value(value) {}
567	StringConstASTNode(const StringConstASTNode & other);
568
569	virtual ASTNode * clone() const { return new StringConstASTNode(*this); }
570
571	virtual std::string nodeName() const { return "StringConstASTNode"; }
572
573	virtual void printTree(int indent) const;
574
575	std::string * getString() { return m_value; }
576
577protected:
578	smart_ptr<std::string> m_value;
579};
580
581/*!
582 *
583 */
584class BlobConstASTNode : public ConstASTNode
585{
586public:
587	BlobConstASTNode(Blob * value) : ConstASTNode(), m_blob(value) {}
588	BlobConstASTNode(const BlobConstASTNode & other);
589
590	virtual ASTNode * clone() const { return new BlobConstASTNode(*this); }
591
592	virtual std::string nodeName() const { return "BlobConstASTNode"; }
593
594	virtual void printTree(int indent) const;
595
596	Blob * getBlob() { return m_blob; }
597
598protected:
599	smart_ptr<Blob> m_blob;
600};
601
602// Forward declaration.
603struct hab_ivt;
604
605/*!
606 * \brief Node for a constant IVT structure as used by HAB4.
607 */
608class IVTConstASTNode : public ConstASTNode
609{
610public:
611    IVTConstASTNode() : ConstASTNode(), m_fields() {}
612    IVTConstASTNode(const IVTConstASTNode & other);
613
614	virtual ASTNode * clone() const { return new IVTConstASTNode(*this); }
615
616	virtual std::string nodeName() const { return "IVTConstASTNode"; }
617
618	virtual void printTree(int indent) const;
619
620    void setFieldAssignments(ListASTNode * fields) { m_fields = fields; }
621    ListASTNode * getFieldAssignments() { return m_fields; }
622
623protected:
624    //! Fields of the IVT are set through assignment statements.
625    smart_ptr<ListASTNode> m_fields;
626};
627
628/*!
629 *
630 */
631class AssignmentASTNode : public ASTNode
632{
633public:
634	AssignmentASTNode(std::string * ident, ASTNode * value)
635	:	ASTNode(), m_ident(ident), m_value(value)
636	{
637	}
638
639	AssignmentASTNode(const AssignmentASTNode & other);
640
641	virtual ASTNode * clone() const { return new AssignmentASTNode(*this); }
642
643	virtual std::string nodeName() const { return "AssignmentASTNode"; }
644
645	virtual void printTree(int indent) const;
646
647	inline std::string * getIdent() { return m_ident; }
648	inline ASTNode * getValue() { return m_value; }
649
650protected:
651	smart_ptr<std::string> m_ident;
652	smart_ptr<ASTNode> m_value;
653};
654
655/*!
656 * Base class for PathSourceDefASTNode and ExternSourceDefASTNode.
657 */
658class SourceDefASTNode : public ASTNode
659{
660public:
661	SourceDefASTNode(std::string * name) : m_name(name) {}
662	SourceDefASTNode(const SourceDefASTNode & other);
663
664	inline std::string * getName() { return m_name; }
665
666	inline void setAttributes(ListASTNode * attributes) { m_attributes = attributes; }
667	inline ListASTNode * getAttributes() { return m_attributes; }
668
669protected:
670	smart_ptr<std::string> m_name;
671	smart_ptr<ListASTNode> m_attributes;
672};
673
674/*!
675 *
676 */
677class PathSourceDefASTNode : public SourceDefASTNode
678{
679public:
680	PathSourceDefASTNode(std::string * name, std::string * path)
681	:	SourceDefASTNode(name), m_path(path)
682	{
683	}
684
685	PathSourceDefASTNode(const PathSourceDefASTNode & other);
686
687	virtual PathSourceDefASTNode * clone() const { return new PathSourceDefASTNode(*this); }
688
689	virtual std::string nodeName() const { return "PathSourceDefASTNode"; }
690
691	virtual void printTree(int indent) const;
692
693	std::string * getPath() { return m_path; }
694
695protected:
696	smart_ptr<std::string> m_path;
697};
698
699/*!
700 *
701 */
702class ExternSourceDefASTNode : public SourceDefASTNode
703{
704public:
705	ExternSourceDefASTNode(std::string * name, ExprASTNode * expr)
706	:	SourceDefASTNode(name), m_expr(expr)
707	{
708	}
709
710	ExternSourceDefASTNode(const ExternSourceDefASTNode & other);
711
712	virtual ASTNode * clone() const { return new ExternSourceDefASTNode(*this); }
713
714	virtual std::string nodeName() const { return "ExternSourceDefASTNode"; }
715
716	virtual void printTree(int indent) const;
717
718	ExprASTNode * getSourceNumberExpr() { return m_expr; }
719
720protected:
721	smart_ptr<ExprASTNode> m_expr;
722};
723
724/*!
725 *
726 */
727class SectionContentsASTNode : public ASTNode
728{
729public:
730	SectionContentsASTNode() : m_sectionExpr() {}
731	SectionContentsASTNode(ExprASTNode * section) : m_sectionExpr(section) {}
732	SectionContentsASTNode(const SectionContentsASTNode & other);
733
734	virtual ASTNode * clone() const { return new SectionContentsASTNode(*this); }
735
736	virtual std::string nodeName() const { return "SectionContentsASTNode"; }
737
738	virtual void printTree(int indent) const;
739
740	inline void setSectionNumberExpr(ExprASTNode * section)
741	{
742		m_sectionExpr = section;
743	}
744
745	inline ExprASTNode * getSectionNumberExpr()
746	{
747		return m_sectionExpr;
748	}
749
750	inline void setOptions(ListASTNode * options)
751	{
752		m_options = options;
753	}
754
755	inline ListASTNode * getOptions()
756	{
757		return m_options;
758	}
759
760protected:
761	smart_ptr<ExprASTNode> m_sectionExpr;
762	smart_ptr<ListASTNode> m_options;
763};
764
765/*!
766 * @brief Node representing a raw binary section definition.
767 */
768class DataSectionContentsASTNode : public SectionContentsASTNode
769{
770public:
771	DataSectionContentsASTNode(ASTNode * contents)
772	:	SectionContentsASTNode(), m_contents(contents)
773	{
774	}
775
776	DataSectionContentsASTNode(const DataSectionContentsASTNode & other);
777
778	virtual ASTNode * clone() const { return new DataSectionContentsASTNode(*this); }
779
780	virtual std::string nodeName() const { return "DataSectionContentsASTNode"; }
781
782	virtual void printTree(int indent) const;
783
784	ASTNode * getContents() { return m_contents; }
785
786protected:
787	smart_ptr<ASTNode> m_contents;
788};
789
790/*!
791 *
792 */
793class BootableSectionContentsASTNode : public SectionContentsASTNode
794{
795public:
796	BootableSectionContentsASTNode(ListASTNode * statements)
797	:	SectionContentsASTNode(), m_statements(statements)
798	{
799	}
800
801	BootableSectionContentsASTNode(const BootableSectionContentsASTNode & other);
802
803	virtual ASTNode * clone() const { return new BootableSectionContentsASTNode(*this); }
804
805	virtual std::string nodeName() const { return "BootableSectionContentsASTNode"; }
806
807	virtual void printTree(int indent) const;
808
809	ListASTNode * getStatements() { return m_statements; }
810
811protected:
812	smart_ptr<ListASTNode> m_statements;
813};
814
815/*!
816 *
817 */
818class StatementASTNode : public ASTNode
819{
820public:
821	StatementASTNode() : ASTNode() {}
822	StatementASTNode(const StatementASTNode & other) : ASTNode(other) {}
823
824protected:
825};
826
827/*!
828 *
829 */
830class IfStatementASTNode : public StatementASTNode
831{
832public:
833	IfStatementASTNode() : StatementASTNode(), m_ifStatements(), m_nextIf(), m_elseStatements() {}
834	IfStatementASTNode(const IfStatementASTNode & other);
835
836	virtual ASTNode * clone() const { return new IfStatementASTNode(*this); }
837
838	void setConditionExpr(ExprASTNode * expr) { m_conditionExpr = expr; }
839	ExprASTNode * getConditionExpr() { return m_conditionExpr; }
840
841	void setIfStatements(ListASTNode * statements) { m_ifStatements = statements; }
842	ListASTNode * getIfStatements() { return m_ifStatements; }
843
844	void setNextIf(IfStatementASTNode * nextIf) { m_nextIf = nextIf; }
845	IfStatementASTNode * getNextIf() { return m_nextIf; }
846
847	void setElseStatements(ListASTNode * statements) { m_elseStatements = statements; }
848	ListASTNode * getElseStatements() { return m_elseStatements; }
849
850protected:
851	smart_ptr<ExprASTNode> m_conditionExpr;	//!< Boolean expression.
852	smart_ptr<ListASTNode> m_ifStatements;	//!< List of "if" section statements.
853	smart_ptr<IfStatementASTNode> m_nextIf;	//!< Link to next "else if". If this is non-NULL then #m_elseStatements must be NULL and vice-versa.
854	smart_ptr<ListASTNode> m_elseStatements;	//!< Statements for the "else" part of the statements.
855};
856
857/*!
858 * \brief Statement to insert a ROM_MODE_CMD command.
859 */
860class ModeStatementASTNode : public StatementASTNode
861{
862public:
863	ModeStatementASTNode() : StatementASTNode(), m_modeExpr() {}
864	ModeStatementASTNode(ExprASTNode * modeExpr) : StatementASTNode(), m_modeExpr(modeExpr) {}
865	ModeStatementASTNode(const ModeStatementASTNode & other);
866
867	virtual ASTNode * clone() const { return new ModeStatementASTNode(*this); }
868
869	virtual std::string nodeName() const { return "ModeStatementASTNode"; }
870
871	virtual void printTree(int indent) const;
872
873	inline void setModeExpr(ExprASTNode * modeExpr) { m_modeExpr = modeExpr; }
874	inline ExprASTNode * getModeExpr() { return m_modeExpr; }
875
876protected:
877	smart_ptr<ExprASTNode> m_modeExpr;	//!< Expression that evaluates to the new boot mode.
878};
879
880/*!
881 * \brief Statement to print a message to the elftosb user.
882 */
883class MessageStatementASTNode : public StatementASTNode
884{
885public:
886	enum _message_type
887	{
888		kInfo,	//!< Prints an informational messag to the user.
889		kWarning,	//!< Prints a warning to the user.
890		kError	//!< Throws an error exception.
891	};
892
893	typedef enum _message_type message_type_t;
894
895public:
896	MessageStatementASTNode(message_type_t messageType, std::string * message) : StatementASTNode(), m_type(messageType), m_message(message) {}
897	MessageStatementASTNode(const MessageStatementASTNode & other);
898
899	virtual ASTNode * clone() const { return new MessageStatementASTNode(*this); }
900
901	virtual std::string nodeName() const { return "MessageStatementASTNode"; }
902
903	virtual void printTree(int indent) const;
904
905	inline message_type_t getType() { return m_type; }
906	inline std::string * getMessage() { return m_message; }
907
908	const char * getTypeName() const;
909
910protected:
911	message_type_t m_type;
912	smart_ptr<std::string> m_message;	//!< Message to report.
913};
914
915/*!
916 * \brief AST node for a load statement.
917 */
918class LoadStatementASTNode : public StatementASTNode
919{
920public:
921	LoadStatementASTNode()
922	:	StatementASTNode(), m_data(), m_target(), m_isDCDLoad(false)
923	{
924	}
925
926	LoadStatementASTNode(ASTNode * data, ASTNode * target)
927	:	StatementASTNode(), m_data(data), m_target(), m_isDCDLoad(false)
928	{
929	}
930
931	LoadStatementASTNode(const LoadStatementASTNode & other);
932
933	virtual ASTNode * clone() const { return new LoadStatementASTNode(*this); }
934
935	virtual std::string nodeName() const { return "LoadStatementASTNode"; }
936
937	virtual void printTree(int indent) const;
938
939	inline void setData(ASTNode * data) { m_data = data; }
940	inline ASTNode * getData() { return m_data; }
941
942	inline void setTarget(ASTNode * target) { m_target = target; }
943	inline ASTNode * getTarget() { return m_target; }
944
945	inline void setDCDLoad(bool isDCD) { m_isDCDLoad = isDCD; }
946	inline bool isDCDLoad() const { return m_isDCDLoad; }
947
948protected:
949	smart_ptr<ASTNode> m_data;
950	smart_ptr<ASTNode> m_target;
951	bool m_isDCDLoad;
952};
953
954/*!
955 * \brief AST node for a call statement.
956 */
957class CallStatementASTNode : public StatementASTNode
958{
959public:
960	//! Possible sub-types of call statements.
961	typedef enum {
962		kCallType,
963		kJumpType
964	} call_type_t;
965
966public:
967	CallStatementASTNode(call_type_t callType=kCallType)
968	:	StatementASTNode(), m_type(callType), m_target(), m_arg(), m_isHAB(false)
969	{
970	}
971
972	CallStatementASTNode(call_type_t callType, ASTNode * target, ASTNode * arg)
973	:	StatementASTNode(), m_type(callType), m_target(target), m_arg(arg), m_isHAB(false)
974	{
975	}
976
977	CallStatementASTNode(const CallStatementASTNode & other);
978
979	virtual ASTNode * clone() const { return new CallStatementASTNode(*this); }
980
981	virtual std::string nodeName() const { return "CallStatementASTNode"; }
982
983	virtual void printTree(int indent) const;
984
985	inline void setCallType(call_type_t callType) { m_type = callType; }
986	inline call_type_t getCallType() { return m_type; }
987
988	inline void setTarget(ASTNode * target) { m_target = target; }
989	inline ASTNode * getTarget() { return m_target; }
990
991	inline void setArgument(ASTNode * arg) { m_arg = arg; }
992	inline ASTNode * getArgument() { return m_arg; }
993
994	inline void setIsHAB(bool isHAB) { m_isHAB = isHAB; }
995	inline bool isHAB() const { return m_isHAB; }
996
997protected:
998	call_type_t m_type;
999	smart_ptr<ASTNode> m_target;	//!< This becomes the IVT address in HAB mode.
1000	smart_ptr<ASTNode> m_arg;
1001	bool m_isHAB;
1002};
1003
1004/*!
1005 *
1006 */
1007class SourceASTNode : public ASTNode
1008{
1009public:
1010	SourceASTNode(std::string * name) : ASTNode(), m_name(name) {}
1011	SourceASTNode(const SourceASTNode & other);
1012
1013	virtual ASTNode * clone() const { return new SourceASTNode(*this); }
1014
1015	virtual std::string nodeName() const { return "SourceASTNode"; }
1016
1017	virtual void printTree(int indent) const;
1018
1019	inline std::string * getSourceName() { return m_name; }
1020
1021protected:
1022	smart_ptr<std::string> m_name;
1023};
1024
1025/*!
1026 * \brief List of section matches for a particular source name.
1027 */
1028class SectionMatchListASTNode : public ASTNode
1029{
1030public:
1031	SectionMatchListASTNode(ListASTNode * sections)
1032	:	ASTNode(), m_sections(sections), m_source()
1033	{
1034	}
1035
1036	SectionMatchListASTNode(ListASTNode * sections, std::string * source)
1037	:	ASTNode(), m_sections(sections), m_source(source)
1038	{
1039	}
1040
1041	SectionMatchListASTNode(const SectionMatchListASTNode & other);
1042
1043	virtual ASTNode * clone() const { return new SectionMatchListASTNode(*this); }
1044
1045	virtual std::string nodeName() const { return "SectionMatchListASTNode"; }
1046
1047	virtual void printTree(int indent) const;
1048
1049	inline ListASTNode * getSections() { return m_sections; }
1050	inline std::string * getSourceName() { return m_source; }
1051
1052protected:
1053	smart_ptr<ListASTNode> m_sections;
1054	smart_ptr<std::string> m_source;
1055};
1056
1057/*!
1058 * \brief AST node for a section glob.
1059 *
1060 * Can be assigned an include or exclude action for when this node is part of a
1061 * SectionMatchListASTNode.
1062 */
1063class SectionASTNode : public ASTNode
1064{
1065public:
1066	//! Possible actions for a section match list.
1067	typedef enum
1068	{
1069		kInclude,	//!< Include sections matched by this node.
1070		kExclude	//!< Exclude sections matched by this node.
1071	} match_action_t;
1072
1073public:
1074	SectionASTNode(std::string * name)
1075	:	ASTNode(), m_action(kInclude), m_name(name), m_source()
1076	{
1077	}
1078
1079	SectionASTNode(std::string * name, match_action_t action)
1080	:	ASTNode(), m_action(action), m_name(name), m_source()
1081	{
1082	}
1083
1084	SectionASTNode(std::string * name, std::string * source)
1085	:	ASTNode(), m_action(kInclude), m_name(name), m_source(source)
1086	{
1087	}
1088
1089	SectionASTNode(const SectionASTNode & other);
1090
1091	virtual ASTNode * clone() const { return new SectionASTNode(*this); }
1092
1093	virtual std::string nodeName() const { return "SectionASTNode"; }
1094
1095	virtual void printTree(int indent) const;
1096
1097	inline match_action_t getAction() { return m_action; }
1098	inline std::string * getSectionName() { return m_name; }
1099	inline std::string * getSourceName() { return m_source; }
1100
1101protected:
1102	match_action_t m_action;
1103	smart_ptr<std::string> m_name;
1104	smart_ptr<std::string> m_source;
1105};
1106
1107/*!
1108 *
1109 */
1110class SymbolASTNode : public ASTNode
1111{
1112public:
1113	SymbolASTNode()
1114	:	ASTNode(), m_symbol(), m_source()
1115	{
1116	}
1117
1118	SymbolASTNode(std::string * symbol, std::string * source=0)
1119	:	ASTNode(), m_symbol(symbol), m_source(source)
1120	{
1121	}
1122
1123	SymbolASTNode(const SymbolASTNode & other);
1124
1125	virtual ASTNode * clone() const { return new SymbolASTNode(*this); }
1126
1127	virtual std::string nodeName() const { return "SymbolASTNode"; }
1128
1129	virtual void printTree(int indent) const;
1130
1131	inline void setSymbolName(std::string * symbol) { m_symbol = symbol; }
1132	inline std::string * getSymbolName() { return m_symbol; }
1133
1134	inline void setSource(std::string * source) { m_source = source; }
1135	inline std::string * getSource() { return m_source; }
1136
1137protected:
1138	smart_ptr<std::string> m_symbol;	//!< Required.
1139	smart_ptr<std::string> m_source;	//!< Optional, may be NULL;
1140};
1141
1142/*!
1143 * If the end of the range is NULL, then only a single address was specified.
1144 */
1145class AddressRangeASTNode : public ASTNode
1146{
1147public:
1148	AddressRangeASTNode()
1149	:	ASTNode(), m_begin(), m_end()
1150	{
1151	}
1152
1153	AddressRangeASTNode(ASTNode * begin, ASTNode * end)
1154	:	ASTNode(), m_begin(begin), m_end(end)
1155	{
1156	}
1157
1158	AddressRangeASTNode(const AddressRangeASTNode & other);
1159
1160	virtual ASTNode * clone() const { return new AddressRangeASTNode(*this); }
1161
1162	virtual std::string nodeName() const { return "AddressRangeASTNode"; }
1163
1164	virtual void printTree(int indent) const;
1165
1166	inline void setBegin(ASTNode * begin) { m_begin = begin; }
1167	inline ASTNode * getBegin() { return m_begin; }
1168
1169	inline void setEnd(ASTNode * end) { m_end = end; }
1170	inline ASTNode * getEnd() { return m_end; }
1171
1172protected:
1173	smart_ptr<ASTNode> m_begin;
1174	smart_ptr<ASTNode> m_end;
1175};
1176
1177/*!
1178 *
1179 */
1180class NaturalLocationASTNode : public ASTNode
1181{
1182public:
1183	NaturalLocationASTNode()
1184	:	ASTNode()
1185	{
1186	}
1187
1188	NaturalLocationASTNode(const NaturalLocationASTNode & other)
1189	:	ASTNode(other)
1190	{
1191	}
1192
1193	virtual ASTNode * clone() const { return new NaturalLocationASTNode(*this); }
1194
1195	virtual std::string nodeName() const { return "NaturalLocationASTNode"; }
1196};
1197
1198/*!
1199 *
1200 */
1201class FromStatementASTNode : public StatementASTNode
1202{
1203public:
1204	FromStatementASTNode() : StatementASTNode() {}
1205	FromStatementASTNode(std::string * source, ListASTNode * statements);
1206	FromStatementASTNode(const FromStatementASTNode & other);
1207
1208	virtual ASTNode * clone() const { return new FromStatementASTNode(*this); }
1209
1210	virtual std::string nodeName() const { return "FromStatementASTNode"; }
1211
1212	virtual void printTree(int indent) const;
1213
1214	inline void setSourceName(std::string * source) { m_source = source; }
1215	inline std::string * getSourceName() { return m_source; }
1216
1217	inline void setStatements(ListASTNode * statements) { m_statements = statements; }
1218	inline ListASTNode * getStatements() { return m_statements; }
1219
1220protected:
1221	smart_ptr<std::string> m_source;
1222	smart_ptr<ListASTNode> m_statements;
1223};
1224
1225}; // namespace elftosb
1226
1227#endif // _ElftosbAST_h_
1228