Linkage.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//
  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 provides AST-internal utilities for linkage and visibility
  10. // calculation.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_CLANG_LIB_AST_LINKAGE_H
  14. #define LLVM_CLANG_LIB_AST_LINKAGE_H
  15. #include "clang/AST/ASTFwd.h"
  16. #include "clang/AST/Decl.h"
  17. #include "clang/AST/DeclCXX.h"
  18. #include "clang/AST/Type.h"
  19. #include "llvm/ADT/DenseMap.h"
  20. #include "llvm/ADT/PointerIntPair.h"
  21. #include <optional>
  22. namespace clang {
  23. /// Kinds of LV computation. The linkage side of the computation is
  24. /// always the same, but different things can change how visibility is
  25. /// computed.
  26. struct LVComputationKind {
  27. /// The kind of entity whose visibility is ultimately being computed;
  28. /// visibility computations for types and non-types follow different rules.
  29. unsigned ExplicitKind : 1;
  30. /// Whether explicit visibility attributes should be ignored. When set,
  31. /// visibility may only be restricted by the visibility of template arguments.
  32. unsigned IgnoreExplicitVisibility : 1;
  33. /// Whether all visibility should be ignored. When set, we're only interested
  34. /// in computing linkage.
  35. unsigned IgnoreAllVisibility : 1;
  36. enum { NumLVComputationKindBits = 3 };
  37. explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
  38. : ExplicitKind(EK), IgnoreExplicitVisibility(false),
  39. IgnoreAllVisibility(false) {}
  40. NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
  41. return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
  42. }
  43. bool isTypeVisibility() const {
  44. return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
  45. }
  46. bool isValueVisibility() const {
  47. return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
  48. }
  49. /// Do an LV computation when we only care about the linkage.
  50. static LVComputationKind forLinkageOnly() {
  51. LVComputationKind Result(NamedDecl::VisibilityForValue);
  52. Result.IgnoreExplicitVisibility = true;
  53. Result.IgnoreAllVisibility = true;
  54. return Result;
  55. }
  56. unsigned toBits() {
  57. unsigned Bits = 0;
  58. Bits = (Bits << 1) | ExplicitKind;
  59. Bits = (Bits << 1) | IgnoreExplicitVisibility;
  60. Bits = (Bits << 1) | IgnoreAllVisibility;
  61. return Bits;
  62. }
  63. };
  64. class LinkageComputer {
  65. // We have a cache for repeated linkage/visibility computations. This saves us
  66. // from exponential behavior in heavily templated code, such as:
  67. //
  68. // template <typename T, typename V> struct {};
  69. // using A = int;
  70. // using B = Foo<A, A>;
  71. // using C = Foo<B, B>;
  72. // using D = Foo<C, C>;
  73. //
  74. // The integer represents an LVComputationKind.
  75. using QueryType =
  76. llvm::PointerIntPair<const NamedDecl *,
  77. LVComputationKind::NumLVComputationKindBits>;
  78. llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
  79. static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
  80. return QueryType(ND, Kind.toBits());
  81. }
  82. std::optional<LinkageInfo> lookup(const NamedDecl *ND,
  83. LVComputationKind Kind) const {
  84. auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
  85. if (Iter == CachedLinkageInfo.end())
  86. return std::nullopt;
  87. return Iter->second;
  88. }
  89. void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
  90. CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
  91. }
  92. LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
  93. LVComputationKind computation);
  94. LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
  95. LVComputationKind computation);
  96. void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
  97. const FunctionTemplateSpecializationInfo *specInfo,
  98. LVComputationKind computation);
  99. void mergeTemplateLV(LinkageInfo &LV,
  100. const ClassTemplateSpecializationDecl *spec,
  101. LVComputationKind computation);
  102. void mergeTemplateLV(LinkageInfo &LV,
  103. const VarTemplateSpecializationDecl *spec,
  104. LVComputationKind computation);
  105. LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
  106. LVComputationKind computation,
  107. bool IgnoreVarTypeLinkage);
  108. LinkageInfo getLVForClassMember(const NamedDecl *D,
  109. LVComputationKind computation,
  110. bool IgnoreVarTypeLinkage);
  111. LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
  112. LVComputationKind computation);
  113. LinkageInfo getLVForLocalDecl(const NamedDecl *D,
  114. LVComputationKind computation);
  115. LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
  116. LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
  117. LVComputationKind computation);
  118. LinkageInfo getLVForValue(const APValue &V, LVComputationKind computation);
  119. public:
  120. LinkageInfo computeLVForDecl(const NamedDecl *D,
  121. LVComputationKind computation,
  122. bool IgnoreVarTypeLinkage = false);
  123. LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
  124. LinkageInfo computeTypeLinkageInfo(const Type *T);
  125. LinkageInfo computeTypeLinkageInfo(QualType T) {
  126. return computeTypeLinkageInfo(T.getTypePtr());
  127. }
  128. LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
  129. LinkageInfo getTypeLinkageAndVisibility(const Type *T);
  130. LinkageInfo getTypeLinkageAndVisibility(QualType T) {
  131. return getTypeLinkageAndVisibility(T.getTypePtr());
  132. }
  133. };
  134. } // namespace clang
  135. #endif