Mercurial > hg > CbC > CbC_llvm
view clang/lib/AST/Linkage.h @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | 1f2b6ac9f198 |
children |
line wrap: on
line source
//===----- 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/PointerIntPair.h" #include <optional> 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()); } std::optional<LinkageInfo> lookup(const NamedDecl *ND, LVComputationKind Kind) const { auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind)); if (Iter == CachedLinkageInfo.end()) return std::nullopt; 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