Home | History | Annotate | Line # | Download | only in Basic
      1 //======- AttributeCommonInfo.h - Base info about 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 AttributeCommonInfo type, which is the base for a
     10 // ParsedAttr and is used by Attr as a way to share info between the two.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
     15 #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
     16 #include "clang/Basic/SourceLocation.h"
     17 
     18 namespace clang {
     19 class IdentifierInfo;
     20 class ASTRecordWriter;
     21 
     22 class AttributeCommonInfo {
     23 public:
     24   /// The style used to specify an attribute.
     25   enum Syntax {
     26     /// __attribute__((...))
     27     AS_GNU,
     28 
     29     /// [[...]]
     30     AS_CXX11,
     31 
     32     /// [[...]]
     33     AS_C2x,
     34 
     35     /// __declspec(...)
     36     AS_Declspec,
     37 
     38     /// [uuid("...")] class Foo
     39     AS_Microsoft,
     40 
     41     /// __ptr16, alignas(...), etc.
     42     AS_Keyword,
     43 
     44     /// #pragma ...
     45     AS_Pragma,
     46 
     47     // Note TableGen depends on the order above.  Do not add or change the order
     48     // without adding related code to TableGen/ClangAttrEmitter.cpp.
     49     /// Context-sensitive version of a keyword attribute.
     50     AS_ContextSensitiveKeyword,
     51   };
     52   enum Kind {
     53 #define PARSED_ATTR(NAME) AT_##NAME,
     54 #include "clang/Sema/AttrParsedAttrList.inc"
     55 #undef PARSED_ATTR
     56     NoSemaHandlerAttribute,
     57     IgnoredAttribute,
     58     UnknownAttribute,
     59   };
     60 
     61 private:
     62   const IdentifierInfo *AttrName = nullptr;
     63   const IdentifierInfo *ScopeName = nullptr;
     64   SourceRange AttrRange;
     65   const SourceLocation ScopeLoc;
     66   // Corresponds to the Kind enum.
     67   unsigned AttrKind : 16;
     68   /// Corresponds to the Syntax enum.
     69   unsigned SyntaxUsed : 3;
     70   unsigned SpellingIndex : 4;
     71 
     72 protected:
     73   static constexpr unsigned SpellingNotCalculated = 0xf;
     74 
     75 public:
     76   AttributeCommonInfo(SourceRange AttrRange)
     77       : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
     78         SpellingIndex(SpellingNotCalculated) {}
     79 
     80   AttributeCommonInfo(SourceLocation AttrLoc)
     81       : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
     82         SpellingIndex(SpellingNotCalculated) {}
     83 
     84   AttributeCommonInfo(const IdentifierInfo *AttrName,
     85                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
     86                       SourceLocation ScopeLoc, Syntax SyntaxUsed)
     87       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
     88         ScopeLoc(ScopeLoc),
     89         AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
     90         SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
     91 
     92   AttributeCommonInfo(const IdentifierInfo *AttrName,
     93                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
     94                       SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed)
     95       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
     96         ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
     97         SpellingIndex(SpellingNotCalculated) {}
     98 
     99   AttributeCommonInfo(const IdentifierInfo *AttrName,
    100                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
    101                       SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed,
    102                       unsigned Spelling)
    103       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
    104         ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
    105         SpellingIndex(Spelling) {}
    106 
    107   AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
    108                       Syntax SyntaxUsed)
    109       : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
    110         ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
    111         SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
    112 
    113   AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed)
    114       : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
    115         AttrKind(K), SyntaxUsed(SyntaxUsed),
    116         SpellingIndex(SpellingNotCalculated) {}
    117 
    118   AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed,
    119                       unsigned Spelling)
    120       : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
    121         AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {}
    122 
    123   AttributeCommonInfo(AttributeCommonInfo &&) = default;
    124   AttributeCommonInfo(const AttributeCommonInfo &) = default;
    125 
    126   Kind getParsedKind() const { return Kind(AttrKind); }
    127   Syntax getSyntax() const { return Syntax(SyntaxUsed); }
    128   const IdentifierInfo *getAttrName() const { return AttrName; }
    129   SourceLocation getLoc() const { return AttrRange.getBegin(); }
    130   SourceRange getRange() const { return AttrRange; }
    131   void setRange(SourceRange R) { AttrRange = R; }
    132 
    133   bool hasScope() const { return ScopeName; }
    134   const IdentifierInfo *getScopeName() const { return ScopeName; }
    135   SourceLocation getScopeLoc() const { return ScopeLoc; }
    136 
    137   /// Gets the normalized full name, which consists of both scope and name and
    138   /// with surrounding underscores removed as appropriate (e.g.
    139   /// __gnu__::__attr__ will be normalized to gnu::attr).
    140   std::string getNormalizedFullName() const;
    141 
    142   bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
    143   bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
    144 
    145   bool isGNUScope() const;
    146 
    147   bool isAlignasAttribute() const {
    148     // FIXME: Use a better mechanism to determine this.
    149     return getParsedKind() == AT_Aligned && isKeywordAttribute();
    150   }
    151 
    152   bool isCXX11Attribute() const {
    153     return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
    154   }
    155 
    156   bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
    157 
    158   bool isKeywordAttribute() const {
    159     return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
    160   }
    161 
    162   bool isContextSensitiveKeywordAttribute() const {
    163     return SyntaxUsed == AS_ContextSensitiveKeyword;
    164   }
    165 
    166   unsigned getAttributeSpellingListIndex() const {
    167     assert((isAttributeSpellingListCalculated() || AttrName) &&
    168            "Spelling cannot be found");
    169     return isAttributeSpellingListCalculated()
    170                ? SpellingIndex
    171                : calculateAttributeSpellingListIndex();
    172   }
    173   void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
    174 
    175   static Kind getParsedKind(const IdentifierInfo *Name,
    176                             const IdentifierInfo *Scope, Syntax SyntaxUsed);
    177 
    178 private:
    179   /// Get an index into the attribute spelling list
    180   /// defined in Attr.td. This index is used by an attribute
    181   /// to pretty print itself.
    182   unsigned calculateAttributeSpellingListIndex() const;
    183 
    184   friend class clang::ASTRecordWriter;
    185   // Used exclusively by ASTDeclWriter to get the raw spelling list state.
    186   unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
    187 
    188 protected:
    189   bool isAttributeSpellingListCalculated() const {
    190     return SpellingIndex != SpellingNotCalculated;
    191   }
    192 };
    193 } // namespace clang
    194 
    195 #endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
    196