Coverage Report

Created: 2021-08-24 07:12

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Attributes.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "clang/Basic/Attributes.h"
2
#include "clang/Basic/AttrSubjectMatchRules.h"
3
#include "clang/Basic/AttributeCommonInfo.h"
4
#include "clang/Basic/IdentifierTable.h"
5
#include "llvm/ADT/StringSwitch.h"
6
using namespace clang;
7
8
int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
9
                        const IdentifierInfo *Attr, const TargetInfo &Target,
10
63.2k
                        const LangOptions &LangOpts) {
11
63.2k
  StringRef Name = Attr->getName();
12
  // Normalize the attribute name, __foo__ becomes foo.
13
63.2k
  if (Name.size() >= 4 && 
Name.startswith("__")63.2k
&&
Name.endswith("__")7.21k
)
14
7.21k
    Name = Name.substr(2, Name.size() - 4);
15
16
  // Normalize the scope name, but only for gnu and clang attributes.
17
63.2k
  StringRef ScopeName = Scope ? 
Scope->getName()1.84k
:
""61.4k
;
18
63.2k
  if (ScopeName == "__gnu__")
19
5
    ScopeName = "gnu";
20
63.2k
  else if (ScopeName == "_Clang")
21
8
    ScopeName = "clang";
22
23
  // As a special case, look for the omp::sequence and omp::directive
24
  // attributes. We support those, but not through the typical attribute
25
  // machinery that goes through TableGen. We support this in all OpenMP modes
26
  // so long as double square brackets are enabled.
27
63.2k
  if (LangOpts.OpenMP && 
LangOpts.DoubleSquareBracketAttributes709
&&
28
63.2k
      
ScopeName == "omp"709
)
29
658
    return (Name == "directive" || 
Name == "sequence"121
) ?
1652
:
06
;
30
31
63.2k
#include "clang/Basic/AttrHasAttributeImpl.inc"
32
33
21
  return 0;
34
62.5k
}
35
36
137
const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
37
137
  switch (Rule) {
38
0
#define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract)                            \
39
137
  case attr::NAME:                                                             \
40
137
    return SPELLING;
41
137
#include 
"clang/Basic/AttrSubMatchRulesList.inc"0
42
137
  }
43
0
  llvm_unreachable("Invalid subject match rule");
44
0
}
45
46
static StringRef
47
normalizeAttrScopeName(const IdentifierInfo *Scope,
48
171M
                       AttributeCommonInfo::Syntax SyntaxUsed) {
49
171M
  if (!Scope)
50
171M
    return "";
51
52
  // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
53
  // to be "clang".
54
3.10k
  StringRef ScopeName = Scope->getName();
55
3.10k
  if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
56
3.10k
      
SyntaxUsed == AttributeCommonInfo::AS_C2x165
) {
57
3.10k
    if (ScopeName == "__gnu__")
58
13
      ScopeName = "gnu";
59
3.09k
    else if (ScopeName == "_Clang")
60
22
      ScopeName = "clang";
61
3.10k
  }
62
3.10k
  return ScopeName;
63
171M
}
64
65
static StringRef normalizeAttrName(const IdentifierInfo *Name,
66
                                   StringRef NormalizedScopeName,
67
171M
                                   AttributeCommonInfo::Syntax SyntaxUsed) {
68
  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
69
  // for GNU attributes, and attributes using the double square bracket syntax.
70
171M
  bool ShouldNormalize =
71
171M
      SyntaxUsed == AttributeCommonInfo::AS_GNU ||
72
171M
      
(3.76M
(3.76M
SyntaxUsed == AttributeCommonInfo::AS_CXX113.76M
||
73
3.76M
        
SyntaxUsed == AttributeCommonInfo::AS_C2x3.75M
) &&
74
3.76M
       
(16.1k
NormalizedScopeName.empty()16.1k
||
NormalizedScopeName == "gnu"3.10k
||
75
16.1k
        
NormalizedScopeName == "clang"2.71k
));
76
171M
  StringRef AttrName = Name->getName();
77
171M
  if (ShouldNormalize && 
AttrName.size() >= 4167M
&&
AttrName.startswith("__")167M
&&
78
171M
      
AttrName.endswith("__")140M
)
79
75.8M
    AttrName = AttrName.slice(2, AttrName.size() - 2);
80
81
171M
  return AttrName;
82
171M
}
83
84
14.4k
bool AttributeCommonInfo::isGNUScope() const {
85
14.4k
  return ScopeName && 
(705
ScopeName->isStr("gnu")705
||
ScopeName->isStr("__gnu__")525
);
86
14.4k
}
87
88
#include "clang/Sema/AttrParsedAttrKinds.inc"
89
90
static SmallString<64> normalizeName(const IdentifierInfo *Name,
91
                                     const IdentifierInfo *Scope,
92
171M
                                     AttributeCommonInfo::Syntax SyntaxUsed) {
93
171M
  StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
94
171M
  StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
95
96
171M
  SmallString<64> FullName = ScopeName;
97
171M
  if (!ScopeName.empty()) {
98
2.41k
    assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
99
2.41k
           SyntaxUsed == AttributeCommonInfo::AS_C2x);
100
0
    FullName += "::";
101
2.41k
  }
102
0
  FullName += AttrName;
103
104
171M
  return FullName;
105
171M
}
106
107
AttributeCommonInfo::Kind
108
AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
109
                                   const IdentifierInfo *ScopeName,
110
171M
                                   Syntax SyntaxUsed) {
111
171M
  return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
112
171M
}
113
114
164
std::string AttributeCommonInfo::getNormalizedFullName() const {
115
164
  return static_cast<std::string>(
116
164
      normalizeName(getAttrName(), getScopeName(), getSyntax()));
117
164
}
118
119
388k
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
120
  // Both variables will be used in tablegen generated
121
  // attribute spell list index matching code.
122
388k
  auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
123
388k
  StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
124
388k
  StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
125
126
388k
#include "clang/Sema/AttrSpellingListIndex.inc"
0
127
388k
}