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
);
99 std::vector
<ASTMutationListener
*> Listeners
;
102 MultiplexASTMutationListener::MultiplexASTMutationListener(
103 const std::vector
<ASTMutationListener
*>& L
)
107 void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl
*D
) {
108 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
109 Listeners
[i
]->CompletedTagDefinition(D
);
112 void MultiplexASTMutationListener::AddedVisibleDecl(
113 const DeclContext
*DC
, const Decl
*D
) {
114 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
115 Listeners
[i
]->AddedVisibleDecl(DC
, D
);
118 void MultiplexASTMutationListener::AddedCXXImplicitMember(
119 const CXXRecordDecl
*RD
, const Decl
*D
) {
120 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
121 Listeners
[i
]->AddedCXXImplicitMember(RD
, D
);
123 void MultiplexASTMutationListener::AddedCXXTemplateSpecialization(
124 const ClassTemplateDecl
*TD
, const ClassTemplateSpecializationDecl
*D
) {
125 for (size_t i
= 0, e
= Listeners
.size(); i
!= e
; ++i
)
126 Listeners
[i
]->AddedCXXTemplateSpecialization(TD
, D
);
129 } // end namespace clang
132 MultiplexConsumer::MultiplexConsumer(const std::vector
<ASTConsumer
*>& C
)
133 : Consumers(C
), MutationListener(0), DeserializationListener(0) {
134 // Collect the mutation listeners and deserialization listeners of all
135 // children, and create a multiplex listener each if so.
136 std::vector
<ASTMutationListener
*> mutationListeners
;
137 std::vector
<ASTDeserializationListener
*> serializationListeners
;
138 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
) {
139 ASTMutationListener
* mutationListener
=
140 Consumers
[i
]->GetASTMutationListener();
141 if (mutationListener
)
142 mutationListeners
.push_back(mutationListener
);
143 ASTDeserializationListener
* serializationListener
=
144 Consumers
[i
]->GetASTDeserializationListener();
145 if (serializationListener
)
146 serializationListeners
.push_back(serializationListener
);
148 if (mutationListeners
.size()) {
149 MutationListener
.reset(new MultiplexASTMutationListener(mutationListeners
));
151 if (serializationListeners
.size()) {
152 DeserializationListener
.reset(
153 new MultiplexASTDeserializationListener(serializationListeners
));
157 MultiplexConsumer::~MultiplexConsumer() {
158 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
162 void MultiplexConsumer::Initialize(ASTContext
&Context
) {
163 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
164 Consumers
[i
]->Initialize(Context
);
167 void MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D
) {
168 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
169 Consumers
[i
]->HandleTopLevelDecl(D
);
172 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D
) {
173 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
174 Consumers
[i
]->HandleInterestingDecl(D
);
177 void MultiplexConsumer::HandleTranslationUnit(ASTContext
&Ctx
) {
178 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
179 Consumers
[i
]->HandleTranslationUnit(Ctx
);
182 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl
*D
) {
183 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
184 Consumers
[i
]->HandleTagDeclDefinition(D
);
187 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl
*D
) {
188 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
189 Consumers
[i
]->CompleteTentativeDefinition(D
);
192 void MultiplexConsumer::HandleVTable(
193 CXXRecordDecl
*RD
, bool DefinitionRequired
) {
194 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
195 Consumers
[i
]->HandleVTable(RD
, DefinitionRequired
);
198 ASTMutationListener
*MultiplexConsumer::GetASTMutationListener() {
199 return MutationListener
.get();
202 ASTDeserializationListener
*MultiplexConsumer::GetASTDeserializationListener() {
203 return DeserializationListener
.get();
206 void MultiplexConsumer::PrintStats() {
207 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
208 Consumers
[i
]->PrintStats();
211 void MultiplexConsumer::InitializeSema(Sema
&S
) {
212 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
213 if (SemaConsumer
*SC
= dyn_cast
<SemaConsumer
>(Consumers
[i
]))
214 SC
->InitializeSema(S
);
217 void MultiplexConsumer::ForgetSema() {
218 for (size_t i
= 0, e
= Consumers
.size(); i
!= e
; ++i
)
219 if (SemaConsumer
*SC
= dyn_cast
<SemaConsumer
>(Consumers
[i
]))