Attributes.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
  8. const IdentifierInfo *Attr, const TargetInfo &Target,
  9. const LangOptions &LangOpts) {
  10. StringRef Name = Attr->getName();
  11. // Normalize the attribute name, __foo__ becomes foo.
  12. if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
  13. Name = Name.substr(2, Name.size() - 4);
  14. // Normalize the scope name, but only for gnu and clang attributes.
  15. StringRef ScopeName = Scope ? Scope->getName() : "";
  16. if (ScopeName == "__gnu__")
  17. ScopeName = "gnu";
  18. else if (ScopeName == "_Clang")
  19. ScopeName = "clang";
  20. #include "clang/Basic/AttrHasAttributeImpl.inc"
  21. return 0;
  22. }
  23. const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
  24. switch (Rule) {
  25. #define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract) \
  26. case attr::NAME: \
  27. return SPELLING;
  28. #include "clang/Basic/AttrSubMatchRulesList.inc"
  29. }
  30. llvm_unreachable("Invalid subject match rule");
  31. }
  32. static StringRef
  33. normalizeAttrScopeName(StringRef ScopeName,
  34. AttributeCommonInfo::Syntax SyntaxUsed) {
  35. // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
  36. // to be "clang".
  37. if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
  38. SyntaxUsed == AttributeCommonInfo::AS_C2x) {
  39. if (ScopeName == "__gnu__")
  40. ScopeName = "gnu";
  41. else if (ScopeName == "_Clang")
  42. ScopeName = "clang";
  43. }
  44. return ScopeName;
  45. }
  46. static StringRef normalizeAttrName(StringRef AttrName,
  47. StringRef NormalizedScopeName,
  48. AttributeCommonInfo::Syntax SyntaxUsed) {
  49. // Normalize the attribute name, __foo__ becomes foo. This is only allowable
  50. // for GNU attributes, and attributes using the double square bracket syntax.
  51. bool ShouldNormalize =
  52. SyntaxUsed == AttributeCommonInfo::AS_GNU ||
  53. ((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
  54. SyntaxUsed == AttributeCommonInfo::AS_C2x) &&
  55. (NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
  56. NormalizedScopeName == "clang"));
  57. if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") &&
  58. AttrName.endswith("__"))
  59. AttrName = AttrName.slice(2, AttrName.size() - 2);
  60. return AttrName;
  61. }
  62. bool AttributeCommonInfo::isGNUScope() const {
  63. return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
  64. }
  65. #include "clang/Sema/AttrParsedAttrKinds.inc"
  66. AttributeCommonInfo::Kind
  67. AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
  68. const IdentifierInfo *ScopeName,
  69. Syntax SyntaxUsed) {
  70. StringRef AttrName = Name->getName();
  71. SmallString<64> FullName;
  72. if (ScopeName)
  73. FullName += normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed);
  74. AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
  75. // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
  76. // unscoped.
  77. if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
  78. FullName += "::";
  79. FullName += AttrName;
  80. return ::getAttrKind(FullName, SyntaxUsed);
  81. }
  82. unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
  83. // Both variables will be used in tablegen generated
  84. // attribute spell list index matching code.
  85. auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
  86. StringRef Scope =
  87. getScopeName() ? normalizeAttrScopeName(getScopeName()->getName(), Syntax)
  88. : "";
  89. StringRef Name = normalizeAttrName(getAttrName()->getName(), Scope, Syntax);
  90. #include "clang/Sema/AttrSpellingListIndex.inc"
  91. }