clang API Documentation

Attr.h
Go to the documentation of this file.
00001 //===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the Attr interface and subclasses.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_AST_ATTR_H
00015 #define LLVM_CLANG_AST_ATTR_H
00016 
00017 #include "clang/AST/AttrIterator.h"
00018 #include "clang/AST/Decl.h"
00019 #include "clang/AST/Expr.h"
00020 #include "clang/AST/Type.h"
00021 #include "clang/Basic/AttrKinds.h"
00022 #include "clang/Basic/LLVM.h"
00023 #include "clang/Basic/SourceLocation.h"
00024 #include "clang/Basic/VersionTuple.h"
00025 #include "llvm/ADT/SmallVector.h"
00026 #include "llvm/ADT/StringRef.h"
00027 #include "llvm/ADT/StringSwitch.h"
00028 #include "llvm/Support/ErrorHandling.h"
00029 #include "llvm/Support/raw_ostream.h"
00030 #include <algorithm>
00031 #include <cassert>
00032 
00033 namespace clang {
00034   class ASTContext;
00035   class IdentifierInfo;
00036   class ObjCInterfaceDecl;
00037   class Expr;
00038   class QualType;
00039   class FunctionDecl;
00040   class TypeSourceInfo;
00041 
00042 /// Attr - This represents one attribute.
00043 class Attr {
00044 private:
00045   SourceRange Range;
00046   unsigned AttrKind : 16;
00047 
00048 protected:
00049   /// An index into the spelling list of an
00050   /// attribute defined in Attr.td file.
00051   unsigned SpellingListIndex : 4;
00052   bool Inherited : 1;
00053   bool IsPackExpansion : 1;
00054   bool Implicit : 1;
00055 
00056   virtual ~Attr();
00057 
00058   void* operator new(size_t bytes) throw() {
00059     llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
00060   }
00061   void operator delete(void* data) throw() {
00062     llvm_unreachable("Attrs cannot be released with regular 'delete'.");
00063   }
00064 
00065 public:
00066   // Forward so that the regular new and delete do not hide global ones.
00067   void* operator new(size_t Bytes, ASTContext &C,
00068                      size_t Alignment = 16) throw() {
00069     return ::operator new(Bytes, C, Alignment);
00070   }
00071   void operator delete(void *Ptr, ASTContext &C,
00072                        size_t Alignment) throw() {
00073     return ::operator delete(Ptr, C, Alignment);
00074   }
00075 
00076 protected:
00077   Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
00078     : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
00079       Inherited(false), IsPackExpansion(false), Implicit(false) {}
00080 
00081 public:
00082 
00083   attr::Kind getKind() const {
00084     return static_cast<attr::Kind>(AttrKind);
00085   }
00086   
00087   unsigned getSpellingListIndex() const { return SpellingListIndex; }
00088   virtual const char *getSpelling() const = 0;
00089 
00090   SourceLocation getLocation() const { return Range.getBegin(); }
00091   SourceRange getRange() const { return Range; }
00092   void setRange(SourceRange R) { Range = R; }
00093 
00094   bool isInherited() const { return Inherited; }
00095 
00096   /// \brief Returns true if the attribute has been implicitly created instead
00097   /// of explicitly written by the user.
00098   bool isImplicit() const { return Implicit; }
00099   void setImplicit(bool I) { Implicit = I; }
00100 
00101   void setPackExpansion(bool PE) { IsPackExpansion = PE; }
00102   bool isPackExpansion() const { return IsPackExpansion; }
00103 
00104   // Clone this attribute.
00105   virtual Attr *clone(ASTContext &C) const = 0;
00106 
00107   virtual bool isLateParsed() const { return false; }
00108 
00109   // Pretty print this attribute.
00110   virtual void printPretty(raw_ostream &OS,
00111                            const PrintingPolicy &Policy) const = 0;
00112 
00113   /// \brief By default, attributes cannot be duplicated when being merged;
00114   /// however, an attribute can override this. Returns true if the attribute
00115   /// can be duplicated when merging.
00116   virtual bool duplicatesAllowed() const { return false; }
00117 };
00118 
00119 class InheritableAttr : public Attr {
00120   virtual void anchor();
00121 protected:
00122   InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
00123     : Attr(AK, R, SpellingListIndex) {}
00124 
00125 public:
00126   void setInherited(bool I) { Inherited = I; }
00127 
00128   // Implement isa/cast/dyncast/etc.
00129   static bool classof(const Attr *A) {
00130     return A->getKind() <= attr::LAST_INHERITABLE;
00131   }
00132 };
00133 
00134 class InheritableParamAttr : public InheritableAttr {
00135   void anchor() override;
00136 protected:
00137   InheritableParamAttr(attr::Kind AK, SourceRange R,
00138                        unsigned SpellingListIndex = 0)
00139     : InheritableAttr(AK, R, SpellingListIndex) {}
00140 
00141 public:
00142   // Implement isa/cast/dyncast/etc.
00143   static bool classof(const Attr *A) {
00144     // Relies on relative order of enum emission with respect to MS inheritance
00145     // attrs.
00146     return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
00147   }
00148 };
00149 
00150 #include "clang/AST/Attrs.inc"
00151 
00152 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
00153                                            const Attr *At) {
00154   DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
00155                   DiagnosticsEngine::ak_attr);
00156   return DB;
00157 }
00158 
00159 inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
00160                                            const Attr *At) {
00161   PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
00162                   DiagnosticsEngine::ak_attr);
00163   return PD;
00164 }
00165 }  // end namespace clang
00166 
00167 #endif