Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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