Add and use a new method
[oota-llvm.git] / support / tools / TableGen / Record.h
index 0c8ed33205d47dfafc5fc29874c85a0647571566..5c50a07651dd29faaeae643da184b468c6592959 100644 (file)
@@ -1,5 +1,7 @@
 //===- Record.h - Classes to represent Table Records ------------*- C++ -*-===//
 //
+// This file defines the main TableGen data structures, including the TableGen
+// types, values, and high-level data structures.
 //
 //===----------------------------------------------------------------------===//
 
 #include <vector>
 #include <map>
 #include <iostream>
+#include <cassert>
+
+// RecTy subclasses...
+class BitRecTy;
+class BitsRecTy;
+class IntRecTy;
+class StringRecTy;
+class ListRecTy;
+class CodeRecTy;
+class DagRecTy;
+class RecordRecTy;
+
+// Init subclasses...
 class Init;
 class UnsetInit;
 class BitInit;
 class BitsInit;
 class IntInit;
 class StringInit;
+class CodeInit;
 class ListInit;
-class VarInit;
-class VarBitInit;
 class DefInit;
+class DagInit;
+class TypedInit;
+class VarInit;
 class FieldInit;
+class VarBitInit;
+
+// Other classes...
 class Record;
 
 //===----------------------------------------------------------------------===//
@@ -30,19 +50,43 @@ class Record;
 struct RecTy {
   virtual ~RecTy() {}
 
+  virtual void print(std::ostream &OS) const = 0;
+  void dump() const;
+
+  /// typeIsConvertibleTo - Return true if all values of 'this' type can be
+  /// converted to the specified type.
+  virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
+
+public:   // These methods should only be called from subclasses of Init
   virtual Init *convertValue( UnsetInit *UI) { return 0; }
   virtual Init *convertValue(   BitInit *BI) { return 0; }
   virtual Init *convertValue(  BitsInit *BI) { return 0; }
   virtual Init *convertValue(   IntInit *II) { return 0; }
   virtual Init *convertValue(StringInit *SI) { return 0; }
   virtual Init *convertValue(  ListInit *LI) { return 0; }
-  virtual Init *convertValue(   VarInit *VI) { return 0; }
+  virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
-  virtual Init *convertValue( FieldInit *FI) { return 0; }
-
-  virtual void print(std::ostream &OS) const = 0;
-  void dump() const;
+  virtual Init *convertValue(   DagInit *DI) { return 0; }
+  virtual Init *convertValue( TypedInit *TI) { return 0; }
+  virtual Init *convertValue(   VarInit *VI) {
+    return convertValue((TypedInit*)VI);
+  }
+  virtual Init *convertValue( FieldInit *FI) {
+    return convertValue((TypedInit*)FI);
+  }
+
+public:   // These methods should only be called by subclasses of RecTy.
+  // baseClassOf - These virtual methods should be overloaded to return true iff
+  // all values of type 'RHS' can be converted to the 'this' type.
+  virtual bool baseClassOf(const BitRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const BitsRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const IntRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
+  virtual bool baseClassOf(const ListRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const CodeRecTy   *RHS) const { return false; }
+  virtual bool baseClassOf(const DagRecTy    *RHS) const { return false; }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
 };
 
 inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
@@ -58,10 +102,17 @@ struct BitRecTy : public RecTy {
   Init *convertValue(BitInit *BI) { return (Init*)BI; }
   Init *convertValue(BitsInit *BI);
   Init *convertValue(IntInit *II);
-  Init *convertValue(VarInit *VI);
+  Init *convertValue(TypedInit *VI);
   Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
 
   void print(std::ostream &OS) const { OS << "bit"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy *RHS) const;
+  virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
 };
 
 
@@ -78,10 +129,18 @@ public:
   Init *convertValue(BitInit *UI);
   Init *convertValue(BitsInit *BI);
   Init *convertValue(IntInit *II);
-  Init *convertValue(VarInit *VI);
-  Init *convertValue(FieldInit *VI);
+  Init *convertValue(TypedInit *VI);
 
   void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; }
+  virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy *RHS) const {
+    return RHS->Size == Size;
+  }
 };
 
 
@@ -90,10 +149,19 @@ public:
 struct IntRecTy : public RecTy {
   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
   Init *convertValue(IntInit *II) { return (Init*)II; }
+  Init *convertValue(BitInit *BI);
   Init *convertValue(BitsInit *BI);
-  Init *convertValue(VarInit *VI);
+  Init *convertValue(TypedInit *TI);
 
   void print(std::ostream &OS) const { OS << "int"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
+  virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; }
 };
 
 /// StringRecTy - 'string' - Represent an string value
