Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h
Line
Count
Source (jump to first uncovered line)
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
3.43M
        SpellingIndex(SpellingNotCalculated) {}
82
83
  AttributeCommonInfo(SourceLocation AttrLoc)
84
      : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
85
19.7M
        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
82.6M
        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
0
        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
2.81M
        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
475k
        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
843
        SpellingIndex(SpellingNotCalculated) {}
120
121
  AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed,
122
                      unsigned Spelling)
123
      : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
124
198k
        AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {}
125
126
  AttributeCommonInfo(AttributeCommonInfo &&) = default;
127
  AttributeCommonInfo(const AttributeCommonInfo &) = default;
128
129
519M
  Kind getParsedKind() const { return Kind(AttrKind); }
130
83.7M
  Syntax getSyntax() const { return Syntax(SyntaxUsed); }
131
44.2M
  const IdentifierInfo *getAttrName() const { return AttrName; }
132
2.22M
  SourceLocation getLoc() const { return AttrRange.getBegin(); }
133
9.97M
  SourceRange getRange() const { return AttrRange; }
134
1.64M
  void setRange(SourceRange R) { AttrRange = R; }
135
136
0
  bool hasScope() const { return ScopeName; }
137
1.69M
  const IdentifierInfo *getScopeName() const { return ScopeName; }
138
1.29M
  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
38.6k
  bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
146
387
  bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
147
148
  bool isGNUScope() const;
149
  bool isClangScope() const;
150
151
161M
  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
161M
    return getParsedKind() == AT_Aligned && 
isKeywordAttribute()45.5k
;
169
161M
  }
170
171
161M
  bool isCXX11Attribute() const {
172
161M
    return SyntaxUsed == AS_CXX11 || 
isAlignasAttribute()161M
;
173
161M
  }
174
175
161M
  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
161M
  bool isStandardAttributeSyntax() const {
180
161M
    return isCXX11Attribute() || 
isC2xAttribute()161M
;
181
161M
  }
182
183
39.6k
  bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
184
185
45.5k
  bool isKeywordAttribute() const {
186
45.5k
    return SyntaxUsed == AS_Keyword || 
SyntaxUsed == AS_ContextSensitiveKeyword40.7k
;
187
45.5k
  }
188
189
2.02M
  bool isContextSensitiveKeywordAttribute() const {
190
2.02M
    return SyntaxUsed == AS_ContextSensitiveKeyword;
191
2.02M
  }
192
193
405k
  unsigned getAttributeSpellingListIndex() const {
194
405k
    assert((isAttributeSpellingListCalculated() || AttrName) &&
195
405k
           "Spelling cannot be found");
196
405k
    return isAttributeSpellingListCalculated()
197
405k
               ? 
SpellingIndex4.09k
198
405k
               : 
calculateAttributeSpellingListIndex()401k
;
199
405k
  }
200
23.1M
  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
1.29M
  unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
214
215
protected:
216
24.6M
  bool isAttributeSpellingListCalculated() const {
217
24.6M
    return SpellingIndex != SpellingNotCalculated;
218
24.6M
  }
219
};
220
} // namespace clang
221
222
#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H