Coverage Report

Created: 2020-02-15 09:57

/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 <cassert>
23
#include <cstddef>
24
#include <utility>
25
26
using namespace clang;
27
28
IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc,
29
6.99M
                                     IdentifierInfo *Ident) {
30
6.99M
  IdentifierLoc *Result = new (Ctx) IdentifierLoc;
31
6.99M
  Result->Loc = Loc;
32
6.99M
  Result->Ident = Ident;
33
6.99M
  return Result;
34
6.99M
}
35
36
19.3M
size_t ParsedAttr::allocated_size() const {
37
19.3M
  if (IsAvailability) 
return AttributeFactory::AvailabilityAllocSize6.02M
;
38
13.3M
  else if (IsTypeTagForDatatype)
39
167
    return AttributeFactory::TypeTagForDatatypeAllocSize;
40
13.3M
  else if (IsProperty)
41
101
    return AttributeFactory::PropertyAllocSize;
42
13.3M
  else if (HasParsedType)
43
65
    return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
44
65
                            detail::TypeTagForDatatypeData, ParsedType,
45
65
                            detail::PropertyData>(0, 0, 0, 1, 0);
46
13.3M
  return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
47
13.3M
                          detail::TypeTagForDatatypeData, ParsedType,
48
13.3M
                          detail::PropertyData>(NumArgs, 0, 0, 0, 0);
49
13.3M
}
50
51
125k
AttributeFactory::AttributeFactory() {
52
125k
  // Go ahead and configure all the inline capacity.  This is just a memset.
53
125k
  FreeLists.resize(InlineFreeListsCapacity);
54
125k
}
55
125k
AttributeFactory::~AttributeFactory() = default;
56
57
38.6M
static size_t getFreeListIndexForSize(size_t size) {
58
38.6M
  assert(size >= sizeof(ParsedAttr));
59
38.6M
  assert((size % sizeof(void*)) == 0);
60
38.6M
  return ((size - sizeof(ParsedAttr)) / sizeof(void *));
61
38.6M
}
62
63
19.3M
void *AttributeFactory::allocate(size_t size) {
64
19.3M
  // Check for a previously reclaimed attribute.
65
19.3M
  size_t index = getFreeListIndexForSize(size);
66
19.3M
  if (index < FreeLists.size() && 
!FreeLists[index].empty()19.3M
) {
67
19.2M
    ParsedAttr *attr = FreeLists[index].back();
68
19.2M
    FreeLists[index].pop_back();
69
19.2M
    return attr;
70
19.2M
  }
71
35.1k
72
35.1k
  // Otherwise, allocate something new.
73
35.1k
  return Alloc.Allocate(size, alignof(AttributeFactory));
74
35.1k
}
75
76
19.3M
void AttributeFactory::deallocate(ParsedAttr *Attr) {
77
19.3M
  size_t size = Attr->allocated_size();
78
19.3M
  size_t freeListIndex = getFreeListIndexForSize(size);
79
19.3M
80
19.3M
  // Expand FreeLists to the appropriate size, if required.
81
19.3M
  if (freeListIndex >= FreeLists.size())
82
1
    FreeLists.resize(freeListIndex + 1);
83
19.3M
84
19.3M
#ifndef NDEBUG
85
19.3M
  // In debug mode, zero out the attribute to help find memory overwriting.
86
19.3M
  memset(Attr, 0, size);
87
19.3M
#endif
88
19.3M
89
19.3M
  // Add 'Attr' to the appropriate free-list.
90
19.3M
  FreeLists[freeListIndex].push_back(Attr);
91
19.3M
}
92
93
229M
void AttributeFactory::reclaimPool(AttributePool &cur) {
94
229M
  for (ParsedAttr *AL : cur.Attrs)
95
19.3M
    deallocate(AL);
96
229M
}
97
98
49.1M
void AttributePool::takePool(AttributePool &pool) {
99
49.1M
  Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
100
49.1M
  pool.Attrs.clear();
101
49.1M
}
102
103
struct ParsedAttrInfo {
104
  unsigned NumArgs : 4;
105
  unsigned OptArgs : 4;
106
  unsigned HasCustomParsing : 1;
107
  unsigned IsTargetSpecific : 1;
108
  unsigned IsType : 1;
109
  unsigned IsStmt : 1;
110
  unsigned IsKnownToGCC : 1;
111
  unsigned IsSupportedByPragmaAttribute : 1;
112
113
  bool (*DiagAppertainsToDecl)(Sema &S, const ParsedAttr &Attr, const Decl *);
114
  bool (*DiagLangOpts)(Sema &S, const ParsedAttr &Attr);
115
  bool (*ExistsInTarget)(const TargetInfo &Target);
116
  unsigned (*SpellingIndexToSemanticSpelling)(const ParsedAttr &Attr);
117
  void (*GetPragmaAttributeMatchRules)(
118
      llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
119
      const LangOptions &LangOpts);
120
};
121
122
namespace {
123
124
#include "clang/Sema/AttrParsedAttrImpl.inc"
125
126
} // namespace
127
128
137M
static const ParsedAttrInfo &getInfo(const ParsedAttr &A) {
129
137M
  return AttrInfoMap[A.getKind()];
130
137M
}
131
132
36.0M
unsigned ParsedAttr::getMinArgs() const { return getInfo(*this).NumArgs; }
133
134
12.1M
unsigned ParsedAttr::getMaxArgs() const {
135
12.1M
  return getMinArgs() + getInfo(*this).OptArgs;
136
12.1M
}
137
138
18.0M
bool ParsedAttr::hasCustomParsing() const {
139
18.0M
  return getInfo(*this).HasCustomParsing;
140
18.0M
}
141
142
18.0M
bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
143
18.0M
  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
