//===--- Attr.h - Classes for representing expressions ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the Attr interface and subclasses.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_ATTR_H
#define LLVM_CLANG_AST_ATTR_H

#include "llvm/Support/Casting.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstring>
#include <algorithm>
using llvm::dyn_cast;

namespace clang {
  class ASTContext;
}


// Defined in ASTContext.h
void *operator new(size_t Bytes, clang::ASTContext &C,
                   size_t Alignment = 16) throw ();

// It is good practice to pair new/delete operators.  Also, MSVC gives many
// warnings if a matching delete overload is not declared, even though the
// throw() spec guarantees it will not be implicitly called.
void operator delete(void *Ptr, clang::ASTContext &C, size_t)
              throw ();

namespace clang {

/// Attr - This represents one attribute.
class Attr {
public:
  enum Kind {
    Alias,
    Aligned,
    AlwaysInline,
    AnalyzerNoReturn, // Clang-specific.
    Annotate,
    AsmLabel, // Represent GCC asm label extension.
    BaseCheck,
    Blocks,
    CDecl,
    Cleanup,
    Const,
    Constructor,
    Deprecated,
    Destructor,
    FastCall,
    Final,
    Format,
    FormatArg,
    GNUInline,
    Hiding,
    IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
    IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
    Malloc,
    NoDebug,
    NoInline,
    NonNull,
    NoReturn,
    NoThrow,
    ObjCException,
    ObjCNSObject,
    Override,
    CFReturnsRetained,      // Clang/Checker-specific.
    CFReturnsNotRetained,   // Clang/Checker-specific.
    NSReturnsRetained,      // Clang/Checker-specific.
    NSReturnsNotRetained,   // Clang/Checker-specific.
    Overloadable, // Clang-specific
    Packed,
    PragmaPack,
    Pure,
    Regparm,
    ReqdWorkGroupSize,   // OpenCL-specific
    Section,
    Sentinel,
    StdCall,
    TransparentUnion,
    Unavailable,
    Unused,
    Used,
    Visibility,
    WarnUnusedResult,
    Weak,
    WeakImport,
    WeakRef,

    FIRST_TARGET_ATTRIBUTE,
    DLLExport,
    DLLImport,
    MSP430Interrupt,
    X86ForceAlignArgPointer
  };

private:
  Attr *Next;
  Kind AttrKind;
  bool Inherited : 1;

protected:
  void* operator new(size_t bytes) throw() {
    assert(0 && "Attrs cannot be allocated with regular 'new'.");
    return 0;
  }
  void operator delete(void* data) throw() {
    assert(0 && "Attrs cannot be released with regular 'delete'.");
  }

protected:
  Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
  virtual ~Attr() {
    assert(Next == 0 && "Destroy didn't work");
  }
public:
  virtual void Destroy(ASTContext &C);

  /// \brief Whether this attribute should be merged to new
  /// declarations.
  virtual bool isMerged() const { return true; }

  Kind getKind() const { return AttrKind; }

  Attr *getNext() { return Next; }
  const Attr *getNext() const { return Next; }
  void setNext(Attr *next) { Next = next; }

  template<typename T> const T *getNext() const {
    for (const Attr *attr = getNext(); attr; attr = attr->getNext())
      if (const T *V = dyn_cast<T>(attr))
        return V;
    return 0;
  }

  bool isInherited() const { return Inherited; }
  void setInherited(bool value) { Inherited = value; }

  void addAttr(Attr *attr) {
    assert((attr != 0) && "addAttr(): attr is null");

    // FIXME: This doesn't preserve the order in any way.
    attr->Next = Next;
    Next = attr;
  }

  // Clone this attribute.
  virtual Attr* clone(ASTContext &C) const = 0;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *) { return true; }
};
  
class AttrWithString : public Attr {
private:
  const char *Str;
  unsigned StrLen;
protected:
  AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s);
  llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
  void ReplaceString(ASTContext &C, llvm::StringRef newS);
public:
  virtual void Destroy(ASTContext &C);
};

#define DEF_SIMPLE_ATTR(ATTR)                                           \
class ATTR##Attr : public Attr {                                        \
public:                                                                 \
  ATTR##Attr() : Attr(ATTR) {}                                          \
  virtual Attr *clone(ASTContext &C) const;                             \
  static bool classof(const Attr *A) { return A->getKind() == ATTR; }   \
  static bool classof(const ATTR##Attr *A) { return true; }             \
}

DEF_SIMPLE_ATTR(Packed);

class PragmaPackAttr : public Attr {
  unsigned Alignment;

public:
  PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {}

