Coverage Report

Created: 2020-09-22 08:39

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Sema/ParsedAttr.cpp
Line
Count
Source (jump to first uncovered line)
1
//======- ParsedAttr.cpp --------------------------------------------------===//
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 ParsedAttr class implementation
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Sema/ParsedAttr.h"
14
#include "clang/AST/ASTContext.h"
15
#include "clang/Basic/AttrSubjectMatchRules.h"
16
#include "clang/Basic/IdentifierTable.h"
17
#include "clang/Basic/TargetInfo.h"
18
#include "clang/Sema/SemaInternal.h"
19
#include "llvm/ADT/SmallString.h"
20
#include "llvm/ADT/SmallVector.h"
21
#include "llvm/ADT/StringRef.h"
22
#include "llvm/Support/ManagedStatic.h"
23
#include <cassert>
24
#include <cstddef>
25
#include <utility>
26
27
using namespace clang;
28
29
LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry)
30
31
IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc,
32
15.5M
                                     IdentifierInfo *Ident) {
33
15.5M
  IdentifierLoc *Result = new (Ctx) IdentifierLoc;
34
15.5M
  Result->Loc = Loc;
35
15.5M
  Result->Ident = Ident;
36
15.5M
  return Result;
37
15.5M
}
38
39
49.0M
size_t ParsedAttr::allocated_size() const {
40
49.0M
  if (IsAvailability) 
return AttributeFactory::AvailabilityAllocSize7.71M
;
41
41.3M
  else if (IsTypeTagForDatatype)
42
168
    return AttributeFactory::TypeTagForDatatypeAllocSize;
43
41.3M
  else if (IsProperty)
44
101
    return AttributeFactory::PropertyAllocSize;
45
41.3M
  else if (HasParsedType)
46
67
    return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
47
67
                            detail::TypeTagForDatatypeData, ParsedType,
48
67
                            detail::PropertyData>(0, 0, 0, 1, 0);
49
41.3M
  return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
50
41.3M
                          detail::TypeTagForDatatypeData, ParsedType,
51
41.3M
                          detail::PropertyData>(NumArgs, 0, 0, 0, 0);
52
41.3M
}
53
54
159k
AttributeFactory::AttributeFactory() {
55
  // Go ahead and configure all the inline capacity.  This is just a memset.
56
159k
  FreeLists.resize(InlineFreeListsCapacity);
57
159k
}
58
159k
AttributeFactory::~AttributeFactory() = default;
59
60
98.0M
static size_t getFreeListIndexForSize(size_t size) {
61
98.0M
  assert(size >= sizeof(ParsedAttr));
62
98.0M
  assert((size % sizeof(void*)) == 0);
63
98.0M
  return ((size - sizeof(ParsedAttr)) / sizeof(void *));
64
98.0M
}
65
66
49.0M
void *AttributeFactory::allocate(size_t size) {
67
  // Check for a previously reclaimed attribute.
68
49.0M
  size_t index = getFreeListIndexForSize(size);
69
49.0M
  if (index < FreeLists.size() && 
!FreeLists[index].empty()49.0M
) {
70
48.9M
    ParsedAttr *attr = FreeLists[index].back();
71
48.9M
    FreeLists[index].pop_back();
72
48.9M
    return attr;
73
48.9M
  }
74
75
  // Otherwise, allocate something new.
76
44.6k
  return Alloc.Allocate(size, alignof(AttributeFactory));
77
44.6k
}
78
79
49.0M
void AttributeFactory::deallocate(ParsedAttr *Attr) {
80
49.0M
  size_t size = Attr->allocated_size();
81
49.0M
  size_t freeListIndex = getFreeListIndexForSize(size);
82
83
  // Expand FreeLists to the appropriate size, if required.
84
49.0M
  if (freeListIndex >= FreeLists.size())
85
1
    FreeLists.resize(freeListIndex + 1);
86
87
49.0M
#ifndef NDEBUG
88
  // In debug mode, zero out the attribute to help find memory overwriting.
89
49.0M
  memset(Attr, 0, size);
90
49.0M
#endif
91
92
  // Add 'Attr' to the appropriate free-list.
93
49.0M
  FreeLists[freeListIndex].push_back(Attr);
94
49.0M
}
95
96
383M
void AttributeFactory::reclaimPool(AttributePool &cur) {
97
383M
  for (ParsedAttr *AL : cur.Attrs)
98
49.0M
    deallocate(AL);
99
383M
}
100
101
87.5M
void AttributePool::takePool(AttributePool &pool) {
102
87.5M
  Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
103
87.5M
  pool.Attrs.clear();
104
87.5M
}
105
106
namespace {
107
108
#include "clang/Sema/AttrParsedAttrImpl.inc"
109
110
} // namespace
111
112
49.0M
const ParsedAttrInfo &ParsedAttrInfo::get(const AttributeCommonInfo &A) {
113
  // If we have a ParsedAttrInfo for this ParsedAttr then return that.
114
49.0M
  if ((size_t)A.getParsedKind() < llvm::array_lengthof(AttrInfoMap))
115
49.0M
    return *AttrInfoMap[A.getParsedKind()];
116
117
  // If this is an ignored attribute then return an appropriate ParsedAttrInfo.
118
600
  static const ParsedAttrInfo IgnoredParsedAttrInfo(
119
600
      AttributeCommonInfo::IgnoredAttribute);
120
600
  if (A.getParsedKind() == AttributeCommonInfo::IgnoredAttribute)
121
160
    return IgnoredParsedAttrInfo;
122
123
  // Otherwise this may be an attribute defined by a plugin. First instantiate
124
  // all plugin attributes if we haven't already done so.
125
440
  static llvm::ManagedStatic<std::list<std::unique_ptr<ParsedAttrInfo>>>
126
440
      PluginAttrInstances;
127
440
  if (PluginAttrInstances->empty())
128
440
    for (auto It : ParsedAttrInfoRegistry::entries())
129
0
      PluginAttrInstances->emplace_back(It.instantiate());
130
131
  // Search for a ParsedAttrInfo whose name and syntax match.
132
440
  std::string FullName = A.getNormalizedFullName();
133
440
  AttributeCommonInfo::Syntax SyntaxUsed = A.getSyntax();
134
440
  if (SyntaxUsed == AttributeCommonInfo::AS_ContextSensitiveKeyword)
135
0
    SyntaxUsed = AttributeCommonInfo::AS_Keyword;
136
137
440
  for (auto &Ptr : *PluginAttrInstances)
138
0
    for (auto &S : Ptr->Spellings)
139
0
      if (S.Syntax == SyntaxUsed && S.NormalizedFullName == FullName)
140
0
        return *Ptr;
141
142
  // If we failed to find a match then return a default ParsedAttrInfo.
143
440
  static const ParsedAttrInfo DefaultParsedAttrInfo(
144
440
      AttributeCommonInfo::UnknownAttribute);
145
440
  return DefaultParsedAttrInfo;
146
440
}
147
148
120M
unsigned ParsedAttr::getMinArgs() const { return getInfo().NumArgs; }
149
150
40.2M
unsigned ParsedAttr::getMaxArgs() const {
151
40.2M
  return getMinArgs() + getInfo().OptArgs;
152
40.2M
}
153
154
47.8M
bool ParsedAttr::hasCustomParsing() const {
155
47.8M
  return getInfo().HasCustomParsing;
156
47.8M
}
157
158
47.8M
bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
159
47.8M
  return getInfo().diagAppertainsToDecl(S, *this, D);
