1*0b57cec5SDimitry Andric //===- ASTCommon.h - Common stuff for ASTReader/ASTWriter -*- C++ -*-=========//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file defines common functions that both ASTReader and ASTWriter use.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_SERIALIZATION_ASTCOMMON_H
14*0b57cec5SDimitry Andric #define LLVM_CLANG_LIB_SERIALIZATION_ASTCOMMON_H
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
17*0b57cec5SDimitry Andric #include "clang/AST/DeclFriend.h"
18*0b57cec5SDimitry Andric #include "clang/Serialization/ASTBitCodes.h"
19*0b57cec5SDimitry Andric
20*0b57cec5SDimitry Andric namespace clang {
21*0b57cec5SDimitry Andric
22*0b57cec5SDimitry Andric namespace serialization {
23*0b57cec5SDimitry Andric
24*0b57cec5SDimitry Andric enum DeclUpdateKind {
25*0b57cec5SDimitry Andric UPD_CXX_ADDED_IMPLICIT_MEMBER,
26*0b57cec5SDimitry Andric UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
27*0b57cec5SDimitry Andric UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
28*0b57cec5SDimitry Andric UPD_CXX_ADDED_FUNCTION_DEFINITION,
29*0b57cec5SDimitry Andric UPD_CXX_ADDED_VAR_DEFINITION,
30*0b57cec5SDimitry Andric UPD_CXX_POINT_OF_INSTANTIATION,
31*0b57cec5SDimitry Andric UPD_CXX_INSTANTIATED_CLASS_DEFINITION,
32*0b57cec5SDimitry Andric UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT,
33*0b57cec5SDimitry Andric UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER,
34*0b57cec5SDimitry Andric UPD_CXX_RESOLVED_DTOR_DELETE,
35*0b57cec5SDimitry Andric UPD_CXX_RESOLVED_EXCEPTION_SPEC,
36*0b57cec5SDimitry Andric UPD_CXX_DEDUCED_RETURN_TYPE,
37*0b57cec5SDimitry Andric UPD_DECL_MARKED_USED,
38*0b57cec5SDimitry Andric UPD_MANGLING_NUMBER,
39*0b57cec5SDimitry Andric UPD_STATIC_LOCAL_NUMBER,
40*0b57cec5SDimitry Andric UPD_DECL_MARKED_OPENMP_THREADPRIVATE,
41*0b57cec5SDimitry Andric UPD_DECL_MARKED_OPENMP_ALLOCATE,
42*0b57cec5SDimitry Andric UPD_DECL_MARKED_OPENMP_DECLARETARGET,
43*0b57cec5SDimitry Andric UPD_DECL_EXPORTED,
44*0b57cec5SDimitry Andric UPD_ADDED_ATTR_TO_RECORD
45*0b57cec5SDimitry Andric };
46*0b57cec5SDimitry Andric
47*0b57cec5SDimitry Andric TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
48*0b57cec5SDimitry Andric
49*0b57cec5SDimitry Andric unsigned ComputeHash(Selector Sel);
50*0b57cec5SDimitry Andric
51*0b57cec5SDimitry Andric /// Retrieve the "definitive" declaration that provides all of the
52*0b57cec5SDimitry Andric /// visible entries for the given declaration context, if there is one.
53*0b57cec5SDimitry Andric ///
54*0b57cec5SDimitry Andric /// The "definitive" declaration is the only place where we need to look to
55*0b57cec5SDimitry Andric /// find information about the declarations within the given declaration
56*0b57cec5SDimitry Andric /// context. For example, C++ and Objective-C classes, C structs/unions, and
57*0b57cec5SDimitry Andric /// Objective-C protocols, categories, and extensions are all defined in a
58*0b57cec5SDimitry Andric /// single place in the source code, so they have definitive declarations
59*0b57cec5SDimitry Andric /// associated with them. C++ namespaces, on the other hand, can have
60*0b57cec5SDimitry Andric /// multiple definitions.
61*0b57cec5SDimitry Andric const DeclContext *getDefinitiveDeclContext(const DeclContext *DC);
62*0b57cec5SDimitry Andric
63*0b57cec5SDimitry Andric /// Determine whether the given declaration kind is redeclarable.
64*0b57cec5SDimitry Andric bool isRedeclarableDeclKind(unsigned Kind);
65*0b57cec5SDimitry Andric
66*0b57cec5SDimitry Andric /// Determine whether the given declaration needs an anonymous
67*0b57cec5SDimitry Andric /// declaration number.
68*0b57cec5SDimitry Andric bool needsAnonymousDeclarationNumber(const NamedDecl *D);
69*0b57cec5SDimitry Andric
70*0b57cec5SDimitry Andric /// Visit each declaration within \c DC that needs an anonymous
71*0b57cec5SDimitry Andric /// declaration number and call \p Visit with the declaration and its number.
numberAnonymousDeclsWithin(const DeclContext * DC,Fn Visit)72*0b57cec5SDimitry Andric template<typename Fn> void numberAnonymousDeclsWithin(const DeclContext *DC,
73*0b57cec5SDimitry Andric Fn Visit) {
74*0b57cec5SDimitry Andric unsigned Index = 0;
75*0b57cec5SDimitry Andric for (Decl *LexicalD : DC->decls()) {
76*0b57cec5SDimitry Andric // For a friend decl, we care about the declaration within it, if any.
77*0b57cec5SDimitry Andric if (auto *FD = dyn_cast<FriendDecl>(LexicalD))
78*0b57cec5SDimitry Andric LexicalD = FD->getFriendDecl();
79*0b57cec5SDimitry Andric
80*0b57cec5SDimitry Andric auto *ND = dyn_cast_or_null<NamedDecl>(LexicalD);
81*0b57cec5SDimitry Andric if (!ND || !needsAnonymousDeclarationNumber(ND))
82*0b57cec5SDimitry Andric continue;
83*0b57cec5SDimitry Andric
84*0b57cec5SDimitry Andric Visit(ND, Index++);
85*0b57cec5SDimitry Andric }
86*0b57cec5SDimitry Andric }
87*0b57cec5SDimitry Andric
88*0b57cec5SDimitry Andric /// Determine whether the given declaration will be included in the per-module
89*0b57cec5SDimitry Andric /// initializer if it needs to be eagerly handed to the AST consumer. If so, we
90*0b57cec5SDimitry Andric /// should not hand it to the consumer when deserializing it, nor include it in
91*0b57cec5SDimitry Andric /// the list of eagerly deserialized declarations.
isPartOfPerModuleInitializer(const Decl * D)92*0b57cec5SDimitry Andric inline bool isPartOfPerModuleInitializer(const Decl *D) {
93*0b57cec5SDimitry Andric if (isa<ImportDecl>(D))
94*0b57cec5SDimitry Andric return true;
95*0b57cec5SDimitry Andric // Template instantiations are notionally in an "instantiation unit" rather
96*0b57cec5SDimitry Andric // than in any particular translation unit, so they need not be part of any
97*0b57cec5SDimitry Andric // particular (sub)module's per-module initializer.
98*0b57cec5SDimitry Andric if (auto *VD = dyn_cast<VarDecl>(D))
99*0b57cec5SDimitry Andric return !isTemplateInstantiation(VD->getTemplateSpecializationKind());
100*0b57cec5SDimitry Andric return false;
101*0b57cec5SDimitry Andric }
102*0b57cec5SDimitry Andric
103*0b57cec5SDimitry Andric } // namespace serialization
104*0b57cec5SDimitry Andric
105*0b57cec5SDimitry Andric } // namespace clang
106*0b57cec5SDimitry Andric
107*0b57cec5SDimitry Andric #endif
108