  /// getAlignment - The specified alignment in bits.
  unsigned getAlignment() const { return Alignment; }

  virtual Attr* clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == PragmaPack;
  }
  static bool classof(const PragmaPackAttr *A) { return true; }
};

class AlignedAttr : public Attr {
  unsigned Alignment;
public:
  AlignedAttr(unsigned alignment)
    : Attr(Aligned), Alignment(alignment) {}

  /// getAlignment - The specified alignment in bits.
  unsigned getAlignment() const { return Alignment; }
  
  /// getMaxAlignment - Get the maximum alignment of attributes on this list.
  unsigned getMaxAlignment() const {
    const AlignedAttr *Next = getNext<AlignedAttr>();
    if (Next)
      return std::max(Next->getMaxAlignment(), Alignment);
    else
      return Alignment;
  }

  virtual Attr* clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == Aligned;
  }
  static bool classof(const AlignedAttr *A) { return true; }
};

class AnnotateAttr : public AttrWithString {
public:
  AnnotateAttr(ASTContext &C, llvm::StringRef ann)
    : AttrWithString(Annotate, C, ann) {}

  llvm::StringRef getAnnotation() const { return getString(); }

  virtual Attr* clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == Annotate;
  }
  static bool classof(const AnnotateAttr *A) { return true; }
};

class AsmLabelAttr : public AttrWithString {
public:
  AsmLabelAttr(ASTContext &C, llvm::StringRef L)
    : AttrWithString(AsmLabel, C, L) {}

  llvm::StringRef getLabel() const { return getString(); }

  virtual Attr* clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == AsmLabel;
  }
  static bool classof(const AsmLabelAttr *A) { return true; }
};

DEF_SIMPLE_ATTR(AlwaysInline);

class AliasAttr : public AttrWithString {
public:
  AliasAttr(ASTContext &C, llvm::StringRef aliasee)
    : AttrWithString(Alias, C, aliasee) {}

  llvm::StringRef getAliasee() const { return getString(); }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Alias; }
  static bool classof(const AliasAttr *A) { return true; }
};

class ConstructorAttr : public Attr {
  int priority;
public:
  ConstructorAttr(int p) : Attr(Constructor), priority(p) {}

  int getPriority() const { return priority; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Constructor; }
  static bool classof(const ConstructorAttr *A) { return true; }
};

class DestructorAttr : public Attr {
  int priority;
public:
  DestructorAttr(int p) : Attr(Destructor), priority(p) {}

  int getPriority() const { return priority; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Destructor; }
  static bool classof(const DestructorAttr *A) { return true; }
};

class IBOutletAttr : public Attr {
public:
  IBOutletAttr() : Attr(IBOutletKind) {}

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == IBOutletKind;
  }
  static bool classof(const IBOutletAttr *A) { return true; }
};

class IBActionAttr : public Attr {
public:
  IBActionAttr() : Attr(IBActionKind) {}

  virtual Attr *clone(ASTContext &C) const;

    // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == IBActionKind;
  }
  static bool classof(const IBActionAttr *A) { return true; }
};

DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
DEF_SIMPLE_ATTR(Final);
DEF_SIMPLE_ATTR(GNUInline);
DEF_SIMPLE_ATTR(Malloc);
DEF_SIMPLE_ATTR(NoReturn);

class SectionAttr : public AttrWithString {
public:
  SectionAttr(ASTContext &C, llvm::StringRef N)
    : AttrWithString(Section, C, N) {}

  llvm::StringRef getName() const { return getString(); }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == Section;
  }
  static bool classof(const SectionAttr *A) { return true; }
};

DEF_SIMPLE_ATTR(Unavailable);
DEF_SIMPLE_ATTR(Unused);
DEF_SIMPLE_ATTR(Used);
DEF_SIMPLE_ATTR(Weak);
DEF_SIMPLE_ATTR(WeakImport);
DEF_SIMPLE_ATTR(WeakRef);
DEF_SIMPLE_ATTR(NoThrow);
DEF_SIMPLE_ATTR(Const);
DEF_SIMPLE_ATTR(Pure);

class NonNullAttr : public Attr {
  unsigned* ArgNums;
  unsigned Size;
public:
  NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);

  virtual void Destroy(ASTContext &C);

  typedef const unsigned *iterator;
  iterator begin() const { return ArgNums; }
  iterator end() const { return ArgNums + Size; }
  unsigned size() const { return Size; }

  bool isNonNull(unsigned arg) const {
    return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
  }

  virtual Attr *clone(ASTContext &C) const;

  static bool classof(const Attr *A) { return A->getKind() == NonNull; }
  static bool classof(const NonNullAttr *A) { return true; }
};