@@ -101,23 +169,72 @@ struct IntRecTy : public RecTy {
 struct StringRecTy : public RecTy {
   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
   Init *convertValue(StringInit *SI) { return (Init*)SI; }
-  Init *convertValue(VarInit *VI);
+  Init *convertValue(TypedInit *TI);
   void print(std::ostream &OS) const { OS << "string"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
 };
 
-/// ListRecTy - 'list<class>' - Represent a list defs, all of which must be
-/// derived from the specified class.
+/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
+/// the specified type.
 ///
 class ListRecTy : public RecTy {
-  Record *Class;
+  RecTy *Ty;
 public:
-  ListRecTy(Record *C) : Class(C) {}
+  ListRecTy(RecTy *T) : Ty(T) {}
+
+  RecTy *getElementType() const { return Ty; }
+
   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
   Init *convertValue(ListInit *LI);
+  Init *convertValue(TypedInit *TI);
   
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+
+  virtual bool baseClassOf(const ListRecTy *RHS) const {
+    return RHS->getElementType()->typeIsConvertibleTo(Ty); 
+  }
+};
+
+/// CodeRecTy - 'code' - Represent an code fragment, function or method.
+///
+struct CodeRecTy : public RecTy {
+  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
+  Init *convertValue( CodeInit *CI) { return (Init*)CI; }
+  Init *convertValue(TypedInit *TI);
+
+  void print(std::ostream &OS) const { OS << "code"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; }
+};
+
+/// DagRecTy - 'dag' - Represent a dag fragment
+///
+struct DagRecTy : public RecTy {
+  Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
+  Init *convertValue( DagInit *CI) { return (Init*)CI; }
+  Init *convertValue(TypedInit *TI);
+
+  void print(std::ostream &OS) const { OS << "dag"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const DagRecTy *RHS) const { return true; }
 };
 
+
 /// RecordRecTy - '<classname>' - Represent an instance of a class, such as:
 /// (R32 X = EAX).
 ///
@@ -129,9 +246,15 @@ public:
   Record *getRecord() const { return Rec; }
 
   Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
-  Init *convertValue(   DefInit *DI);
+  Init *convertValue(  DefInit *DI);
+  Init *convertValue(TypedInit *VI); 
 
   void print(std::ostream &OS) const;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const {
+    return RHS->baseClassOf(this);
+  }
+  virtual bool baseClassOf(const RecordRecTy *RHS) const;
 };
 
 
@@ -175,6 +298,14 @@ struct Init {
   ///
   virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
 
+  /// getFieldInit - This method complements getFieldType to return the
+  /// initializer for the specified field.  If getFieldType returns non-null
+  /// this method should return non-null, otherwise it returns null.
+  ///
+  virtual Init *getFieldInit(Record &R, const std::string &FieldName) const {
+    return 0;
+  }
+
   /// resolveReferences - This method is used by classes that refer to other
   /// variables which may not be defined at the time they expression is formed.
   /// If a value is set for the variable later, this method will be called on
@@ -232,6 +363,7 @@ public:
   }
   void setBit(unsigned Bit, Init *V) {
     assert(Bit < Bits.size() && "Bit index out of range!");
+    assert(Bits[Bit] == 0 && "Bit already set!");
     Bits[Bit] = V;
   }
 
@@ -282,6 +414,8 @@ class StringInit : public Init {
 public:
   StringInit(const std::string &V) : Value(V) {}
 
+  const std::string &getValue() const { return Value; }
+
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
   }
@@ -289,19 +423,35 @@ public:
   virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; }
 };
 
+/// CodeInit - "[{...}]" - Represent a code fragment.
+///
+class CodeInit : public Init {
+  std::string Value;
+public:
+  CodeInit(const std::string &V) : Value(V) {}
+
+  const std::string getValue() const { return Value; }
+
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  virtual void print(std::ostream &OS) const { OS << "[{" << Value << "}]"; }
+};
+
 /// ListInit - [AL, AH, CL] - Represent a list of defs
 ///
 class ListInit : public Init {
-  std::vector<Record*> Records;
+  std::vector<Init*> Values;
 public:
-  ListInit(std::vector<Record*> &Rs) {
-    Records.swap(Rs);
+  ListInit(std::vector<Init*> &Vs) {
+    Values.swap(Vs);
   }
 
-  unsigned getSize() const { return Records.size(); }
-  Record  *getElement(unsigned i) const {
-    assert(i < Records.size() && "List element index out of range!");
-    return Records[i];
+  unsigned getSize() const { return Values.size(); }
+  Init *getElement(unsigned i) const {
+    assert(i < Values.size() && "List element index out of range!");
+    return Values[i];
   }
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
@@ -347,6 +497,14 @@ public:
   virtual Init *resolveBitReference(Record &R, unsigned Bit);
 
   virtual RecTy *getFieldType(const std::string &FieldName) const;
+  virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
+
+  /// resolveReferences - This method is used by classes that refer to other
+  /// variables which may not be defined at the time they expression is formed.
+  /// If a value is set for the variable later, this method will be called on
+  /// users of the value to allow the value to propagate out.
+  ///
+  virtual Init *resolveReferences(Record &R);
   
   virtual void print(std::ostream &OS) const { OS << VarName; }
 };
@@ -392,6 +550,9 @@ public:
   Record *getDef() const { return Def; }
 
   //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+
+  virtual RecTy *getFieldType(const std::string &FieldName) const;
+  virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
   
   virtual void print(std::ostream &OS) const;
 };
@@ -416,11 +577,34 @@ public:
 
   virtual Init *resolveBitReference(Record &R, unsigned Bit);
 
+  virtual Init *resolveReferences(Record &R);
+
   virtual void print(std::ostream &OS) const {
     Rec->print(OS); OS << "." << FieldName;
   }
 };
 
