Coverage Report

Created: 2021-01-23 06:44

/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.3k
                        const LangOptions &LangOpts) {
11
62.3k
  StringRef Name = Attr->getName();
12
  // Normalize the attribute name, __foo__ becomes foo.
13
62.3k
  if (Name.size() >= 4 && 
Name.startswith("__")62.3k
&&
Name.endswith("__")6.12k
)
14
6.11k
    Name = Name.substr(2, Name.size() - 4);
15
16
  // Normalize the scope name, but only for gnu and clang attributes.
17
61.2k
  StringRef ScopeName = Scope ? 
Scope->getName()1.13k
: "";
18
62.3k
  if (ScopeName == "__gnu__")
19
5
    ScopeName = "gnu";
20
62.3k
  else if (ScopeName == "_Clang")
21
8
    ScopeName = "clang";
22
23
62.3k
#include "clang/Basic/AttrHasAttributeImpl.inc"
24
25
15
  return 0;
26
62.3k
}
27
28
137
const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
29
137
  switch (Rule) {
30
0
#define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract)                            \
31
137
  case attr::NAME:                                                             \
32
137
    return SPELLING;
33
0
#include "clang/Basic/AttrSubMatchRulesList.inc"
34
137
  }
35
137
  
llvm_unreachable0
("Invalid subject match rule");
36
137
}
37
38
static StringRef
39
normalizeAttrScopeName(const IdentifierInfo *Scope,
40
78.5M
                       AttributeCommonInfo::Syntax SyntaxUsed) {
41
78.5M
  if (!Scope)
42
78.5M
    return "";
43
44
  // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
45
  // to be "clang".
46
4.52k
  StringRef ScopeName = Scope->getName();
47
4.52k
  if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
48
4.52k
      
SyntaxUsed == AttributeCommonInfo::AS_C2x160
) {
49
4.52k
    if (ScopeName == "__gnu__")
50
8
      ScopeName = "gnu";
51
4.51k
    else if (ScopeName == "_Clang")
52
32
      ScopeName = "clang";
53
4.52k
  }
54
4.52k
  return ScopeName;
55
4.52k
}
56
57
static StringRef normalizeAttrName(const IdentifierInfo *Name,
58
                                   StringRef NormalizedScopeName,
59
78.5M
                                   AttributeCommonInfo::Syntax SyntaxUsed) {
60
  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
61
  // for GNU attributes, and attributes using the double square bracket syntax.
62
78.5M
  bool ShouldNormalize =
63
78.5M
      SyntaxUsed == AttributeCommonInfo::AS_GNU ||
64
4.95M
      ((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
65
4.92M
        SyntaxUsed == AttributeCommonInfo::AS_C2x) &&
66
26.7k
       (NormalizedScopeName.empty() || 
NormalizedScopeName == "gnu"4.52k
||
67
4.12k
        NormalizedScopeName == "clang"));
68
78.5M
  StringRef AttrName = Name->getName();
69
78.5M
  if (ShouldNormalize && 
AttrName.size() >= 473.6M
&&
AttrName.startswith("__")73.6M
&&
70
54.9M
      AttrName.endswith("__"))
71
31.6M
    AttrName = AttrName.slice(2, AttrName.size() - 2);
72
73
78.5M
  return AttrName;
74
78.5M
}
75
76
12.5k
bool AttributeCommonInfo::isGNUScope() const {
77
12.5k
  return ScopeName && 
(581
ScopeName->isStr("gnu")581
||
ScopeName->isStr("__gnu__")435
);
78
12.5k
}
79
80
#include "clang/Sema/AttrParsedAttrKinds.inc"
81
82
static SmallString<64> normalizeName(const IdentifierInfo *Name,
83
                                     const IdentifierInfo *Scope,
84
78.0M
                                     AttributeCommonInfo::Syntax SyntaxUsed) {
85
78.0M
  StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
86
78.0M
  StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
87
88
78.0M
  SmallString<64> FullName = ScopeName;
89
78.0M
  if (!ScopeName.empty()) {
90
3.93k
    assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
91
3.93k
           SyntaxUsed == AttributeCommonInfo::AS_C2x);
92
3.93k
    FullName += "::";
93
3.93k
  }
94
78.0M
  FullName += AttrName;
95
96
78.0M
  return FullName;
97
78.0M
}
98
99
AttributeCommonInfo::Kind
100
AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
101
                                   const IdentifierInfo *ScopeName,
102
78.0M
                                   Syntax SyntaxUsed) {
103
78.0M
  return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
104
78.0M
}
105
106
134
std::string AttributeCommonInfo::getNormalizedFullName() const {
107
134
  return static_cast<std::string>(
108
134
      normalizeName(getAttrName(), getScopeName(), getSyntax()));
109
134
}
110
111
463k
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
112
  // Both variables will be used in tablegen generated
113
  // attribute spell list index matching code.
114
463k
  auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
115
463k
  StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
116
463k
  StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
117
118
463k
#include "clang/Sema/AttrSpellingListIndex.inc"
119
143
}