Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  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.     /// <vardecl> : <semantic>
  53.     AS_HLSLSemantic,
  54.   };
  55.   enum Kind {
  56. #define PARSED_ATTR(NAME) AT_##NAME,
  57. #include "clang/Sema/AttrParsedAttrList.inc"
  58. #undef PARSED_ATTR
  59.     NoSemaHandlerAttribute,
  60.     IgnoredAttribute,
  61.     UnknownAttribute,
  62.   };
  63.  
  64. private:
  65.   const IdentifierInfo *AttrName = nullptr;
  66.   const IdentifierInfo *ScopeName = nullptr;
  67.   SourceRange AttrRange;
  68.   const SourceLocation ScopeLoc;
  69.   // Corresponds to the Kind enum.
  70.   unsigned AttrKind : 16;
  71.   /// Corresponds to the Syntax enum.
  72.   unsigned SyntaxUsed : 4;
  73.   unsigned SpellingIndex : 4;
  74.  
  75. protected:
  76.   static constexpr unsigned SpellingNotCalculated = 0xf;
  77.  
  78. public:
  79.   AttributeCommonInfo(SourceRange AttrRange)
  80.       : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
  81.         SpellingIndex(SpellingNotCalculated) {}
  82.  
  83.   AttributeCommonInfo(SourceLocation AttrLoc)
  84.       : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
  85.         SpellingIndex(SpellingNotCalculated) {}
  86.  
  87.   AttributeCommonInfo(const IdentifierInfo *AttrName,
  88.                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
  89.                       SourceLocation ScopeLoc, Syntax SyntaxUsed)
  90.       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
  91.         ScopeLoc(ScopeLoc),
  92.         AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
  93.         SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
  94.  
  95.   AttributeCommonInfo(const IdentifierInfo *AttrName,
  96.                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
  97.                       SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed)
  98.       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
  99.         ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
  100.         SpellingIndex(SpellingNotCalculated) {}
  101.  
  102.   AttributeCommonInfo(const IdentifierInfo *AttrName,
  103.                       const IdentifierInfo *ScopeName, SourceRange AttrRange,
  104.                       SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed,
  105.                       unsigned Spelling)
  106.       : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
  107.         ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
  108.         SpellingIndex(Spelling) {}
  109.  
  110.   AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
  111.                       Syntax SyntaxUsed)
  112.       : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
  113.         ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
  114.         SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
  115.  
  116.   AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed)
  117.       : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
  118.         AttrKind(K), SyntaxUsed(SyntaxUsed),
  119.         SpellingIndex(SpellingNotCalculated) {}
  120.  
  121.   AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed,
  122.                       unsigned Spelling)
  123.       : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
  124.         AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {}
  125.  
  126.   AttributeCommonInfo(AttributeCommonInfo &&) = default;
  127.   AttributeCommonInfo(const AttributeCommonInfo &) = default;
  128.  
  129.   Kind getParsedKind() const { return Kind(AttrKind); }
  130.   Syntax getSyntax() const { return Syntax(SyntaxUsed); }
  131.   const IdentifierInfo *getAttrName() const { return AttrName; }
  132.   SourceLocation getLoc() const { return AttrRange.getBegin(); }
  133.   SourceRange getRange() const { return AttrRange; }
  134.   void setRange(SourceRange R) { AttrRange = R; }
  135.  
  136.   bool hasScope() const { return ScopeName; }
  137.   const IdentifierInfo *getScopeName() const { return ScopeName; }
  138.   SourceLocation getScopeLoc() const { return ScopeLoc; }
  139.  
  140.   /// Gets the normalized full name, which consists of both scope and name and
  141.   /// with surrounding underscores removed as appropriate (e.g.
  142.   /// __gnu__::__attr__ will be normalized to gnu::attr).
  143.   std::string getNormalizedFullName() const;
  144.  
  145.   bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
  146.   bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
  147.  
  148.   bool isGNUScope() const;
  149.   bool isClangScope() const;
  150.  
  151.   bool isAlignasAttribute() const {
  152.     // FIXME: Use a better mechanism to determine this.
  153.     // We use this in `isCXX11Attribute` below, so it _should_ only return
  154.     // true for the `alignas` spelling, but it currently also returns true
  155.     // for the `_Alignas` spelling, which only exists in C11. Distinguishing
  156.     // between the two is important because they behave differently:
  157.     // - `alignas` may only appear in the attribute-specifier-seq before
  158.     //   the decl-specifier-seq and is therefore associated with the
  159.     //   declaration.
  160.     // - `_Alignas` may appear anywhere within the declaration-specifiers
  161.     //   and is therefore associated with the `DeclSpec`.
  162.     // It's not clear how best to fix this:
  163.     // - We have the necessary information in the form of the `SpellingIndex`,
  164.     //   but we would need to compare against AlignedAttr::Keyword_alignas,
  165.     //   and we can't depend on clang/AST/Attr.h here.
  166.     // - We could test `getAttrName()->getName() == "alignas"`, but this is
  167.     //   inefficient.
  168.     return getParsedKind() == AT_Aligned && isKeywordAttribute();
  169.   }
  170.  
  171.   bool isCXX11Attribute() const {
  172.     return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
  173.   }
  174.  
  175.   bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
  176.  
  177.   /// The attribute is spelled [[]] in either C or C++ mode, including standard
  178.   /// attributes spelled with a keyword, like alignas.
  179.   bool isStandardAttributeSyntax() const {
  180.     return isCXX11Attribute() || isC2xAttribute();
  181.   }
  182.  
  183.   bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
  184.  
  185.   bool isKeywordAttribute() const {
  186.     return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
  187.   }
  188.  
  189.   bool isContextSensitiveKeywordAttribute() const {
  190.     return SyntaxUsed == AS_ContextSensitiveKeyword;
  191.   }
  192.  
  193.   unsigned getAttributeSpellingListIndex() const {
  194.     assert((isAttributeSpellingListCalculated() || AttrName) &&
  195.            "Spelling cannot be found");
  196.     return isAttributeSpellingListCalculated()
  197.                ? SpellingIndex
  198.                : calculateAttributeSpellingListIndex();
  199.   }
  200.   void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
  201.  
  202.   static Kind getParsedKind(const IdentifierInfo *Name,
  203.                             const IdentifierInfo *Scope, Syntax SyntaxUsed);
  204.  
  205. private:
  206.   /// Get an index into the attribute spelling list
  207.   /// defined in Attr.td. This index is used by an attribute
  208.   /// to pretty print itself.
  209.   unsigned calculateAttributeSpellingListIndex() const;
  210.  
  211.   friend class clang::ASTRecordWriter;
  212.   // Used exclusively by ASTDeclWriter to get the raw spelling list state.
  213.   unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
  214.  
  215. protected:
  216.   bool isAttributeSpellingListCalculated() const {
  217.     return SpellingIndex != SpellingNotCalculated;
  218.   }
  219. };
  220. } // namespace clang
  221.  
  222. #endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
  223.