Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Basic/Attributes.cpp
35232 views
1
//===--- Attributes.cpp ---------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements the AttributeCommonInfo interface.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Basic/Attributes.h"
14
#include "clang/Basic/AttrSubjectMatchRules.h"
15
#include "clang/Basic/IdentifierTable.h"
16
#include "clang/Basic/LangOptions.h"
17
#include "clang/Basic/ParsedAttrInfo.h"
18
#include "clang/Basic/TargetInfo.h"
19
20
using namespace clang;
21
22
static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name,
23
StringRef ScopeName, const TargetInfo &Target,
24
const LangOptions &LangOpts) {
25
26
#include "clang/Basic/AttrHasAttributeImpl.inc"
27
28
return 0;
29
}
30
31
int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
32
const IdentifierInfo *Scope, const IdentifierInfo *Attr,
33
const TargetInfo &Target, const LangOptions &LangOpts) {
34
StringRef Name = Attr->getName();
35
// Normalize the attribute name, __foo__ becomes foo.
36
if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__"))
37
Name = Name.substr(2, Name.size() - 4);
38
39
// Normalize the scope name, but only for gnu and clang attributes.
40
StringRef ScopeName = Scope ? Scope->getName() : "";
41
if (ScopeName == "__gnu__")
42
ScopeName = "gnu";
43
else if (ScopeName == "_Clang")
44
ScopeName = "clang";
45
46
// As a special case, look for the omp::sequence and omp::directive
47
// attributes. We support those, but not through the typical attribute
48
// machinery that goes through TableGen. We support this in all OpenMP modes
49
// so long as double square brackets are enabled.
50
//
51
// Other OpenMP attributes (e.g. [[omp::assume]]) are handled via the
52
// regular attribute parsing machinery.
53
if (LangOpts.OpenMP && ScopeName == "omp" &&
54
(Name == "directive" || Name == "sequence"))
55
return 1;
56
57
int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts);
58
if (res)
59
return res;
60
61
// Check if any plugin provides this attribute.
62
for (auto &Ptr : getAttributePluginInstances())
63
if (Ptr->hasSpelling(Syntax, Name))
64
return 1;
65
66
return 0;
67
}
68
69
const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
70
switch (Rule) {
71
#define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract) \
72
case attr::NAME: \
73
return SPELLING;
74
#include "clang/Basic/AttrSubMatchRulesList.inc"
75
}
76
llvm_unreachable("Invalid subject match rule");
77
}
78
79
static StringRef
80
normalizeAttrScopeName(const IdentifierInfo *Scope,
81
AttributeCommonInfo::Syntax SyntaxUsed) {
82
if (!Scope)
83
return "";
84
85
// Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
86
// to be "clang".
87
StringRef ScopeName = Scope->getName();
88
if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
89
SyntaxUsed == AttributeCommonInfo::AS_C23) {
90
if (ScopeName == "__gnu__")
91
ScopeName = "gnu";
92
else if (ScopeName == "_Clang")
93
ScopeName = "clang";
94
}
95
return ScopeName;
96
}
97
98
static StringRef normalizeAttrName(const IdentifierInfo *Name,
99
StringRef NormalizedScopeName,
100
AttributeCommonInfo::Syntax SyntaxUsed) {
101
// Normalize the attribute name, __foo__ becomes foo. This is only allowable
102
// for GNU attributes, and attributes using the double square bracket syntax.
103
bool ShouldNormalize =
104
SyntaxUsed == AttributeCommonInfo::AS_GNU ||
105
((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
106
SyntaxUsed == AttributeCommonInfo::AS_C23) &&
107
(NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
108
NormalizedScopeName == "clang"));
109
StringRef AttrName = Name->getName();
110
if (ShouldNormalize && AttrName.size() >= 4 && AttrName.starts_with("__") &&
111
AttrName.ends_with("__"))
112
AttrName = AttrName.slice(2, AttrName.size() - 2);
113
114
return AttrName;
115
}
116
117
bool AttributeCommonInfo::isGNUScope() const {
118
return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
119
}
120
121
bool AttributeCommonInfo::isClangScope() const {
122
return ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"));
123
}
124
125
#include "clang/Sema/AttrParsedAttrKinds.inc"
126
127
static SmallString<64> normalizeName(const IdentifierInfo *Name,
128
const IdentifierInfo *Scope,
129
AttributeCommonInfo::Syntax SyntaxUsed) {
130
StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
131
StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
132
133
SmallString<64> FullName = ScopeName;
134
if (!ScopeName.empty()) {
135
assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
136
SyntaxUsed == AttributeCommonInfo::AS_C23);
137
FullName += "::";
138
}
139
FullName += AttrName;
140
141
return FullName;
142
}
143
144
AttributeCommonInfo::Kind
145
AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
146
const IdentifierInfo *ScopeName,
147
Syntax SyntaxUsed) {
148
return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
149
}
150
151
std::string AttributeCommonInfo::getNormalizedFullName() const {
152
return static_cast<std::string>(
153
normalizeName(getAttrName(), getScopeName(), getSyntax()));
154
}
155
156
unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
157
// Both variables will be used in tablegen generated
158
// attribute spell list index matching code.
159
auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
160
StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
161
StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
162
163
#include "clang/Sema/AttrSpellingListIndex.inc"
164
}
165
166