+/// DagInit - (v a, b) - Represent a DAG tree value. DAG inits are required
+/// to have at least one value then a (possibly empty) list of arguments. Each
+/// argument can have a name associated with it.
+///
+class DagInit : public Init {
+ Init *Val;
+ std::vector<Init*> Args;
+ std::vector<std::string> ArgNames;
+public:
+ DagInit(Init *V, const std::vector<std::pair<Init*, std::string> > &args)
+ : Val(V) {
+ Args.reserve(args.size());
+ ArgNames.reserve(args.size());
+ for (unsigned i = 0, e = args.size(); i != e; ++i) {
+ Args.push_back(args[i].first);
+ ArgNames.push_back(args[i].second);
+ }
+ }
+ DagInit(Init *V, const std::vector<Init*> &args,
+ const std::vector<std::string> &argNames)
+ : Val(V), Args(args), ArgNames(argNames) {
+ }
+
+ virtual Init *convertInitializerTo(RecTy *Ty) {
+ return Ty->convertValue(this);
+ }
+
+ Init *getOperator() const { return Val; }
+
+ unsigned getNumArgs() const { return Args.size(); }
+ Init *getArg(unsigned Num) const {
+ assert(Num < Args.size() && "Arg number out of range!");
+ return Args[Num];
+ }
+ const std::string &getArgName(unsigned Num) const {
+ assert(Num < ArgNames.size() && "Arg number out of range!");
+ return ArgNames[Num];
+ }
+
+ void setArg(unsigned Num, Init *I) {
+ assert(Num < Args.size() && "Arg number out of range!");
+ Args[Num] = I;
+ }
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+ virtual std::string getAsString() const;
+
+ typedef std::vector<Init*>::iterator arg_iterator;
+ typedef std::vector<Init*>::const_iterator const_arg_iterator;
+ typedef std::vector<std::string>::iterator name_iterator;
+ typedef std::vector<std::string>::const_iterator const_name_iterator;
+
+ inline arg_iterator arg_begin() { return Args.begin(); }
+ inline const_arg_iterator arg_begin() const { return Args.begin(); }
+ inline arg_iterator arg_end () { return Args.end(); }
+ inline const_arg_iterator arg_end () const { return Args.end(); }
+
+ inline size_t arg_size () const { return Args.size(); }
+ inline bool arg_empty() const { return Args.empty(); }
+
+ inline name_iterator name_begin() { return ArgNames.begin(); }
+ inline const_name_iterator name_begin() const { return ArgNames.begin(); }
+ inline name_iterator name_end () { return ArgNames.end(); }
+ inline const_name_iterator name_end () const { return ArgNames.end(); }
+
+ inline size_t name_size () const { return ArgNames.size(); }
+ inline bool name_empty() const { return ArgNames.empty(); }
+
+};