123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- //===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file provides AST-internal utilities for linkage and visibility
- // calculation.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_LIB_AST_LINKAGE_H
- #define LLVM_CLANG_LIB_AST_LINKAGE_H
- #include "clang/AST/ASTFwd.h"
- #include "clang/AST/Decl.h"
- #include "clang/AST/DeclCXX.h"
- #include "clang/AST/Type.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/Optional.h"
- #include "llvm/ADT/PointerIntPair.h"
- namespace clang {
- /// Kinds of LV computation. The linkage side of the computation is
- /// always the same, but different things can change how visibility is
- /// computed.
- struct LVComputationKind {
- /// The kind of entity whose visibility is ultimately being computed;
- /// visibility computations for types and non-types follow different rules.
- unsigned ExplicitKind : 1;
- /// Whether explicit visibility attributes should be ignored. When set,
- /// visibility may only be restricted by the visibility of template arguments.
- unsigned IgnoreExplicitVisibility : 1;
- /// Whether all visibility should be ignored. When set, we're only interested
- /// in computing linkage.
- unsigned IgnoreAllVisibility : 1;
- enum { NumLVComputationKindBits = 3 };
- explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
- : ExplicitKind(EK), IgnoreExplicitVisibility(false),
- IgnoreAllVisibility(false) {}
- NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
- return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
- }
- bool isTypeVisibility() const {
- return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
- }
- bool isValueVisibility() const {
- return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
- }
- /// Do an LV computation when we only care about the linkage.
- static LVComputationKind forLinkageOnly() {
- LVComputationKind Result(NamedDecl::VisibilityForValue);
- Result.IgnoreExplicitVisibility = true;
- Result.IgnoreAllVisibility = true;
- return Result;
- }
- unsigned toBits() {
- unsigned Bits = 0;
- Bits = (Bits << 1) | ExplicitKind;
- Bits = (Bits << 1) | IgnoreExplicitVisibility;
- Bits = (Bits << 1) | IgnoreAllVisibility;
- return Bits;
- }
- };
- class LinkageComputer {
- // We have a cache for repeated linkage/visibility computations. This saves us
- // from exponential behavior in heavily templated code, such as:
- //
- // template <typename T, typename V> struct {};
- // using A = int;
- // using B = Foo<A, A>;
- // using C = Foo<B, B>;
- // using D = Foo<C, C>;
- //
- // The integer represents an LVComputationKind.
- using QueryType =
- llvm::PointerIntPair<const NamedDecl *,
- LVComputationKind::NumLVComputationKindBits>;
- llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
- static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
- return QueryType(ND, Kind.toBits());
- }
- llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
- LVComputationKind Kind) const {
- auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
- if (Iter == CachedLinkageInfo.end())
- return None;
- return Iter->second;
- }
- void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
- CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
- }
- LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
- LVComputationKind computation);
- LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
- LVComputationKind computation);
- void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
- const FunctionTemplateSpecializationInfo *specInfo,
- LVComputationKind computation);
- void mergeTemplateLV(LinkageInfo &LV,
- const ClassTemplateSpecializationDecl *spec,
- LVComputationKind computation);
- void mergeTemplateLV(LinkageInfo &LV,
- const VarTemplateSpecializationDecl *spec,
- LVComputationKind computation);
- LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
- LVComputationKind computation,
- bool IgnoreVarTypeLinkage);
- LinkageInfo getLVForClassMember(const NamedDecl *D,
- LVComputationKind computation,
- bool IgnoreVarTypeLinkage);
- LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
- LVComputationKind computation);
- LinkageInfo getLVForLocalDecl(const NamedDecl *D,
- LVComputationKind computation);
- LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
- LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
- LVComputationKind computation);
- LinkageInfo getLVForValue(const APValue &V, LVComputationKind computation);
- public:
- LinkageInfo computeLVForDecl(const NamedDecl *D,
- LVComputationKind computation,
- bool IgnoreVarTypeLinkage = false);
- LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
- LinkageInfo computeTypeLinkageInfo(const Type *T);
- LinkageInfo computeTypeLinkageInfo(QualType T) {
- return computeTypeLinkageInfo(T.getTypePtr());
- }
- LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
- LinkageInfo getTypeLinkageAndVisibility(const Type *T);
- LinkageInfo getTypeLinkageAndVisibility(QualType T) {
- return getTypeLinkageAndVisibility(T.getTypePtr());
- }
- };
- } // namespace clang
- #endif
|