144
18.0M
}
145
146
bool ParsedAttr::appliesToDecl(const Decl *D,
147
291k
                               attr::SubjectMatchRule MatchRule) const {
148
291k
  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
149
291k
}
150
151
void ParsedAttr::getMatchRules(
152
    const LangOptions &LangOpts,
153
    SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
154
434
    const {
155
434
  return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
156
434
}
157
158
18.0M
bool ParsedAttr::diagnoseLangOpts(Sema &S) const {
159
18.0M
  return getInfo(*this).DiagLangOpts(S, *this);
160
18.0M
}
161
162
0
bool ParsedAttr::isTargetSpecificAttr() const {
163
0
  return getInfo(*this).IsTargetSpecific;
164
0
}
165
166
2.64M
bool ParsedAttr::isTypeAttr() const { return getInfo(*this).IsType; }
167
168
2.64M
bool ParsedAttr::isStmtAttr() const { return getInfo(*this).IsStmt; }
169
170
29.9M
bool ParsedAttr::existsInTarget(const TargetInfo &Target) const {
171
29.9M
  return getInfo(*this).ExistsInTarget(Target);
172
29.9M
}
173
174
5.08k
bool ParsedAttr::isKnownToGCC() const { return getInfo(*this).IsKnownToGCC; }
175
176
486
bool ParsedAttr::isSupportedByPragmaAttribute() const {
177
486
  return getInfo(*this).IsSupportedByPragmaAttribute;
178
486
}
179
180
7.66k
unsigned ParsedAttr::getSemanticSpelling() const {
181
7.66k
  return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
182
7.66k
}
183
184
146k
bool ParsedAttr::hasVariadicArg() const {
185
146k
  // If the attribute has the maximum number of optional arguments, we will
186
146k
  // claim that as being variadic. If we someday get an attribute that
187
146k
  // legitimately bumps up against that maximum, we can use another bit to track
188
146k
  // whether it's truly variadic or not.
189
146k
  return getInfo(*this).OptArgs == 15;
190
146k
}