1 //===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the MultiplexConsumer class. It also declares and defines
11 // MultiplexASTDeserializationListener and MultiplexASTMutationListener, which
12 // are implementation details of MultiplexConsumer.
14 //===----------------------------------------------------------------------===//
16 #include "clang/Frontend/MultiplexConsumer.h"
18 #include "clang/AST/ASTMutationListener.h"
19 #include "clang/AST/DeclGroup.h"
20 #include "clang/Serialization/ASTDeserializationListener.h"
22 using namespace clang
;
26 // This ASTDeserializationListener forwards its notifications to a set of
28 class MultiplexASTDeserializationListener
29 : public ASTDeserializationListener
{
31 // Does NOT take ownership of the elements in L.
32 MultiplexASTDeserializationListener(
33 const std::vector
<ASTDeserializationListener
*>& L
);
34 virtual void ReaderInitialized(ASTReader
*Reader
);
35 virtual void IdentifierRead(serialization::IdentID ID
,
37 virtual void TypeRead(serialization::TypeIdx Idx
, QualType T
);
38 virtual void DeclRead(serialization::DeclID ID
, const Decl
*D
);
39 virtual void SelectorRead(serialization::SelectorID iD
, Selector Sel
);
40 virtual void MacroDefinitionRead(serialization::MacroID
,
43 std::vector
<ASTDeserializationListener
*> Listeners
;
46 MultiplexASTDeserializationListener::MultiplexASTDeserializationListener(
47 const std::vector
<ASTDeserializationListener
*>& L
)
51 void MultiplexASTDeserializationListener::ReaderInitialized(
53 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
54 Listeners
[i
]->ReaderInitialized(Reader
);
57 void MultiplexASTDeserializationListener::IdentifierRead(
58 serialization::IdentID ID
, IdentifierInfo
*II
) {
59 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
60 Listeners
[i
]->IdentifierRead(ID
, II
);
63 void MultiplexASTDeserializationListener::TypeRead(
64 serialization::TypeIdx Idx
, QualType T
) {
65 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
66 Listeners
[i
]->TypeRead(Idx
, T
);
69 void MultiplexASTDeserializationListener::DeclRead(
70 serialization::DeclID ID
, const Decl
*D
) {
71 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
72 Listeners
[i
]->DeclRead(ID
, D
);
75 void MultiplexASTDeserializationListener::SelectorRead(
76 serialization::SelectorID ID
, Selector Sel
) {
77 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
78 Listeners
[i
]->SelectorRead(ID
, Sel
);
81 void MultiplexASTDeserializationListener::MacroDefinitionRead(
82 serialization::MacroID ID
, MacroDefinition
*MD
) {
83 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
84 Listeners
[i
]->MacroDefinitionRead(ID
, MD
);
87 // This ASTMutationListener forwards its notifications to a set of
89 class MultiplexASTMutationListener
: public ASTMutationListener
{
91 // Does NOT take ownership of the elements in L.
92 MultiplexASTMutationListener(const std::vector
<ASTMutationListener
*>& L
);
93 virtual void CompletedTagDefinition(const TagDecl
*D
);
94 virtual void AddedVisibleDecl(const DeclContext
*DC
, const Decl
*D
);
95 virtual void AddedCXXImplicitMember(const CXXRecordDecl
*RD
, const Decl
*D
);
96 virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl
*TD
,
97 const ClassTemplateSpecializationDecl
*D
);
98 virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl
*TD
,
99 const FunctionDecl
*D
);
100 virtual void CompletedImplicitDefinition(const FunctionDecl
*D
);
101 virtual void StaticDataMemberInstantiated(const VarDecl
*D
);
103 std::vector
<ASTMutationListener
*> Listeners
;
106 MultiplexASTMutationListener::MultiplexASTMutationListener(
107 const std::vector
<ASTMutationListener
*>& L
)
111 void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl
*D
) {
112 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
113 Listeners
[i
]->CompletedTagDefinition(D
);
116 void MultiplexASTMutationListener::AddedVisibleDecl(
117 const DeclContext
*DC
, const Decl
*D
) {
118 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
119 Listeners
[i
]->AddedVisibleDecl(DC
, D
);
122 void MultiplexASTMutationListener::AddedCXXImplicitMember(
123 const CXXRecordDecl
*RD
, const Decl
*D
) {
124 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
125 Listeners
[i
]->AddedCXXImplicitMember(RD
, D
);
127 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
128 const ClassTemplateDecl
*TD
, const ClassTemplateSpecializationDecl
*D
) {
129 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
130 Listeners
[i
]->AddedCXXTemplateSpecialization(TD
, D
);
132 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
133 const FunctionTemplateDecl
*TD
, const FunctionDecl
*D
) {
134 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
135 Listeners
[i
]->AddedCXXTemplateSpecialization(TD
, D
);
137 void MultiplexASTMutationListener::CompletedImplicitDefinition(
138 const FunctionDecl
*D
) {
139 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
140 Listeners
[i
]->CompletedImplicitDefinition(D
);
142 void MultiplexASTMutationListener::StaticDataMemberInstantiated(
144 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
145 Listeners
[i
]->StaticDataMemberInstantiated(D
);
148 } // end namespace clang
151 MultiplexConsumer::MultiplexConsumer(const std::vector
<ASTConsumer
*>& C
)
152 : Consumers(C
), MutationListener(0), DeserializationListener(0) {
153 // Collect the mutation listeners and deserialization listeners of all
154 // children, and create a multiplex listener each if so.
155 std::vector
<ASTMutationListener
*> mutationListeners
;
156 std::vector
<ASTDeserializationListener
*> serializationListeners
;
157 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
) {
158 ASTMutationListener
* mutationListener
=
159 Consumers
[i
]->GetASTMutationListener();
160 if (mutationListener
)
161 mutationListeners
.push_back(mutationListener
);
162 ASTDeserializationListener
* serializationListener
=
163 Consumers
[i
]->GetASTDeserializationListener();
164 if (serializationListener
)
165 serializationListeners
.push_back(serializationListener
);
167 if (mutationListeners
.size()) {
168 MutationListener
.reset(new MultiplexASTMutationListener(mutationListeners
));
170 if (serializationListeners
.size()) {
171 DeserializationListener
.reset(
172 new MultiplexASTDeserializationListener(serializationListeners
));
176 MultiplexConsumer::~MultiplexConsumer() {
177 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
181 void MultiplexConsumer::Initialize(ASTContext
&Context
) {
182 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
183 Consumers
[i
]->Initialize(Context
);
186 void MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D
) {
187 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
188 Consumers
[i
]->HandleTopLevelDecl(D
);
191 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D
) {
192 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
193 Consumers
[i
]->HandleInterestingDecl(D
);
196 void MultiplexConsumer::HandleTranslationUnit(ASTContext
&Ctx
) {
197 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
198 Consumers
[i
]->HandleTranslationUnit(Ctx
);
201 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl
*D
) {
202 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
203 Consumers
[i
]->HandleTagDeclDefinition(D
);
206 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl
*D
) {
207 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
208 Consumers
[i
]->CompleteTentativeDefinition(D
);
211 void MultiplexConsumer::HandleVTable(
212 CXXRecordDecl
*RD
, bool DefinitionRequired
) {
213 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
214 Consumers
[i
]->HandleVTable(RD
, DefinitionRequired
);
217 ASTMutationListener
*MultiplexConsumer::GetASTMutationListener() {
218 return MutationListener
.get();
221 ASTDeserializationListener
*MultiplexConsumer::GetASTDeserializationListener() {
222 return DeserializationListener
.get();
225 void MultiplexConsumer::PrintStats() {
226 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
227 Consumers
[i
]->PrintStats();
230 void MultiplexConsumer::InitializeSema(Sema
&S
) {
231 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
232 if (SemaConsumer
*SC
= dyn_cast
<SemaConsumer
>(Consumers
[i
]))
233 SC
->InitializeSema(S
);
236 void MultiplexConsumer::ForgetSema() {
237 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
238 if (SemaConsumer
*SC
= dyn_cast
<SemaConsumer
>(Consumers
[i
]))