Coverage Report

Created: 2022-05-14 11:35

/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
64.0k
                        const LangOptions &LangOpts) {
11
64.0k
  StringRef Name = Attr->getName();
12
  // Normalize the attribute name, __foo__ becomes foo.
13
64.0k
  if (Name.size() >= 4 && 
Name.startswith("__")64.0k
&&
Name.endswith("__")6.45k
)
14
6.45k
    Name = Name.substr(2, Name.size() - 4);
15
16
  // Normalize the scope name, but only for gnu and clang attributes.
17
64.0k
  StringRef ScopeName = Scope ? 
Scope->getName()2.86k
:
""61.1k
;
18
64.0k
  if (ScopeName == "__gnu__")
19
5
    ScopeName = "gnu";
20
64.0k
  else if (ScopeName == "_Clang")
21
13
    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
64.0k
  if (LangOpts.OpenMP && 
LangOpts.DoubleSquareBracketAttributes676
&&
28
64.0k
      
ScopeName == "omp"676
)
29
658
    return (Name == "directive" || 
Name == "sequence"121
) ?
1652
:
06
;
30
31
64.0k
#include "clang/Basic/AttrHasAttributeImpl.inc"
32
33
938
  return 0;
34
63.3k
}
35
36
140
const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
37
140
  switch (Rule) {
38
0
#define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract)                            \
39
140
  case attr::NAME:                                                             \
40
140
    return SPELLING;
41
140
#include 
"clang/Basic/AttrSubMatchRulesList.inc"0
42
140
  }
43
0
  llvm_unreachable("Invalid subject match rule");
44
0
}
45
46
static StringRef
47
normalizeAttrScopeName(const IdentifierInfo *Scope,
48
128M
                       AttributeCommonInfo::Syntax SyntaxUsed) {
49
128M
  if (!Scope)
50
128M
    return "";
51
52
  // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
53
  // to be "clang".
54
3.39k
  StringRef ScopeName = Scope->getName();
55
3.39k
  if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
56
3.39k
      
SyntaxUsed == AttributeCommonInfo::AS_C2x176
) {
57
3.39k
    if (ScopeName == "__gnu__")
58
13
      ScopeName = "gnu";
59
3.38k
    else if (ScopeName == "_Clang")
60
22
      ScopeName = "clang";
61
3.39k
  }
62
3.39k
  return ScopeName;
63
128M
}
64
65
static StringRef normalizeAttrName(const IdentifierInfo *Name,
66
                                   StringRef NormalizedScopeName,
67
128M
                                   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
128M
  bool ShouldNormalize =
71
128M
      SyntaxUsed == AttributeCommonInfo::AS_GNU ||
72
128M
      
(3.84M
(3.84M
SyntaxUsed == AttributeCommonInfo::AS_CXX113.84M
||
73
3.84M
        
SyntaxUsed == AttributeCommonInfo::AS_C2x3.83M
) &&
74
3.84M
       
(16.9k
NormalizedScopeName.empty()16.9k
||
NormalizedScopeName == "gnu"3.39k
||
75
16.9k
        
NormalizedScopeName == "clang"2.98k
));
76
128M
  StringRef AttrName = Name->getName();
77
128M
  if (ShouldNormalize && 
AttrName.size() >= 4124M
&&
AttrName.startswith("__")124M
&&
78
128M
      
AttrName.endswith("__")110M
)
79
55.4M
    AttrName = AttrName.slice(2, AttrName.size() - 2);
80
81
128M
  return AttrName;
82
128M
}
83
84
14.8k
bool AttributeCommonInfo::isGNUScope() const {
85
14.8k
  return ScopeName && 
(762
ScopeName->isStr("gnu")762
||
ScopeName->isStr("__gnu__")566
);
86
14.8k
}
87
88
#include "clang/Sema/AttrParsedAttrKinds.inc"
89
90
static SmallString<64> normalizeName(const IdentifierInfo *Name,
91
                                     const IdentifierInfo *Scope,
92
128M
                                     AttributeCommonInfo::Syntax SyntaxUsed) {
93
128M
  StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
94
128M
  StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
95
96
128M
  SmallString<64> FullName = ScopeName;
97
128M
  if (!ScopeName.empty()) {
98
2.64k
    assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
99
2.64k
           SyntaxUsed == AttributeCommonInfo::AS_C2x);
100
0
    FullName += "::";
101
2.64k
  }
102
0
  FullName += AttrName;
103
104
128M
  return FullName;
105
128M
}
106
107
AttributeCommonInfo::Kind
108
AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
109
                                   const IdentifierInfo *ScopeName,
110
128M
                                   Syntax SyntaxUsed) {
111
128M
  return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
112
128M
}
113
114
192
std::string AttributeCommonInfo::getNormalizedFullName() const {
115
192
  return static_cast<std::string>(
116
192
      normalizeName(getAttrName(), getScopeName(), getSyntax()));
117
192
}
118
119
398k
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
120
  // Both variables will be used in tablegen generated
121
  // attribute spell list index matching code.
122
398k
  auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
123
398k
  StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
124
398k
  StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
125
126
398k
#include "clang/Sema/AttrSpellingListIndex.inc"
0
127
398k
}