1*2992efa4SNico Weber //===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- C++ -*-===//
2*2992efa4SNico Weber //
3*2992efa4SNico Weber //                     The LLVM Compiler Infrastructure
4*2992efa4SNico Weber //
5*2992efa4SNico Weber // This file is distributed under the University of Illinois Open Source
6*2992efa4SNico Weber // License. See LICENSE.TXT for details.
7*2992efa4SNico Weber //
8*2992efa4SNico Weber //===----------------------------------------------------------------------===//
9*2992efa4SNico Weber //
10*2992efa4SNico Weber //  This file defines the MultiplexConsumer class. It also declares and defines
11*2992efa4SNico Weber //  MultiplexASTDeserializationListener and  MultiplexASTMutationListener, which
12*2992efa4SNico Weber //  are implementation details of MultiplexConsumer.
13*2992efa4SNico Weber //
14*2992efa4SNico Weber //===----------------------------------------------------------------------===//
15*2992efa4SNico Weber 
16*2992efa4SNico Weber #include "clang/Frontend/MultiplexConsumer.h"
17*2992efa4SNico Weber 
18*2992efa4SNico Weber #include "clang/AST/ASTMutationListener.h"
19*2992efa4SNico Weber #include "clang/AST/DeclGroup.h"
20*2992efa4SNico Weber #include "clang/Serialization/ASTDeserializationListener.h"
21*2992efa4SNico Weber 
22*2992efa4SNico Weber using namespace clang;
23*2992efa4SNico Weber 
24*2992efa4SNico Weber namespace clang {
25*2992efa4SNico Weber 
26*2992efa4SNico Weber // This ASTDeserializationListener forwards its notifications to a set of
27*2992efa4SNico Weber // child listeners.
28*2992efa4SNico Weber class MultiplexASTDeserializationListener
29*2992efa4SNico Weber     : public ASTDeserializationListener {
30*2992efa4SNico Weber public:
31*2992efa4SNico Weber   // Does NOT take ownership of the elements in L.
32*2992efa4SNico Weber   MultiplexASTDeserializationListener(
33*2992efa4SNico Weber       const std::vector<ASTDeserializationListener*>& L);
34*2992efa4SNico Weber   virtual void ReaderInitialized(ASTReader *Reader);
35*2992efa4SNico Weber   virtual void IdentifierRead(serialization::IdentID ID,
36*2992efa4SNico Weber                               IdentifierInfo *II);
37*2992efa4SNico Weber   virtual void TypeRead(serialization::TypeIdx Idx, QualType T);
38*2992efa4SNico Weber   virtual void DeclRead(serialization::DeclID ID, const Decl *D);
39*2992efa4SNico Weber   virtual void SelectorRead(serialization::SelectorID iD, Selector Sel);
40*2992efa4SNico Weber   virtual void MacroDefinitionRead(serialization::MacroID,
41*2992efa4SNico Weber                                    MacroDefinition *MD);
42*2992efa4SNico Weber private:
43*2992efa4SNico Weber   std::vector<ASTDeserializationListener*> Listeners;
44*2992efa4SNico Weber };
45*2992efa4SNico Weber 
46*2992efa4SNico Weber MultiplexASTDeserializationListener::MultiplexASTDeserializationListener(
47*2992efa4SNico Weber       const std::vector<ASTDeserializationListener*>& L)
48*2992efa4SNico Weber     : Listeners(L) {
49*2992efa4SNico Weber }
50*2992efa4SNico Weber 
51*2992efa4SNico Weber void MultiplexASTDeserializationListener::ReaderInitialized(
52*2992efa4SNico Weber     ASTReader *Reader) {
53*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
54*2992efa4SNico Weber     Listeners[i]->ReaderInitialized(Reader);
55*2992efa4SNico Weber }
56*2992efa4SNico Weber 
57*2992efa4SNico Weber void MultiplexASTDeserializationListener::IdentifierRead(
58*2992efa4SNico Weber     serialization::IdentID ID, IdentifierInfo *II) {
59*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
60*2992efa4SNico Weber     Listeners[i]->IdentifierRead(ID, II);
61*2992efa4SNico Weber }
62*2992efa4SNico Weber 
63*2992efa4SNico Weber void MultiplexASTDeserializationListener::TypeRead(
64*2992efa4SNico Weber     serialization::TypeIdx Idx, QualType T) {
65*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
66*2992efa4SNico Weber     Listeners[i]->TypeRead(Idx, T);
67*2992efa4SNico Weber }
68*2992efa4SNico Weber 
69*2992efa4SNico Weber void MultiplexASTDeserializationListener::DeclRead(
70*2992efa4SNico Weber     serialization::DeclID ID, const Decl *D) {
71*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
72*2992efa4SNico Weber     Listeners[i]->DeclRead(ID, D);
73*2992efa4SNico Weber }
74*2992efa4SNico Weber 
75*2992efa4SNico Weber void MultiplexASTDeserializationListener::SelectorRead(
76*2992efa4SNico Weber     serialization::SelectorID ID, Selector Sel) {
77*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
78*2992efa4SNico Weber     Listeners[i]->SelectorRead(ID, Sel);
79*2992efa4SNico Weber }
80*2992efa4SNico Weber 
81*2992efa4SNico Weber void MultiplexASTDeserializationListener::MacroDefinitionRead(
82*2992efa4SNico Weber     serialization::MacroID ID, MacroDefinition *MD) {
83*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
84*2992efa4SNico Weber     Listeners[i]->MacroDefinitionRead(ID, MD);
85*2992efa4SNico Weber }
86*2992efa4SNico Weber 
87*2992efa4SNico Weber // This ASTMutationListener forwards its notifications to a set of
88*2992efa4SNico Weber // child listeners.
89*2992efa4SNico Weber class MultiplexASTMutationListener : public ASTMutationListener {
90*2992efa4SNico Weber public:
91*2992efa4SNico Weber   // Does NOT take ownership of the elements in L.
92*2992efa4SNico Weber   MultiplexASTMutationListener(const std::vector<ASTMutationListener*>& L);
93*2992efa4SNico Weber   virtual void CompletedTagDefinition(const TagDecl *D);
94*2992efa4SNico Weber   virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
95*2992efa4SNico Weber   virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D);
96*2992efa4SNico Weber   virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
97*2992efa4SNico Weber                                     const ClassTemplateSpecializationDecl *D);
98*2992efa4SNico Weber private:
99*2992efa4SNico Weber   std::vector<ASTMutationListener*> Listeners;
100*2992efa4SNico Weber };
101*2992efa4SNico Weber 
102*2992efa4SNico Weber MultiplexASTMutationListener::MultiplexASTMutationListener(
103*2992efa4SNico Weber     const std::vector<ASTMutationListener*>& L)
104*2992efa4SNico Weber     : Listeners(L) {
105*2992efa4SNico Weber }
106*2992efa4SNico Weber 
107*2992efa4SNico Weber void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) {
108*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
109*2992efa4SNico Weber     Listeners[i]->CompletedTagDefinition(D);
110*2992efa4SNico Weber }
111*2992efa4SNico Weber 
112*2992efa4SNico Weber void MultiplexASTMutationListener::AddedVisibleDecl(
113*2992efa4SNico Weber     const DeclContext *DC, const Decl *D) {
114*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
115*2992efa4SNico Weber     Listeners[i]->AddedVisibleDecl(DC, D);
116*2992efa4SNico Weber }
117*2992efa4SNico Weber 
118*2992efa4SNico Weber void MultiplexASTMutationListener::AddedCXXImplicitMember(
119*2992efa4SNico Weber     const CXXRecordDecl *RD, const Decl *D) {
120*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
121*2992efa4SNico Weber     Listeners[i]->AddedCXXImplicitMember(RD, D);
122*2992efa4SNico Weber }
123*2992efa4SNico Weber void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
124*2992efa4SNico Weber     const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) {
125*2992efa4SNico Weber   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
126*2992efa4SNico Weber     Listeners[i]->AddedCXXTemplateSpecialization(TD, D);
127*2992efa4SNico Weber }
128*2992efa4SNico Weber 
129*2992efa4SNico Weber }  // end namespace clang
130*2992efa4SNico Weber 
131*2992efa4SNico Weber 
132*2992efa4SNico Weber MultiplexConsumer::MultiplexConsumer(const std::vector<ASTConsumer*>& C)
133*2992efa4SNico Weber     : Consumers(C), MutationListener(0), DeserializationListener(0) {
134*2992efa4SNico Weber   // Collect the mutation listeners and deserialization listeners of all
135*2992efa4SNico Weber   // children, and create a multiplex listener each if so.
136*2992efa4SNico Weber   std::vector<ASTMutationListener*> mutationListeners;
137*2992efa4SNico Weber   std::vector<ASTDeserializationListener*> serializationListeners;
138*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i) {
139*2992efa4SNico Weber     ASTMutationListener* mutationListener =
140*2992efa4SNico Weber         Consumers[i]->GetASTMutationListener();
141*2992efa4SNico Weber     if (mutationListener)
142*2992efa4SNico Weber       mutationListeners.push_back(mutationListener);
143*2992efa4SNico Weber     ASTDeserializationListener* serializationListener =
144*2992efa4SNico Weber         Consumers[i]->GetASTDeserializationListener();
145*2992efa4SNico Weber     if (serializationListener)
146*2992efa4SNico Weber       serializationListeners.push_back(serializationListener);
147*2992efa4SNico Weber   }
148*2992efa4SNico Weber   if (mutationListeners.size()) {
149*2992efa4SNico Weber     MutationListener.reset(new MultiplexASTMutationListener(mutationListeners));
150*2992efa4SNico Weber   }
151*2992efa4SNico Weber   if (serializationListeners.size()) {
152*2992efa4SNico Weber     DeserializationListener.reset(
153*2992efa4SNico Weber         new MultiplexASTDeserializationListener(serializationListeners));
154*2992efa4SNico Weber   }
155*2992efa4SNico Weber }
156*2992efa4SNico Weber 
157*2992efa4SNico Weber MultiplexConsumer::~MultiplexConsumer() {
158*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
159*2992efa4SNico Weber     delete Consumers[i];
160*2992efa4SNico Weber }
161*2992efa4SNico Weber 
162*2992efa4SNico Weber void MultiplexConsumer::Initialize(ASTContext &Context) {
163*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
164*2992efa4SNico Weber     Consumers[i]->Initialize(Context);
165*2992efa4SNico Weber }
166*2992efa4SNico Weber 
167*2992efa4SNico Weber void MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
168*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
169*2992efa4SNico Weber     Consumers[i]->HandleTopLevelDecl(D);
170*2992efa4SNico Weber }
171*2992efa4SNico Weber 
172*2992efa4SNico Weber void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) {
173*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
174*2992efa4SNico Weber     Consumers[i]->HandleInterestingDecl(D);
175*2992efa4SNico Weber }
176*2992efa4SNico Weber 
177*2992efa4SNico Weber void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) {
178*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
179*2992efa4SNico Weber     Consumers[i]->HandleTranslationUnit(Ctx);
180*2992efa4SNico Weber }
181*2992efa4SNico Weber 
182*2992efa4SNico Weber void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) {
183*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
184*2992efa4SNico Weber     Consumers[i]->HandleTagDeclDefinition(D);
185*2992efa4SNico Weber }
186*2992efa4SNico Weber 
187*2992efa4SNico Weber void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
188*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
189*2992efa4SNico Weber     Consumers[i]->CompleteTentativeDefinition(D);
190*2992efa4SNico Weber }
191*2992efa4SNico Weber 
192*2992efa4SNico Weber void MultiplexConsumer::HandleVTable(
193*2992efa4SNico Weber     CXXRecordDecl *RD, bool DefinitionRequired) {
194*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
195*2992efa4SNico Weber     Consumers[i]->HandleVTable(RD, DefinitionRequired);
196*2992efa4SNico Weber }
197*2992efa4SNico Weber 
198*2992efa4SNico Weber ASTMutationListener *MultiplexConsumer::GetASTMutationListener() {
199*2992efa4SNico Weber   return MutationListener.get();
200*2992efa4SNico Weber }
201*2992efa4SNico Weber 
202*2992efa4SNico Weber ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() {
203*2992efa4SNico Weber   return DeserializationListener.get();
204*2992efa4SNico Weber }
205*2992efa4SNico Weber 
206*2992efa4SNico Weber void MultiplexConsumer::PrintStats() {
207*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
208*2992efa4SNico Weber     Consumers[i]->PrintStats();
209*2992efa4SNico Weber }
210*2992efa4SNico Weber 
211*2992efa4SNico Weber void MultiplexConsumer::InitializeSema(Sema &S) {
212*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
213*2992efa4SNico Weber     if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
214*2992efa4SNico Weber       SC->InitializeSema(S);
215*2992efa4SNico Weber }
216*2992efa4SNico Weber 
217*2992efa4SNico Weber void MultiplexConsumer::ForgetSema() {
218*2992efa4SNico Weber   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
219*2992efa4SNico Weber     if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
220*2992efa4SNico Weber       SC->ForgetSema();
221*2992efa4SNico Weber }
222