Linkage.h 6.0 KB

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