12fbf9942SAaron Ballman #include "clang/Basic/Attributes.h"
29e7bf161SAlex Lorenz #include "clang/Basic/AttrSubjectMatchRules.h"
3b79f3319SErich Keane #include "clang/Basic/AttributeCommonInfo.h"
42fbf9942SAaron Ballman #include "clang/Basic/IdentifierTable.h"
52fbf9942SAaron Ballman #include "llvm/ADT/StringSwitch.h"
62fbf9942SAaron Ballman using namespace clang;
72fbf9942SAaron Ballman
hasAttribute(AttributeCommonInfo::Syntax Syntax,const IdentifierInfo * Scope,const IdentifierInfo * Attr,const TargetInfo & Target,const LangOptions & LangOpts)8*dd6bcdbfSLeonard Grey int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
9*dd6bcdbfSLeonard Grey const IdentifierInfo *Scope, const IdentifierInfo *Attr,
10*dd6bcdbfSLeonard Grey const TargetInfo &Target, const LangOptions &LangOpts) {
112fbf9942SAaron Ballman StringRef Name = Attr->getName();
122fbf9942SAaron Ballman // Normalize the attribute name, __foo__ becomes foo.
132fbf9942SAaron Ballman if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
142fbf9942SAaron Ballman Name = Name.substr(2, Name.size() - 4);
152fbf9942SAaron Ballman
16c44c1742SAaron Ballman // Normalize the scope name, but only for gnu and clang attributes.
17ad672ffbSAaron Ballman StringRef ScopeName = Scope ? Scope->getName() : "";
18ad672ffbSAaron Ballman if (ScopeName == "__gnu__")
19c44c1742SAaron Ballman ScopeName = "gnu";
20c44c1742SAaron Ballman else if (ScopeName == "_Clang")
21c44c1742SAaron Ballman ScopeName = "clang";
22ad672ffbSAaron Ballman
23de59f564SAaron Ballman // As a special case, look for the omp::sequence and omp::directive
24de59f564SAaron Ballman // attributes. We support those, but not through the typical attribute
25de59f564SAaron Ballman // machinery that goes through TableGen. We support this in all OpenMP modes
26de59f564SAaron Ballman // so long as double square brackets are enabled.
27de59f564SAaron Ballman if (LangOpts.OpenMP && LangOpts.DoubleSquareBracketAttributes &&
28de59f564SAaron Ballman ScopeName == "omp")
29de59f564SAaron Ballman return (Name == "directive" || Name == "sequence") ? 1 : 0;
30de59f564SAaron Ballman
312fbf9942SAaron Ballman #include "clang/Basic/AttrHasAttributeImpl.inc"
322fbf9942SAaron Ballman
33a0344c5dSAaron Ballman return 0;
342fbf9942SAaron Ballman }
359e7bf161SAlex Lorenz
getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule)369e7bf161SAlex Lorenz const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
379e7bf161SAlex Lorenz switch (Rule) {
389e7bf161SAlex Lorenz #define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract) \
399e7bf161SAlex Lorenz case attr::NAME: \
409e7bf161SAlex Lorenz return SPELLING;
419e7bf161SAlex Lorenz #include "clang/Basic/AttrSubMatchRulesList.inc"
429e7bf161SAlex Lorenz }
439e7bf161SAlex Lorenz llvm_unreachable("Invalid subject match rule");
449e7bf161SAlex Lorenz }
45b79f3319SErich Keane
46b79f3319SErich Keane static StringRef
normalizeAttrScopeName(const IdentifierInfo * Scope,AttributeCommonInfo::Syntax SyntaxUsed)4775d4d4bdSJohn Brawn normalizeAttrScopeName(const IdentifierInfo *Scope,
48b79f3319SErich Keane AttributeCommonInfo::Syntax SyntaxUsed) {
4975d4d4bdSJohn Brawn if (!Scope)
5075d4d4bdSJohn Brawn return "";
5175d4d4bdSJohn Brawn
52b79f3319SErich Keane // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
53b79f3319SErich Keane // to be "clang".
5475d4d4bdSJohn Brawn StringRef ScopeName = Scope->getName();
55b79f3319SErich Keane if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
56b79f3319SErich Keane SyntaxUsed == AttributeCommonInfo::AS_C2x) {
57b79f3319SErich Keane if (ScopeName == "__gnu__")
58b79f3319SErich Keane ScopeName = "gnu";
59b79f3319SErich Keane else if (ScopeName == "_Clang")
60b79f3319SErich Keane ScopeName = "clang";
61b79f3319SErich Keane }
62b79f3319SErich Keane return ScopeName;
63b79f3319SErich Keane }
64b79f3319SErich Keane
normalizeAttrName(const IdentifierInfo * Name,StringRef NormalizedScopeName,AttributeCommonInfo::Syntax SyntaxUsed)6575d4d4bdSJohn Brawn static StringRef normalizeAttrName(const IdentifierInfo *Name,
66b79f3319SErich Keane StringRef NormalizedScopeName,
67b79f3319SErich Keane AttributeCommonInfo::Syntax SyntaxUsed) {
68b79f3319SErich Keane // Normalize the attribute name, __foo__ becomes foo. This is only allowable
69b79f3319SErich Keane // for GNU attributes, and attributes using the double square bracket syntax.
70b79f3319SErich Keane bool ShouldNormalize =
71b79f3319SErich Keane SyntaxUsed == AttributeCommonInfo::AS_GNU ||
72b79f3319SErich Keane ((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
73b79f3319SErich Keane SyntaxUsed == AttributeCommonInfo::AS_C2x) &&
74b79f3319SErich Keane (NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
75b79f3319SErich Keane NormalizedScopeName == "clang"));
7675d4d4bdSJohn Brawn StringRef AttrName = Name->getName();
77b79f3319SErich Keane if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") &&
78b79f3319SErich Keane AttrName.endswith("__"))
79b79f3319SErich Keane AttrName = AttrName.slice(2, AttrName.size() - 2);
80b79f3319SErich Keane
81b79f3319SErich Keane return AttrName;
82b79f3319SErich Keane }
83b79f3319SErich Keane
isGNUScope() const84b79f3319SErich Keane bool AttributeCommonInfo::isGNUScope() const {
85b79f3319SErich Keane return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
86b79f3319SErich Keane }
87b79f3319SErich Keane
isClangScope() const88cb08f4aaSDavid Blaikie bool AttributeCommonInfo::isClangScope() const {
89cb08f4aaSDavid Blaikie return ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"));
90cb08f4aaSDavid Blaikie }
91cb08f4aaSDavid Blaikie
92b79f3319SErich Keane #include "clang/Sema/AttrParsedAttrKinds.inc"
93b79f3319SErich Keane
normalizeName(const IdentifierInfo * Name,const IdentifierInfo * Scope,AttributeCommonInfo::Syntax SyntaxUsed)9475d4d4bdSJohn Brawn static SmallString<64> normalizeName(const IdentifierInfo *Name,
9575d4d4bdSJohn Brawn const IdentifierInfo *Scope,
9675d4d4bdSJohn Brawn AttributeCommonInfo::Syntax SyntaxUsed) {
9775d4d4bdSJohn Brawn StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
9875d4d4bdSJohn Brawn StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
9975d4d4bdSJohn Brawn
10075d4d4bdSJohn Brawn SmallString<64> FullName = ScopeName;
101bc3f1710SJohn Brawn if (!ScopeName.empty()) {
102bc3f1710SJohn Brawn assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
103c278e8f8SHans Wennborg SyntaxUsed == AttributeCommonInfo::AS_C2x);
10475d4d4bdSJohn Brawn FullName += "::";
105bc3f1710SJohn Brawn }
10675d4d4bdSJohn Brawn FullName += AttrName;
10775d4d4bdSJohn Brawn
10875d4d4bdSJohn Brawn return FullName;
10975d4d4bdSJohn Brawn }
11075d4d4bdSJohn Brawn
111b79f3319SErich Keane AttributeCommonInfo::Kind
getParsedKind(const IdentifierInfo * Name,const IdentifierInfo * ScopeName,Syntax SyntaxUsed)112b79f3319SErich Keane AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
113b79f3319SErich Keane const IdentifierInfo *ScopeName,
114b79f3319SErich Keane Syntax SyntaxUsed) {
11575d4d4bdSJohn Brawn return ::getAttrKind(normalizeName(Name, ScopeName, SyntaxUsed), SyntaxUsed);
11675d4d4bdSJohn Brawn }
117b79f3319SErich Keane
getNormalizedFullName() const11875d4d4bdSJohn Brawn std::string AttributeCommonInfo::getNormalizedFullName() const {
11975d4d4bdSJohn Brawn return static_cast<std::string>(
12075d4d4bdSJohn Brawn normalizeName(getAttrName(), getScopeName(), getSyntax()));
121b79f3319SErich Keane }
122b79f3319SErich Keane
calculateAttributeSpellingListIndex() const123b79f3319SErich Keane unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
124b79f3319SErich Keane // Both variables will be used in tablegen generated
125b79f3319SErich Keane // attribute spell list index matching code.
126b79f3319SErich Keane auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
12775d4d4bdSJohn Brawn StringRef Scope = normalizeAttrScopeName(getScopeName(), Syntax);
12875d4d4bdSJohn Brawn StringRef Name = normalizeAttrName(getAttrName(), Scope, Syntax);
129b79f3319SErich Keane
130b79f3319SErich Keane #include "clang/Sema/AttrSpellingListIndex.inc"
131b79f3319SErich Keane }
132