//===-- llvm/Support/Annotation.h - Annotation classes ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations for two classes: Annotation & Annotable.
// Using these two simple classes, anything that derives from Annotable can have
// Annotation subclasses attached to them, ready for easy retrieval.
//
// Annotations are designed to be easily attachable to various classes.
//
// The AnnotationManager class is essential for using these classes.  It is
// responsible for turning Annotation name strings into tokens [unique id #'s]
// that may be used to search for and create annotations.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_ANNOTATION_H
#define LLVM_SUPPORT_ANNOTATION_H

#include <string>
#include <cassert>

namespace llvm {

class AnnotationID;
class Annotation;
class Annotable;
struct AnnotationManager;

//===----------------------------------------------------------------------===//
//
// AnnotationID - This class is a thin wrapper around an unsigned integer that
// is used to hopefully prevent errors using AnnotationID's.  They may be copied
// freely around and passed byvalue with little or no overhead.
//
class AnnotationID {
  friend struct AnnotationManager;
  unsigned ID;

  AnnotationID();                             // Default ctor is disabled
  inline AnnotationID(unsigned i) : ID(i) {}  // Only creatable from AnnMgr
public:
  inline AnnotationID(const AnnotationID &A) : ID(A.ID) {}

  inline bool operator==(const AnnotationID &A) const {
    return A.ID == ID;
  }
  inline bool operator<(const AnnotationID &A) const {
    return ID < A.ID;
  }
};


//===----------------------------------------------------------------------===//
//
// Annotation Class - This class serves as a base class for any specific
// annotations that you might need.  Simply subclass this to add extra
// information to the annotations.
//
class Annotation {
  friend class Annotable;  // Annotable manipulates Next list
  AnnotationID ID;         // ID number, as obtained from AnnotationManager
  Annotation *Next;        // The next annotation in the linked list
public:
  inline Annotation(AnnotationID id) : ID(id), Next(0) {}
  virtual ~Annotation();  // Designed to be subclassed

  // getID - Return the unique ID# of this annotation
  inline AnnotationID getID() const { return ID; }

  // getNext - Return the next annotation in the list...
  inline Annotation *getNext() const { return Next; }
};


//===----------------------------------------------------------------------===//
//
// Annotable - This class is used as a base class for all objects that would
// like to have annotation capability.
//
// Annotable objects keep their annotation list sorted as annotations are
// inserted and deleted.  This is used to ensure that annotations with identical
// ID#'s are stored sequentially.
//
class Annotable {
  mutable Annotation *AnnotationList;

  Annotable(const Annotable &);        // Do not implement
  void operator=(const Annotable &);   // Do not implement
public:
  Annotable() : AnnotationList(0) {}
  ~Annotable();

  // getAnnotation - Search the list for annotations of the specified ID.  The
  // pointer returned is either null (if no annotations of the specified ID
  // exist), or it points to the first element of a potentially list of elements
  // with identical ID #'s.
  //
  Annotation *getAnnotation(AnnotationID ID) const {
    for (Annotation *A = AnnotationList; A; A = A->getNext())
      if (A->getID() == ID) return A;
    return 0;
  }

  // getOrCreateAnnotation - Search through the annotation list, if there is
  // no annotation with the specified ID, then use the AnnotationManager to
  // create one.
  //
  inline Annotation *getOrCreateAnnotation(AnnotationID ID) const;

  // addAnnotation - Insert the annotation into the list in a sorted location.
  //
  void addAnnotation(Annotation *A) const {
    assert(A->Next == 0 && "Annotation already in list?!?");

    Annotation **AL = &AnnotationList;
    while (*AL && (*AL)->ID < A->getID())  // Find where to insert annotation
      AL = &((*AL)->Next);
    A->Next = *AL;                         // Link the annotation in
    *AL = A;
  }

  // unlinkAnnotation - Remove the first annotation of the specified ID... and
  // then return the unlinked annotation.  The annotation object is not deleted.
  //
  inline Annotation *unlinkAnnotation(AnnotationID ID) const {
    for (Annotation **A = &AnnotationList; *A; A = &((*A)->Next))
      if ((*A)->getID() == ID) {
        Annotation *Ret = *A;
        *A = Ret->Next;
        Ret->Next = 0;
        return Ret;
      }
    return 0;
  }

  // deleteAnnotation - Delete the first annotation of the specified ID in the
  // list.  Unlink unlinkAnnotation, this actually deletes the annotation object
  //
  bool deleteAnnotation(AnnotationID ID) const {
    Annotation *A = unlinkAnnotation(ID);
    delete A;
    return A != 0;
  }
};


//===----------------------------------------------------------------------===//
//
// AnnotationManager - This class is primarily responsible for maintaining a
// one-to-one mapping between string Annotation names and Annotation ID numbers.
//
// Compared to the rest of the Annotation system, these mapping methods are
// relatively slow, so they should be avoided by locally caching Annotation
// ID #'s.  These methods are safe to call at any time, even by static ctors, so
// they should be used by static ctors most of the time.
//
// This class also provides support for annotations that are created on demand
// by the Annotable::getOrCreateAnnotation method.  To get this to work, simply
// register an annotation handler
//
struct AnnotationManager {
  typedef Annotation *(*Factory)(AnnotationID, const Annotable *, void*);

  //===--------------------------------------------------------------------===//
  // Basic ID <-> Name map functionality

  static AnnotationID         getID(const std::string &Name);  // Name -> ID
  static const std::string &getName(AnnotationID ID);          // ID -> Name

  // getID - Name -> ID + registration of a factory function for demand driven
  // annotation support.
  static AnnotationID getID(const std::string &Name, Factory Fact,
                            void *Data = 0);

  //===--------------------------------------------------------------------===//
  // Annotation creation on demand support...

  // registerAnnotationFactory - This method is used to register a callback
  // function used to create an annotation on demand if it is needed by the
  // Annotable::getOrCreateAnnotation method.
  //
  static void registerAnnotationFactory(AnnotationID ID, Factory Func,
                                        void *ExtraData = 0);

  // createAnnotation - Create an annotation of the specified ID for the
  // specified object, using a register annotation creation function.
  //
  static Annotation *createAnnotation(AnnotationID ID, const Annotable *Obj);
};



// getOrCreateAnnotation - Search through the annotation list, if there is
// no annotation with the specified ID, then use the AnnotationManager to
// create one.
//
inline Annotation *Annotable::getOrCreateAnnotation(AnnotationID ID) const {
  Annotation *A = getAnnotation(ID);   // Fast path, check for preexisting ann
  if (A) return A;

  // No annotation found, ask the annotation manager to create an annotation...
  A = AnnotationManager::createAnnotation(ID, this);
  assert(A && "AnnotationManager could not create annotation!");
  addAnnotation(A);
  return A;
}

} // End namespace llvm

#endif
