Attr.h revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
1//===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the Attr interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_ATTR_H
15#define LLVM_CLANG_AST_ATTR_H
16
17#include "clang/AST/AttrIterator.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/Type.h"
20#include "clang/Basic/AttrKinds.h"
21#include "clang/Basic/LLVM.h"
22#include "clang/Basic/SourceLocation.h"
23#include "clang/Basic/VersionTuple.h"
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/ADT/StringSwitch.h"
27#include "llvm/Support/ErrorHandling.h"
28#include "llvm/Support/raw_ostream.h"
29#include <algorithm>
30#include <cassert>
31
32namespace clang {
33  class ASTContext;
34  class IdentifierInfo;
35  class ObjCInterfaceDecl;
36  class Expr;
37  class QualType;
38  class FunctionDecl;
39  class TypeSourceInfo;
40
41/// Attr - This represents one attribute.
42class Attr {
43private:
44  SourceRange Range;
45  unsigned AttrKind : 16;
46
47protected:
48  /// An index into the spelling list of an
49  /// attribute defined in Attr.td file.
50  unsigned SpellingListIndex : 4;
51  bool Inherited : 1;
52  bool IsPackExpansion : 1;
53  bool Implicit : 1;
54
55  virtual ~Attr();
56
57  void* operator new(size_t bytes) throw() {
58    llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
59  }
60  void operator delete(void* data) throw() {
61    llvm_unreachable("Attrs cannot be released with regular 'delete'.");
62  }
63
64public:
65  // Forward so that the regular new and delete do not hide global ones.
66  void* operator new(size_t Bytes, ASTContext &C,
67                     size_t Alignment = 16) throw() {
68    return ::operator new(Bytes, C, Alignment);
69  }
70  void operator delete(void *Ptr, ASTContext &C,
71                       size_t Alignment) throw() {
72    return ::operator delete(Ptr, C, Alignment);
73  }
74
75protected:
76  Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
77    : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
78      Inherited(false), IsPackExpansion(false), Implicit(false) {}
79
80public:
81
82  attr::Kind getKind() const {
83    return static_cast<attr::Kind>(AttrKind);
84  }
85
86  unsigned getSpellingListIndex() const { return SpellingListIndex; }
87  virtual const char *getSpelling() const = 0;
88
89  SourceLocation getLocation() const { return Range.getBegin(); }
90  SourceRange getRange() const { return Range; }
91  void setRange(SourceRange R) { Range = R; }
92
93  bool isInherited() const { return Inherited; }
94
95  /// \brief Returns true if the attribute has been implicitly created instead
96  /// of explicitly written by the user.
97  bool isImplicit() const { return Implicit; }
98  void setImplicit(bool I) { Implicit = I; }
99
100  void setPackExpansion(bool PE) { IsPackExpansion = PE; }
101  bool isPackExpansion() const { return IsPackExpansion; }
102
103  // Clone this attribute.
104  virtual Attr *clone(ASTContext &C) const = 0;
105
106  virtual bool isLateParsed() const { return false; }
107
108  // Pretty print this attribute.
109  virtual void printPretty(raw_ostream &OS,
110                           const PrintingPolicy &Policy) const = 0;
111
112  /// \brief By default, attributes cannot be duplicated when being merged;
113  /// however, an attribute can override this. Returns true if the attribute
114  /// can be duplicated when merging.
115  virtual bool duplicatesAllowed() const { return false; }
116};
117
118class InheritableAttr : public Attr {
119  virtual void anchor();
120protected:
121  InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
122    : Attr(AK, R, SpellingListIndex) {}
123
124public:
125  void setInherited(bool I) { Inherited = I; }
126
127  // Implement isa/cast/dyncast/etc.
128  static bool classof(const Attr *A) {
129    return A->getKind() <= attr::LAST_INHERITABLE;
130  }
131};
132
133class InheritableParamAttr : public InheritableAttr {
134  void anchor() override;
135protected:
136  InheritableParamAttr(attr::Kind AK, SourceRange R,
137                       unsigned SpellingListIndex = 0)
138    : InheritableAttr(AK, R, SpellingListIndex) {}
139
140public:
141  // Implement isa/cast/dyncast/etc.
142  static bool classof(const Attr *A) {
143    // Relies on relative order of enum emission with respect to MS inheritance
144    // attrs.
145    return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
146  }
147};
148
149#include "clang/AST/Attrs.inc"
150
151inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
152                                           const Attr *At) {
153  DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
154                  DiagnosticsEngine::ak_attr);
155  return DB;
156}
157
158inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
159                                           const Attr *At) {
160  PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
161                  DiagnosticsEngine::ak_attr);
162  return PD;
163}
164}  // end namespace clang
165
166#endif
167