Attr.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- Attr.h - Classes for representing attributes ----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the Attr interface and subclasses.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_AST_ATTR_H
  18. #define LLVM_CLANG_AST_ATTR_H
  19. #include "clang/AST/ASTFwd.h"
  20. #include "clang/AST/AttrIterator.h"
  21. #include "clang/AST/Decl.h"
  22. #include "clang/AST/Type.h"
  23. #include "clang/Basic/AttrKinds.h"
  24. #include "clang/Basic/AttributeCommonInfo.h"
  25. #include "clang/Basic/LangOptions.h"
  26. #include "clang/Basic/LLVM.h"
  27. #include "clang/Basic/OpenMPKinds.h"
  28. #include "clang/Basic/Sanitizers.h"
  29. #include "clang/Basic/SourceLocation.h"
  30. #include "llvm/ADT/StringSwitch.h"
  31. #include "llvm/Support/ErrorHandling.h"
  32. #include "llvm/Support/VersionTuple.h"
  33. #include "llvm/Support/raw_ostream.h"
  34. #include <algorithm>
  35. #include <cassert>
  36. namespace clang {
  37. class ASTContext;
  38. class AttributeCommonInfo;
  39. class FunctionDecl;
  40. class OMPTraitInfo;
  41. /// Attr - This represents one attribute.
  42. class Attr : public AttributeCommonInfo {
  43. private:
  44. unsigned AttrKind : 16;
  45. protected:
  46. /// An index into the spelling list of an
  47. /// attribute defined in Attr.td file.
  48. unsigned Inherited : 1;
  49. unsigned IsPackExpansion : 1;
  50. unsigned Implicit : 1;
  51. // FIXME: These are properties of the attribute kind, not state for this
  52. // instance of the attribute.
  53. unsigned IsLateParsed : 1;
  54. unsigned InheritEvenIfAlreadyPresent : 1;
  55. void *operator new(size_t bytes) noexcept {
  56. llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
  57. }
  58. void operator delete(void *data) noexcept {
  59. llvm_unreachable("Attrs cannot be released with regular 'delete'.");
  60. }
  61. public:
  62. // Forward so that the regular new and delete do not hide global ones.
  63. void *operator new(size_t Bytes, ASTContext &C,
  64. size_t Alignment = 8) noexcept {
  65. return ::operator new(Bytes, C, Alignment);
  66. }
  67. void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
  68. return ::operator delete(Ptr, C, Alignment);
  69. }
  70. protected:
  71. Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
  72. attr::Kind AK, bool IsLateParsed)
  73. : AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
  74. IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
  75. InheritEvenIfAlreadyPresent(false) {}
  76. public:
  77. attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
  78. unsigned getSpellingListIndex() const {
  79. return getAttributeSpellingListIndex();
  80. }
  81. const char *getSpelling() const;
  82. SourceLocation getLocation() const { return getRange().getBegin(); }
  83. bool isInherited() const { return Inherited; }
  84. /// Returns true if the attribute has been implicitly created instead
  85. /// of explicitly written by the user.
  86. bool isImplicit() const { return Implicit; }
  87. void setImplicit(bool I) { Implicit = I; }
  88. void setPackExpansion(bool PE) { IsPackExpansion = PE; }
  89. bool isPackExpansion() const { return IsPackExpansion; }
  90. // Clone this attribute.
  91. Attr *clone(ASTContext &C) const;
  92. bool isLateParsed() const { return IsLateParsed; }
  93. // Pretty print this attribute.
  94. void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
  95. static StringRef getDocumentation(attr::Kind);
  96. };
  97. class TypeAttr : public Attr {
  98. protected:
  99. TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
  100. attr::Kind AK, bool IsLateParsed)
  101. : Attr(Context, CommonInfo, AK, IsLateParsed) {}
  102. public:
  103. static bool classof(const Attr *A) {
  104. return A->getKind() >= attr::FirstTypeAttr &&
  105. A->getKind() <= attr::LastTypeAttr;
  106. }
  107. };
  108. class StmtAttr : public Attr {
  109. protected:
  110. StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
  111. attr::Kind AK, bool IsLateParsed)
  112. : Attr(Context, CommonInfo, AK, IsLateParsed) {}
  113. public:
  114. static bool classof(const Attr *A) {
  115. return A->getKind() >= attr::FirstStmtAttr &&
  116. A->getKind() <= attr::LastStmtAttr;
  117. }
  118. };
  119. class InheritableAttr : public Attr {
  120. protected:
  121. InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
  122. attr::Kind AK, bool IsLateParsed,
  123. bool InheritEvenIfAlreadyPresent)
  124. : Attr(Context, CommonInfo, AK, IsLateParsed) {
  125. this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
  126. }
  127. public:
  128. void setInherited(bool I) { Inherited = I; }
  129. /// Should this attribute be inherited from a prior declaration even if it's
  130. /// explicitly provided in the current declaration?
  131. bool shouldInheritEvenIfAlreadyPresent() const {
  132. return InheritEvenIfAlreadyPresent;
  133. }
  134. // Implement isa/cast/dyncast/etc.
  135. static bool classof(const Attr *A) {
  136. return A->getKind() >= attr::FirstInheritableAttr &&
  137. A->getKind() <= attr::LastInheritableAttr;
  138. }
  139. };
  140. class DeclOrStmtAttr : public InheritableAttr {
  141. protected:
  142. DeclOrStmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
  143. attr::Kind AK, bool IsLateParsed,
  144. bool InheritEvenIfAlreadyPresent)
  145. : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
  146. InheritEvenIfAlreadyPresent) {}
  147. public:
  148. static bool classof(const Attr *A) {
  149. return A->getKind() >= attr::FirstDeclOrStmtAttr &&
  150. A->getKind() <= attr::LastDeclOrStmtAttr;
  151. }
  152. };
  153. class InheritableParamAttr : public InheritableAttr {
  154. protected:
  155. InheritableParamAttr(ASTContext &Context,
  156. const AttributeCommonInfo &CommonInfo, attr::Kind AK,
  157. bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
  158. : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
  159. InheritEvenIfAlreadyPresent) {}
  160. public:
  161. // Implement isa/cast/dyncast/etc.
  162. static bool classof(const Attr *A) {
  163. return A->getKind() >= attr::FirstInheritableParamAttr &&
  164. A->getKind() <= attr::LastInheritableParamAttr;
  165. }
  166. };
  167. /// A parameter attribute which changes the argument-passing ABI rule
  168. /// for the parameter.
  169. class ParameterABIAttr : public InheritableParamAttr {
  170. protected:
  171. ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
  172. attr::Kind AK, bool IsLateParsed,
  173. bool InheritEvenIfAlreadyPresent)
  174. : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
  175. InheritEvenIfAlreadyPresent) {}
  176. public:
  177. ParameterABI getABI() const {
  178. switch (getKind()) {
  179. case attr::SwiftContext:
  180. return ParameterABI::SwiftContext;
  181. case attr::SwiftAsyncContext:
  182. return ParameterABI::SwiftAsyncContext;
  183. case attr::SwiftErrorResult:
  184. return ParameterABI::SwiftErrorResult;
  185. case attr::SwiftIndirectResult:
  186. return ParameterABI::SwiftIndirectResult;
  187. default:
  188. llvm_unreachable("bad parameter ABI attribute kind");
  189. }
  190. }
  191. static bool classof(const Attr *A) {
  192. return A->getKind() >= attr::FirstParameterABIAttr &&
  193. A->getKind() <= attr::LastParameterABIAttr;
  194. }
  195. };
  196. /// A single parameter index whose accessors require each use to make explicit
  197. /// the parameter index encoding needed.
  198. class ParamIdx {
  199. // Idx is exposed only via accessors that specify specific encodings.
  200. unsigned Idx : 30;
  201. unsigned HasThis : 1;
  202. unsigned IsValid : 1;
  203. void assertComparable(const ParamIdx &I) const {
  204. assert(isValid() && I.isValid() &&
  205. "ParamIdx must be valid to be compared");
  206. // It's possible to compare indices from separate functions, but so far
  207. // it's not proven useful. Moreover, it might be confusing because a
  208. // comparison on the results of getASTIndex might be inconsistent with a
  209. // comparison on the ParamIdx objects themselves.
  210. assert(HasThis == I.HasThis &&
  211. "ParamIdx must be for the same function to be compared");
  212. }
  213. public:
  214. /// Construct an invalid parameter index (\c isValid returns false and
  215. /// accessors fail an assert).
  216. ParamIdx() : Idx(0), HasThis(false), IsValid(false) {}
  217. /// \param Idx is the parameter index as it is normally specified in
  218. /// attributes in the source: one-origin including any C++ implicit this
  219. /// parameter.
  220. ///
  221. /// \param D is the declaration containing the parameters. It is used to
  222. /// determine if there is a C++ implicit this parameter.
  223. ParamIdx(unsigned Idx, const Decl *D)
  224. : Idx(Idx), HasThis(false), IsValid(true) {
  225. assert(Idx >= 1 && "Idx must be one-origin");
  226. if (const auto *FD = dyn_cast<FunctionDecl>(D))
  227. HasThis = FD->isCXXInstanceMember();
  228. }
  229. /// A type into which \c ParamIdx can be serialized.
  230. ///
  231. /// A static assertion that it's of the correct size follows the \c ParamIdx
  232. /// class definition.
  233. typedef uint32_t SerialType;
  234. /// Produce a representation that can later be passed to \c deserialize to
  235. /// construct an equivalent \c ParamIdx.
  236. SerialType serialize() const {
  237. return *reinterpret_cast<const SerialType *>(this);
  238. }
  239. /// Construct from a result from \c serialize.
  240. static ParamIdx deserialize(SerialType S) {
  241. // Using this two-step static_cast via void * instead of reinterpret_cast
  242. // silences a -Wstrict-aliasing false positive from GCC7 and earlier.
  243. void *ParamIdxPtr = static_cast<void *>(&S);
  244. ParamIdx P(*static_cast<ParamIdx *>(ParamIdxPtr));
  245. assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
  246. return P;
  247. }
  248. /// Is this parameter index valid?
  249. bool isValid() const { return IsValid; }
  250. /// Get the parameter index as it would normally be encoded for attributes at
  251. /// the source level of representation: one-origin including any C++ implicit
  252. /// this parameter.
  253. ///
  254. /// This encoding thus makes sense for diagnostics, pretty printing, and
  255. /// constructing new attributes from a source-like specification.
  256. unsigned getSourceIndex() const {
  257. assert(isValid() && "ParamIdx must be valid");
  258. return Idx;
  259. }
  260. /// Get the parameter index as it would normally be encoded at the AST level
  261. /// of representation: zero-origin not including any C++ implicit this
  262. /// parameter.
  263. ///
  264. /// This is the encoding primarily used in Sema. However, in diagnostics,
  265. /// Sema uses \c getSourceIndex instead.
  266. unsigned getASTIndex() const {
  267. assert(isValid() && "ParamIdx must be valid");
  268. assert(Idx >= 1 + HasThis &&
  269. "stored index must be base-1 and not specify C++ implicit this");
  270. return Idx - 1 - HasThis;
  271. }
  272. /// Get the parameter index as it would normally be encoded at the LLVM level
  273. /// of representation: zero-origin including any C++ implicit this parameter.
  274. ///
  275. /// This is the encoding primarily used in CodeGen.
  276. unsigned getLLVMIndex() const {
  277. assert(isValid() && "ParamIdx must be valid");
  278. assert(Idx >= 1 && "stored index must be base-1");
  279. return Idx - 1;
  280. }
  281. bool operator==(const ParamIdx &I) const {
  282. assertComparable(I);
  283. return Idx == I.Idx;
  284. }
  285. bool operator!=(const ParamIdx &I) const {
  286. assertComparable(I);
  287. return Idx != I.Idx;
  288. }
  289. bool operator<(const ParamIdx &I) const {
  290. assertComparable(I);
  291. return Idx < I.Idx;
  292. }
  293. bool operator>(const ParamIdx &I) const {
  294. assertComparable(I);
  295. return Idx > I.Idx;
  296. }
  297. bool operator<=(const ParamIdx &I) const {
  298. assertComparable(I);
  299. return Idx <= I.Idx;
  300. }
  301. bool operator>=(const ParamIdx &I) const {
  302. assertComparable(I);
  303. return Idx >= I.Idx;
  304. }
  305. };
  306. static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
  307. "ParamIdx does not fit its serialization type");
  308. /// Contains information gathered from parsing the contents of TargetAttr.
  309. struct ParsedTargetAttr {
  310. std::vector<std::string> Features;
  311. StringRef Architecture;
  312. StringRef Tune;
  313. StringRef BranchProtection;
  314. bool DuplicateArchitecture = false;
  315. bool DuplicateTune = false;
  316. bool operator ==(const ParsedTargetAttr &Other) const {
  317. return DuplicateArchitecture == Other.DuplicateArchitecture &&
  318. DuplicateTune == Other.DuplicateTune &&
  319. Architecture == Other.Architecture &&
  320. Tune == Other.Tune &&
  321. BranchProtection == Other.BranchProtection &&
  322. Features == Other.Features;
  323. }
  324. };
  325. #include "clang/AST/Attrs.inc"
  326. inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
  327. const Attr *At) {
  328. DB.AddTaggedVal(reinterpret_cast<uint64_t>(At), DiagnosticsEngine::ak_attr);
  329. return DB;
  330. }
  331. } // end namespace clang
  332. #endif
  333. #ifdef __GNUC__
  334. #pragma GCC diagnostic pop
  335. #endif