+/// DagInit - (def a, b) - Represent a DAG tree value.  DAG inits are required
+/// to have Records for their first value, after that, any legal Init is
+/// possible.
+///
+class DagInit : public Init {
+  Record *NodeTypeDef;
+  std::vector<Init*> Args;
+public:
+  DagInit(Record *D, std::vector<Init*> &a) : NodeTypeDef(D) {
+    Args.swap(a);  // DESTRUCTIVELY take the arguments
+  }
+  
+  virtual Init *convertInitializerTo(RecTy *Ty) {
+    return Ty->convertValue(this);
+  }
+
+  Record *getNodeType() const { return NodeTypeDef; }
+  const std::vector<Init*> &getArgs() const { return Args; }
+
+  virtual void print(std::ostream &OS) const;
+};
 
 //===----------------------------------------------------------------------===//
 //  High-Level Classes
@@ -502,6 +686,16 @@ public:
     Values.push_back(RV);
   }
 
+  void removeValue(const std::string &Name) {
+    assert(getValue(Name) && "Cannot remove an entry that does not exist!");
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getName() == Name) {
+        Values.erase(Values.begin()+i);
+        return;
+      }
+    assert(0 && "Name does not exist in record!");
+  }
+
   bool isSubClassOf(Record *R) const {
     for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
       if (SuperClasses[i] == R)
@@ -509,6 +703,13 @@ public:
     return false;
   }
 
+  bool isSubClassOf(const std::string &Name) const {
+    for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+      if (SuperClasses[i]->getName() == Name)
+        return true;
+    return false;
+  }
+
   void addSuperClass(Record *R) {
     assert(!isSubClassOf(R) && "Already subclassing record!");
     SuperClasses.push_back(R);
@@ -520,6 +721,57 @@ public:
   void resolveReferences();
 
   void dump() const;
+
+  //===--------------------------------------------------------------------===//
+  // High-level methods useful to tablegen back-ends
+  //
+
+  /// getValueInit - Return the initializer for a value with the specified name,
+  /// or throw an exception if the field does not exist.
+  ///
+  Init *getValueInit(const std::string &FieldName) const;
+
+  /// getValueAsString - This method looks up the specified field and returns
+  /// its value as a string, throwing an exception if the field does not exist
+  /// or if the value is not a string.
+  ///
+  std::string getValueAsString(const std::string &FieldName) const;
+
+  /// getValueAsBitsInit - This method looks up the specified field and returns
+  /// its value as a BitsInit, throwing an exception if the field does not exist
+  /// or if the value is not the right type.
+  ///
+  BitsInit *getValueAsBitsInit(const std::string &FieldName) const;
+
+  /// getValueAsListInit - This method looks up the specified field and returns
+  /// its value as a ListInit, throwing an exception if the field does not exist
+  /// or if the value is not the right type.
+  ///
+  ListInit *getValueAsListInit(const std::string &FieldName) const;
+
+  /// getValueAsDef - This method looks up the specified field and returns its
+  /// value as a Record, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  Record *getValueAsDef(const std::string &FieldName) const;
+
+  /// getValueAsBit - This method looks up the specified field and returns its
+  /// value as a bit, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  bool getValueAsBit(const std::string &FieldName) const;
+
+  /// getValueAsInt - This method looks up the specified field and returns its
+  /// value as an int, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  int getValueAsInt(const std::string &FieldName) const;
+
+  /// getValueAsDag - This method looks up the specified field and returns its
+  /// value as an Dag, throwing an exception if the field does not exist or if
+  /// the value is not the right type.
+  ///
+  DagInit *getValueAsDag(const std::string &FieldName) const;
 };
 
 std::ostream &operator<<(std::ostream &OS, const Record &R);
@@ -556,6 +808,16 @@ public:
     Defs.insert(std::make_pair(R->getName(), R));
   }
 
+  //===--------------------------------------------------------------------===//
+  // High-level helper methods, useful for tablegen backends...
+
+  /// getAllDerivedDefinitions - This method returns all concrete definitions
+  /// that derive from the specified class name.  If a class with the specified
+  /// name does not exist, an exception is thrown.
+  std::vector<Record*>
+  getAllDerivedDefinitions(const std::string &ClassName) const;
+
+
   void dump() const;
 };