MultiplexConsumer.cpp revision 5aa74affa5d61d04c4b034b3722ca41aec0cba6e
1//===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the MultiplexConsumer class. It also declares and defines 11// MultiplexASTDeserializationListener and MultiplexASTMutationListener, which 12// are implementation details of MultiplexConsumer. 13// 14//===----------------------------------------------------------------------===// 15 16#include "clang/Frontend/MultiplexConsumer.h" 17 18#include "clang/AST/ASTMutationListener.h" 19#include "clang/AST/DeclGroup.h" 20#include "clang/Serialization/ASTDeserializationListener.h" 21 22using namespace clang; 23 24namespace clang { 25 26// This ASTDeserializationListener forwards its notifications to a set of 27// child listeners. 28class MultiplexASTDeserializationListener 29 : public ASTDeserializationListener { 30public: 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, 36 IdentifierInfo *II); 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, 41 MacroDefinition *MD); 42private: 43 std::vector<ASTDeserializationListener*> Listeners; 44}; 45 46MultiplexASTDeserializationListener::MultiplexASTDeserializationListener( 47 const std::vector<ASTDeserializationListener*>& L) 48 : Listeners(L) { 49} 50 51void MultiplexASTDeserializationListener::ReaderInitialized( 52 ASTReader *Reader) { 53 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 54 Listeners[i]->ReaderInitialized(Reader); 55} 56 57void 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); 61} 62 63void 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); 67} 68 69void 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); 73} 74 75void 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); 79} 80 81void 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); 85} 86 87// This ASTMutationListener forwards its notifications to a set of 88// child listeners. 89class MultiplexASTMutationListener : public ASTMutationListener { 90public: 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); 98private: 99 std::vector<ASTMutationListener*> Listeners; 100}; 101 102MultiplexASTMutationListener::MultiplexASTMutationListener( 103 const std::vector<ASTMutationListener*>& L) 104 : Listeners(L) { 105} 106 107void MultiplexASTMutationListener::CompletedTagDefinition(const TagDecl *D) { 108 for (size_t i = 0, e = Listeners.size(); i != e; ++i) 109 Listeners[i]->CompletedTagDefinition(D); 110} 111 112void 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); 116} 117 118void 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); 122} 123void 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); 127} 128 129} // end namespace clang 130 131 132MultiplexConsumer::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); 147 } 148 if (mutationListeners.size()) { 149 MutationListener.reset(new MultiplexASTMutationListener(mutationListeners)); 150 } 151 if (serializationListeners.size()) { 152 DeserializationListener.reset( 153 new MultiplexASTDeserializationListener(serializationListeners)); 154 } 155} 156 157MultiplexConsumer::~MultiplexConsumer() { 158 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 159 delete Consumers[i]; 160} 161 162void MultiplexConsumer::Initialize(ASTContext &Context) { 163 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 164 Consumers[i]->Initialize(Context); 165} 166 167void MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) { 168 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 169 Consumers[i]->HandleTopLevelDecl(D); 170} 171 172void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { 173 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 174 Consumers[i]->HandleInterestingDecl(D); 175} 176 177void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) { 178 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 179 Consumers[i]->HandleTranslationUnit(Ctx); 180} 181 182void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) { 183 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 184 Consumers[i]->HandleTagDeclDefinition(D); 185} 186 187void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { 188 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 189 Consumers[i]->CompleteTentativeDefinition(D); 190} 191 192void 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); 196} 197 198ASTMutationListener *MultiplexConsumer::GetASTMutationListener() { 199 return MutationListener.get(); 200} 201 202ASTDeserializationListener *MultiplexConsumer::GetASTDeserializationListener() { 203 return DeserializationListener.get(); 204} 205 206void MultiplexConsumer::PrintStats() { 207 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 208 Consumers[i]->PrintStats(); 209} 210 211void 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); 215} 216 217void MultiplexConsumer::ForgetSema() { 218 for (size_t i = 0, e = Consumers.size(); i != e; ++i) 219 if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i])) 220 SC->ForgetSema(); 221} 222