clang  19.0.0git
Attributes.cpp
Go to the documentation of this file.
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"
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 
32  const IdentifierInfo *Attr, const TargetInfo &Target,
33  const LangOptions &LangOpts) {
34  StringRef ScopeName = Scope ? Scope->getName() : "";
35  StringRef Name = Attr->getName();
36  // Normalize the attribute name, __foo__ becomes foo.
37  // FIXME: Normalization does not work correctly for attributes in
38  // __sycl_detail__ namespace. Should normalization work for
39  // attributes not in gnu and clang namespace?
40  if (ScopeName != "__sycl_detail__" && Name.size() >= 4 &&
41  Name.starts_with("__") && Name.ends_with("__"))
42  Name = Name.substr(2, Name.size() - 4);
43 
44  // Normalize the scope name, but only for gnu and clang attributes.
45  if (ScopeName == "__gnu__")
46  ScopeName = "gnu";
47  else if (ScopeName == "_Clang")
48  ScopeName = "clang";
49 
50  // As a special case, look for the omp::sequence and omp::directive
51  // attributes. We support those, but not through the typical attribute
52  // machinery that goes through TableGen. We support this in all OpenMP modes
53  // so long as double square brackets are enabled.
54  //
55  // Other OpenMP attributes (e.g. [[omp::assume]]) are handled via the
56  // regular attribute parsing machinery.
57  if (LangOpts.OpenMP && ScopeName == "omp" &&
58  (Name == "directive" || Name == "sequence"))
59  return 1;
60 
61  int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts);
62  if (res)
63  return res;
64 
65  // Check if any plugin provides this attribute.
66  for (auto &Ptr : getAttributePluginInstances())
67  if (Ptr->hasSpelling(Syntax, Name))
68  return 1;
69 
70  return 0;
71 }
72 
74  switch (Rule) {
75 #define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract) \
76  case attr::NAME: \
77  return SPELLING;
78 #include "clang/Basic/AttrSubMatchRulesList.inc"
79  }
80  llvm_unreachable("Invalid subject match rule");
81 }
82 
83 static StringRef
85  AttributeCommonInfo::Syntax SyntaxUsed) {
86  if (!Scope)
87  return "";
88 
89  // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
90  // to be "clang".
91  StringRef ScopeName = Scope->getName();
92  if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
93  SyntaxUsed == AttributeCommonInfo::AS_C23) {
94  if (ScopeName == "__gnu__")
95  ScopeName = "gnu";
96  else if (ScopeName == "_Clang")
97  ScopeName = "clang";
98  }
99  return ScopeName;
100 }
101 
102 static StringRef normalizeAttrName(const IdentifierInfo *Name,
103  StringRef NormalizedScopeName,
104  AttributeCommonInfo::Syntax SyntaxUsed) {
105  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
106  // for GNU attributes, and attributes using the double square bracket syntax.
107  bool ShouldNormalize =
108  SyntaxUsed == AttributeCommonInfo::AS_GNU ||
109  ((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
110  SyntaxUsed == AttributeCommonInfo::AS_C23) &&
111  (NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
112  NormalizedScopeName == "clang"));
113  StringRef AttrName = Name->getName();
114  if (ShouldNormalize && AttrName.size() >= 4 && AttrName.starts_with("__") &&
115  AttrName.ends_with("__"))
116  AttrName = AttrName.slice(2, AttrName.size() - 2);
117 
118  return AttrName;
119 }
120 
122  return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
123 }
124 
126  return ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"));
127 }
128 
129 #include "clang/Sema/AttrParsedAttrKinds.inc"
130 
132  const IdentifierInfo *Scope,
133  AttributeCommonInfo::Syntax SyntaxUsed) {
134  StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
135  StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
136 
137  SmallString<64> FullName = ScopeName;
138  if (!ScopeName.empty()) {
139  assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
140  SyntaxUsed == AttributeCommonInfo::AS_C23);
141  FullName += "::";
142  }
143  FullName += AttrName;
144 
145  return FullName;
146 }
147 
150  const IdentifierInfo *ScopeName,
151  Syntax SyntaxUsed) {
152  return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
153 }
154 
156  return static_cast<std::string>(
158 }
159 
160 unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
161  // Both variables will be used in tablegen generated
162  // attribute spell list index matching code.
163  auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
165  StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
166 
167 #include "clang/Sema/AttrSpellingListIndex.inc"
168 }
static SmallString< 64 > normalizeName(const IdentifierInfo *Name, const IdentifierInfo *Scope, AttributeCommonInfo::Syntax SyntaxUsed)
Definition: Attributes.cpp:131
static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name, StringRef ScopeName, const TargetInfo &Target, const LangOptions &LangOpts)
Definition: Attributes.cpp:22
static StringRef normalizeAttrScopeName(const IdentifierInfo *Scope, AttributeCommonInfo::Syntax SyntaxUsed)
Definition: Attributes.cpp:84
static StringRef normalizeAttrName(const IdentifierInfo *Name, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
Definition: Attributes.cpp:102
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Definition: MachO.h:50
Attr - This represents one attribute.
Definition: Attr.h:46
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
Definition: Attributes.cpp:155
Syntax
The style used to specify an attribute.
const IdentifierInfo * getAttrName() const
const IdentifierInfo * getScopeName() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
Exposes information about the current target.
Definition: TargetInfo.h:218
Defines the clang::TargetInfo interface.
SubjectMatchRule
A list of all the recognized kinds of attributes.
const char * getSubjectMatchRuleSpelling(SubjectMatchRule Rule)
Definition: Attributes.cpp:73
The JSON file list parser is used to communicate input to InstallAPI.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
Definition: Attributes.cpp:31
const std::list< std::unique_ptr< ParsedAttrInfo > > & getAttributePluginInstances()