160
47.8M
}
161
162
bool ParsedAttr::appliesToDecl(const Decl *D,
163
982k
                               attr::SubjectMatchRule MatchRule) const {
164
982k
  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
165
982k
}
166
167
void ParsedAttr::getMatchRules(
168
    const LangOptions &LangOpts,
169
    SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
170
1.50k
    const {
171
1.50k
  return getInfo().getPragmaAttributeMatchRules(MatchRules, LangOpts);
172
1.50k
}
173
174
47.8M
bool ParsedAttr::diagnoseLangOpts(Sema &S) const {
175
47.8M
  return getInfo().diagLangOpts(S, *this);
176
47.8M
}
177
178
0
bool ParsedAttr::isTargetSpecificAttr() const {
179
0
  return getInfo().IsTargetSpecific;
180
0
}
181
182
2.84M
bool ParsedAttr::isTypeAttr() const { return getInfo().IsType; }
183
184
2.84M
bool ParsedAttr::isStmtAttr() const { return getInfo().IsStmt; }
185
186
87.7M
bool ParsedAttr::existsInTarget(const TargetInfo &Target) const {
187
87.7M
  return getInfo().existsInTarget(Target);
188
87.7M
}
189
190
9.87k
bool ParsedAttr::isKnownToGCC() const { return getInfo().IsKnownToGCC; }
191
192
1.55k
bool ParsedAttr::isSupportedByPragmaAttribute() const {
193
1.55k
  return getInfo().IsSupportedByPragmaAttribute;
194
1.55k
}
195
196
8.52k
unsigned ParsedAttr::getSemanticSpelling() const {
197
8.52k
  return getInfo().spellingIndexToSemanticSpelling(*this);
198
8.52k
}
199
200
236k
bool ParsedAttr::hasVariadicArg() const {
201
  // If the attribute has the maximum number of optional arguments, we will
202
  // claim that as being variadic. If we someday get an attribute that
203
  // legitimately bumps up against that maximum, we can use another bit to track
204
  // whether it's truly variadic or not.
205
236k
  return getInfo().OptArgs == 15;
206
236k
}