Coverage Report

Created: 2020-09-19 12:23

/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
119k
                        const LangOptions &LangOpts) {
11
119k
  StringRef Name = Attr->getName();
12
  // Normalize the attribute name, __foo__ becomes foo.
13
119k
  if (Name.size() >= 4 && 
Name.startswith("__")119k
&&
Name.endswith("__")11.7k
)
14
11.7k
    Name = Name.substr(2, Name.size() - 4);
15
119k
16
  // Normalize the scope name, but only for gnu and clang attributes.
17
117k
  StringRef ScopeName = Scope ? 
Scope->getName()1.88k
: "";
18
119k
  if (ScopeName == "__gnu__")
19
5
    ScopeName = "gnu";
20
119k
  else if (ScopeName == "_Clang")
21
8
    ScopeName = "clang";
22
119k
23
119k
#include "clang/Basic/AttrHasAttributeImpl.inc"
24
119k
25
15
  return 0;
26
119k
}
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
77.5M
                       AttributeCommonInfo::Syntax SyntaxUsed) {
41
77.5M
  if (!Scope)
42
77.5M
    return "";
43
4.19k
44
  // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
45
  // to be "clang".
46
4.19k
  StringRef ScopeName = Scope->getName();
47
4.19k
  if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
48
4.19k
      
SyntaxUsed == AttributeCommonInfo::AS_C2x160
) {
49
4.19k
    if (ScopeName == "__gnu__")
50
8
      ScopeName = "gnu";
51
4.19k
    else if (ScopeName == "_Clang")
52
32
      ScopeName = "clang";
53
4.19k
  }
54
4.19k
  return ScopeName;
55
4.19k
}
56
57
static StringRef normalizeAttrName(const IdentifierInfo *Name,
58
                                   StringRef NormalizedScopeName,
59
77.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
77.5M
  bool ShouldNormalize =
63
77.5M
      SyntaxUsed == AttributeCommonInfo::AS_GNU ||
64
4.95M
      ((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
65
4.92M
        SyntaxUsed == AttributeCommonInfo::AS_C2x) &&
66
25.4k
       (NormalizedScopeName.empty() || 
NormalizedScopeName == "gnu"4.19k
||
67
3.79k
        NormalizedScopeName == "clang"));
68
77.5M
  StringRef AttrName = Name->getName();
69
77.5M
  if (ShouldNormalize && 
AttrName.size() >= 472.5M
&&
AttrName.startswith("__")72.5M
&&
70
53.8M
      AttrName.endswith("__"))
71
30.9M
    AttrName = AttrName.slice(2, AttrName.size() - 2);
72
77.5M
73
77.5M
  return AttrName;
74
77.5M
}
75
76
12.0k
bool AttributeCommonInfo::isGNUScope() const {
77
12.0k
  return ScopeName && 
(539
ScopeName->isStr("gnu")539
||
ScopeName->isStr("__gnu__")393
);
78
12.0k
}
79
80
#include "clang/Sema/AttrParsedAttrKinds.inc"
81
82
static SmallString<64> normalizeName(const IdentifierInfo *Name,
83
                                     const IdentifierInfo *Scope,
84
77.0M
                                     AttributeCommonInfo::Syntax SyntaxUsed) {
85
77.0M
  StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
86
77.0M
  StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
87
77.0M
88
77.0M
  SmallString<64> FullName = ScopeName;
89
77.0M
  if (!ScopeName.empty()) {
90
3.63k
    assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
91
3.63k
           SyntaxUsed == AttributeCommonInfo::AS_C2x);
92
3.63k
    FullName += "::";
93
3.63k
  }
94
77.0M
  FullName += AttrName;
95
77.0M
96
77.0M
  return FullName;
97
77.0M
}
98
99
AttributeCommonInfo::Kind
100
AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
101
                                   const IdentifierInfo *ScopeName,
102
77.0M
                                   Syntax SyntaxUsed) {
103
77.0M
  return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
104
77.0M
}
105
106
440
std::string AttributeCommonInfo::getNormalizedFullName() const {
107
440
  return static_cast<std::string>(
108
440
      normalizeName(getAttrName(), getScopeName(), getSyntax()));
109
440
}
110
111
458k
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
112
  // Both variables will be used in tablegen generated
113
  // attribute spell list index matching code.
114
458k
  auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
115
458k
  StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
116
458k
  StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
117
458k
118
458k
#include "clang/Sema/AttrSpellingListIndex.inc"
119
}