class FormatAttr : public AttrWithString {
  int formatIdx, firstArg;
public:
  FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
    : AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}

  llvm::StringRef getType() const { return getString(); }
  void setType(ASTContext &C, llvm::StringRef type);
  int getFormatIdx() const { return formatIdx; }
  int getFirstArg() const { return firstArg; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Format; }
  static bool classof(const FormatAttr *A) { return true; }
};

class FormatArgAttr : public Attr {
  int formatIdx;
public:
  FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {}
  int getFormatIdx() const { return formatIdx; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == FormatArg; }
  static bool classof(const FormatArgAttr *A) { return true; }
};

class SentinelAttr : public Attr {
  int sentinel, NullPos;
public:
  SentinelAttr(int sentinel_val, int nullPos) : Attr(Sentinel),
               sentinel(sentinel_val), NullPos(nullPos) {}
  int getSentinel() const { return sentinel; }
  int getNullPos() const { return NullPos; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Sentinel; }
  static bool classof(const SentinelAttr *A) { return true; }
};

class VisibilityAttr : public Attr {
public:
  /// @brief An enumeration for the kinds of visibility of symbols.
  enum VisibilityTypes {
    DefaultVisibility = 0,
    HiddenVisibility,
    ProtectedVisibility
  };
private:
  VisibilityTypes VisibilityType;
public:
  VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
                 VisibilityType(v) {}

  VisibilityTypes getVisibility() const { return VisibilityType; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Visibility; }
  static bool classof(const VisibilityAttr *A) { return true; }
};

DEF_SIMPLE_ATTR(FastCall);
DEF_SIMPLE_ATTR(StdCall);
DEF_SIMPLE_ATTR(CDecl);
DEF_SIMPLE_ATTR(TransparentUnion);
DEF_SIMPLE_ATTR(ObjCNSObject);
DEF_SIMPLE_ATTR(ObjCException);

class OverloadableAttr : public Attr {
public:
  OverloadableAttr() : Attr(Overloadable) { }

  virtual bool isMerged() const { return false; }

  virtual Attr *clone(ASTContext &C) const;

  static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
  static bool classof(const OverloadableAttr *) { return true; }
};

class BlocksAttr : public Attr {
public:
  enum BlocksAttrTypes {
    ByRef = 0
  };
private:
  BlocksAttrTypes BlocksAttrType;
public:
  BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}

  BlocksAttrTypes getType() const { return BlocksAttrType; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Blocks; }
  static bool classof(const BlocksAttr *A) { return true; }
};

class FunctionDecl;

class CleanupAttr : public Attr {
  FunctionDecl *FD;

public:
  CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}

  const FunctionDecl *getFunctionDecl() const { return FD; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
  static bool classof(const CleanupAttr *A) { return true; }
};

DEF_SIMPLE_ATTR(NoDebug);
DEF_SIMPLE_ATTR(WarnUnusedResult);
DEF_SIMPLE_ATTR(NoInline);

class RegparmAttr : public Attr {
  unsigned NumParams;

public:
  RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}

  unsigned getNumParams() const { return NumParams; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == Regparm; }
  static bool classof(const RegparmAttr *A) { return true; }
};

class ReqdWorkGroupSizeAttr : public Attr {
  unsigned X, Y, Z;
public:
  ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
  : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}

  unsigned getXDim() const { return X; }
  unsigned getYDim() const { return Y; }
  unsigned getZDim() const { return Z; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) {
    return A->getKind() == ReqdWorkGroupSize;
  }
  static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
};

// Checker-specific attributes.
DEF_SIMPLE_ATTR(CFReturnsNotRetained);
DEF_SIMPLE_ATTR(CFReturnsRetained);
DEF_SIMPLE_ATTR(NSReturnsNotRetained);
DEF_SIMPLE_ATTR(NSReturnsRetained);

// C++0x member checking attributes.
DEF_SIMPLE_ATTR(BaseCheck);
DEF_SIMPLE_ATTR(Hiding);
DEF_SIMPLE_ATTR(Override);

// Target-specific attributes
DEF_SIMPLE_ATTR(DLLImport);
DEF_SIMPLE_ATTR(DLLExport);

class MSP430InterruptAttr : public Attr {
  unsigned Number;

public:
  MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}

  unsigned getNumber() const { return Number; }

  virtual Attr *clone(ASTContext &C) const;

  // Implement isa/cast/dyncast/etc.
  static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; }
  static bool classof(const MSP430InterruptAttr *A) { return true; }
};

DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);

#undef DEF_SIMPLE_ATTR

}  // end namespace clang

#endif
