Coverage Report

Created: 2022-01-25 06:29

/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
62.8k
                        const LangOptions &LangOpts) {
11
62.8k
  StringRef Name = Attr->getName();
12
  // Normalize the attribute name, __foo__ becomes foo.
13
62.8k
  if (Name.size() >= 4 && 
Name.startswith("__")62.7k
&&
Name.endswith("__")6.39k
)
14
6.39k
    Name = Name.substr(2, Name.size() - 4);
15
16
  // Normalize the scope name, but only for gnu and clang attributes.
17
62.8k
  StringRef ScopeName = Scope ? 
Scope->getName()1.88k
:
""60.9k
;
18
62.8k
  if (ScopeName == "__gnu__")
19
5
    ScopeName = "gnu";
20
62.7k
  else if (ScopeName == "_Clang")
21
12
    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
62.8k
  if (LangOpts.OpenMP && 
LangOpts.DoubleSquareBracketAttributes675
&&
28
62.8k
      
ScopeName == "omp"675
)
29
658
    return (Name == "directive" || 
Name == "sequence"121
) ?
1652
:
06
;
30
31
62.8k
#include "clang/Basic/AttrHasAttributeImpl.inc"
32
33
17
  return 0;
34
62.1k
}
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
148M
                       AttributeCommonInfo::Syntax SyntaxUsed) {
49
148M
  if (!Scope)
50
148M
    return "";
51
52
  // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
53
  // to be "clang".
54
3.14k
  StringRef ScopeName = Scope->getName();
55
3.14k
  if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
56
3.14k
      
SyntaxUsed == AttributeCommonInfo::AS_C2x165
) {
57
3.14k
    if (ScopeName == "__gnu__")
58
13
      ScopeName = "gnu";
59
3.13k
    else if (ScopeName == "_Clang")
60
22
      ScopeName = "clang";
61
3.14k
  }
62
3.14k
  return ScopeName;
63
148M
}
64
65
static StringRef normalizeAttrName(const IdentifierInfo *Name,
66
                                   StringRef NormalizedScopeName,
67
148M
                                   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
148M
  bool ShouldNormalize =
71
148M
      SyntaxUsed == AttributeCommonInfo::AS_GNU ||
72
148M
      
(3.76M
(3.76M
SyntaxUsed == AttributeCommonInfo::AS_CXX113.76M
||
73
3.76M
        
SyntaxUsed == AttributeCommonInfo::AS_C2x3.75M
) &&
74
3.76M
       
(16.5k
NormalizedScopeName.empty()16.5k
||
NormalizedScopeName == "gnu"3.14k
||
75
16.5k
        
NormalizedScopeName == "clang"2.76k
));
76
148M
  StringRef AttrName = Name->getName();
77
148M
  if (ShouldNormalize && 
AttrName.size() >= 4144M
&&
AttrName.startswith("__")144M
&&
78
148M
      
AttrName.endswith("__")129M
)
79
64.3M
    AttrName = AttrName.slice(2, AttrName.size() - 2);
80
81
148M
  return AttrName;
82
148M
}
83
84
14.7k
bool AttributeCommonInfo::isGNUScope() const {
85
14.7k
  return ScopeName && 
(712
ScopeName->isStr("gnu")712
||
ScopeName->isStr("__gnu__")532
);
86
14.7k
}
87
88
#include "clang/Sema/AttrParsedAttrKinds.inc"
89
90
static SmallString<64> normalizeName(const IdentifierInfo *Name,
91
                                     const IdentifierInfo *Scope,
92
147M
                                     AttributeCommonInfo::Syntax SyntaxUsed) {
93
147M
  StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
94
147M
  StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
95
96
147M
  SmallString<64> FullName = ScopeName;
97
147M
  if (!ScopeName.empty()) {
98
2.45k
    assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
99
2.45k
           SyntaxUsed == AttributeCommonInfo::AS_C2x);
100
0
    FullName += "::";
101
2.45k
  }
102
0
  FullName += AttrName;
103
104
147M
  return FullName;
105
147M
}
106
107
AttributeCommonInfo::Kind
108
AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
109
                                   const IdentifierInfo *ScopeName,
110
147M
                                   Syntax SyntaxUsed) {
111
147M
  return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
112
147M
}
113
114
181
std::string AttributeCommonInfo::getNormalizedFullName() const {
115
181
  return static_cast<std::string>(
116
181
      normalizeName(getAttrName(), getScopeName(), getSyntax()));
117
181
}
118
119
389k
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
120
  // Both variables will be used in tablegen generated
121
  // attribute spell list index matching code.
122
389k
  auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
123
389k
  StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
124
389k
  StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
125
126
389k
#include "clang/Sema/AttrSpellingListIndex.inc"
0
127
389k
}