Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:50

0001 //===- ParsedAttrInfo.h - Info needed to parse an attribute -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the ParsedAttrInfo class, which dictates how to
0010 // parse an attribute. This class is the one that plugins derive to
0011 // define a new attribute.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_CLANG_BASIC_PARSEDATTRINFO_H
0016 #define LLVM_CLANG_BASIC_PARSEDATTRINFO_H
0017 
0018 #include "clang/Basic/AttrSubjectMatchRules.h"
0019 #include "clang/Basic/AttributeCommonInfo.h"
0020 #include "clang/Support/Compiler.h"
0021 #include "llvm/ADT/ArrayRef.h"
0022 #include "llvm/Support/Registry.h"
0023 #include <climits>
0024 #include <list>
0025 
0026 namespace clang {
0027 
0028 class Attr;
0029 class Decl;
0030 class LangOptions;
0031 class ParsedAttr;
0032 class Sema;
0033 class Stmt;
0034 class TargetInfo;
0035 
0036 struct ParsedAttrInfo {
0037   /// Corresponds to the Kind enum.
0038   LLVM_PREFERRED_TYPE(AttributeCommonInfo::Kind)
0039   unsigned AttrKind : 16;
0040   /// The number of required arguments of this attribute.
0041   unsigned NumArgs : 4;
0042   /// The number of optional arguments of this attributes.
0043   unsigned OptArgs : 4;
0044   /// The number of non-fake arguments specified in the attribute definition.
0045   unsigned NumArgMembers : 4;
0046   /// True if the parsing does not match the semantic content.
0047   LLVM_PREFERRED_TYPE(bool)
0048   unsigned HasCustomParsing : 1;
0049   // True if this attribute accepts expression parameter pack expansions.
0050   LLVM_PREFERRED_TYPE(bool)
0051   unsigned AcceptsExprPack : 1;
0052   /// True if this attribute is only available for certain targets.
0053   LLVM_PREFERRED_TYPE(bool)
0054   unsigned IsTargetSpecific : 1;
0055   /// True if this attribute applies to types.
0056   LLVM_PREFERRED_TYPE(bool)
0057   unsigned IsType : 1;
0058   /// True if this attribute applies to statements.
0059   LLVM_PREFERRED_TYPE(bool)
0060   unsigned IsStmt : 1;
0061   /// True if this attribute has any spellings that are known to gcc.
0062   LLVM_PREFERRED_TYPE(bool)
0063   unsigned IsKnownToGCC : 1;
0064   /// True if this attribute is supported by #pragma clang attribute.
0065   LLVM_PREFERRED_TYPE(bool)
0066   unsigned IsSupportedByPragmaAttribute : 1;
0067   /// The syntaxes supported by this attribute and how they're spelled.
0068   struct Spelling {
0069     AttributeCommonInfo::Syntax Syntax;
0070     const char *NormalizedFullName;
0071   };
0072   ArrayRef<Spelling> Spellings;
0073   // The names of the known arguments of this attribute.
0074   ArrayRef<const char *> ArgNames;
0075 
0076 protected:
0077   constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
0078                                AttributeCommonInfo::NoSemaHandlerAttribute)
0079       : AttrKind(AttrKind), NumArgs(0), OptArgs(0), NumArgMembers(0),
0080         HasCustomParsing(0), AcceptsExprPack(0), IsTargetSpecific(0), IsType(0),
0081         IsStmt(0), IsKnownToGCC(0), IsSupportedByPragmaAttribute(0) {}
0082 
0083   constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind, unsigned NumArgs,
0084                            unsigned OptArgs, unsigned NumArgMembers,
0085                            unsigned HasCustomParsing, unsigned AcceptsExprPack,
0086                            unsigned IsTargetSpecific, unsigned IsType,
0087                            unsigned IsStmt, unsigned IsKnownToGCC,
0088                            unsigned IsSupportedByPragmaAttribute,
0089                            ArrayRef<Spelling> Spellings,
0090                            ArrayRef<const char *> ArgNames)
0091       : AttrKind(AttrKind), NumArgs(NumArgs), OptArgs(OptArgs),
0092         NumArgMembers(NumArgMembers), HasCustomParsing(HasCustomParsing),
0093         AcceptsExprPack(AcceptsExprPack), IsTargetSpecific(IsTargetSpecific),
0094         IsType(IsType), IsStmt(IsStmt), IsKnownToGCC(IsKnownToGCC),
0095         IsSupportedByPragmaAttribute(IsSupportedByPragmaAttribute),
0096         Spellings(Spellings), ArgNames(ArgNames) {}
0097 
0098 public:
0099   virtual ~ParsedAttrInfo() = default;
0100 
0101   /// Check if this attribute has specified spelling.
0102   bool hasSpelling(AttributeCommonInfo::Syntax Syntax, StringRef Name) const {
0103     return llvm::any_of(Spellings, [&](const Spelling &S) {
0104       return (S.Syntax == Syntax && S.NormalizedFullName == Name);
0105     });
0106   }
0107 
0108   /// Check if this attribute appertains to D, and issue a diagnostic if not.
0109   virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
0110                                     const Decl *D) const {
0111     return true;
0112   }
0113   /// Check if this attribute appertains to St, and issue a diagnostic if not.
0114   virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr,
0115                                     const Stmt *St) const {
0116     return true;
0117   }
0118   /// Check if the given attribute is mutually exclusive with other attributes
0119   /// already applied to the given declaration.
0120   virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A,
0121                                    const Decl *D) const {
0122     return true;
0123   }
0124   /// Check if this attribute is allowed by the language we are compiling.
0125   virtual bool acceptsLangOpts(const LangOptions &LO) const { return true; }
0126 
0127   /// Check if this attribute is allowed when compiling for the given target.
0128   virtual bool existsInTarget(const TargetInfo &Target) const { return true; }
0129 
0130   /// Check if this attribute's spelling is allowed when compiling for the given
0131   /// target.
0132   virtual bool spellingExistsInTarget(const TargetInfo &Target,
0133                                       const unsigned SpellingListIndex) const {
0134     return true;
0135   }
0136 
0137   /// Convert the spelling index of Attr to a semantic spelling enum value.
0138   virtual unsigned
0139   spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const {
0140     return UINT_MAX;
0141   }
0142   /// Returns true if the specified parameter index for this attribute in
0143   /// Attr.td is an ExprArgument or VariadicExprArgument, or a subclass thereof;
0144   /// returns false otherwise.
0145   virtual bool isParamExpr(size_t N) const { return false; }
0146   /// Populate Rules with the match rules of this attribute.
0147   virtual void getPragmaAttributeMatchRules(
0148       llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
0149       const LangOptions &LangOpts) const {}
0150 
0151   enum AttrHandling { NotHandled, AttributeApplied, AttributeNotApplied };
0152   /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
0153   /// Decl then do so and return either AttributeApplied if it was applied or
0154   /// AttributeNotApplied if it wasn't. Otherwise return NotHandled.
0155   virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,
0156                                            const ParsedAttr &Attr) const {
0157     return NotHandled;
0158   }
0159   /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
0160   /// Stmt then do so (referencing the resulting Attr in Result) and return
0161   /// either AttributeApplied if it was applied or AttributeNotApplied if it
0162   /// wasn't. Otherwise return NotHandled.
0163   virtual AttrHandling handleStmtAttribute(Sema &S, Stmt *St,
0164                                            const ParsedAttr &Attr,
0165                                            class Attr *&Result) const {
0166     return NotHandled;
0167   }
0168 
0169   static const ParsedAttrInfo &get(const AttributeCommonInfo &A);
0170   static ArrayRef<const ParsedAttrInfo *> getAllBuiltin();
0171 };
0172 
0173 typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry;
0174 
0175 const std::list<std::unique_ptr<ParsedAttrInfo>> &getAttributePluginInstances();
0176 
0177 } // namespace clang
0178 
0179 namespace llvm {
0180 extern template class CLANG_TEMPLATE_ABI Registry<clang::ParsedAttrInfo>;
0181 } // namespace llvm
0182 
0183 #endif // LLVM_CLANG_BASIC_PARSEDATTRINFO_H