1//===--- MultiplexExternalSemaSource.cpp  ---------------------------------===//
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 implements the event dispatching to the subscribed clients.
11//
12//===----------------------------------------------------------------------===//
13#include "clang/Sema/MultiplexExternalSemaSource.h"
14#include "clang/AST/DeclContextInternals.h"
15#include "clang/Sema/Lookup.h"
16
17using namespace clang;
18
19///\brief Constructs a new multiplexing external sema source and appends the
20/// given element to it.
21///
22///\param[in] source - An ExternalSemaSource.
23///
24MultiplexExternalSemaSource::MultiplexExternalSemaSource(ExternalSemaSource &s1,
25                                                        ExternalSemaSource &s2){
26  Sources.push_back(&s1);
27  Sources.push_back(&s2);
28}
29
30// pin the vtable here.
31MultiplexExternalSemaSource::~MultiplexExternalSemaSource() {}
32
33///\brief Appends new source to the source list.
34///
35///\param[in] source - An ExternalSemaSource.
36///
37void MultiplexExternalSemaSource::addSource(ExternalSemaSource &source) {
38  Sources.push_back(&source);
39}
40
41//===----------------------------------------------------------------------===//
42// ExternalASTSource.
43//===----------------------------------------------------------------------===//
44
45Decl *MultiplexExternalSemaSource::GetExternalDecl(uint32_t ID) {
46  for(size_t i = 0; i < Sources.size(); ++i)
47    if (Decl *Result = Sources[i]->GetExternalDecl(ID))
48      return Result;
49  return nullptr;
50}
51
52void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) {
53  for (size_t i = 0; i < Sources.size(); ++i)
54    Sources[i]->CompleteRedeclChain(D);
55}
56
57Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) {
58  Selector Sel;
59  for(size_t i = 0; i < Sources.size(); ++i) {
60    Sel = Sources[i]->GetExternalSelector(ID);
61    if (!Sel.isNull())
62      return Sel;
63  }
64  return Sel;
65}
66
67uint32_t MultiplexExternalSemaSource::GetNumExternalSelectors() {
68  uint32_t total = 0;
69  for(size_t i = 0; i < Sources.size(); ++i)
70    total += Sources[i]->GetNumExternalSelectors();
71  return total;
72}
73
74Stmt *MultiplexExternalSemaSource::GetExternalDeclStmt(uint64_t Offset) {
75  for(size_t i = 0; i < Sources.size(); ++i)
76    if (Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset))
77      return Result;
78  return nullptr;
79}
80
81CXXBaseSpecifier *MultiplexExternalSemaSource::GetExternalCXXBaseSpecifiers(
82                                                               uint64_t Offset){
83  for(size_t i = 0; i < Sources.size(); ++i)
84    if (CXXBaseSpecifier *R = Sources[i]->GetExternalCXXBaseSpecifiers(Offset))
85      return R;
86  return nullptr;
87}
88
89bool MultiplexExternalSemaSource::
90FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
91  bool AnyDeclsFound = false;
92  for (size_t i = 0; i < Sources.size(); ++i)
93    AnyDeclsFound |= Sources[i]->FindExternalVisibleDeclsByName(DC, Name);
94  return AnyDeclsFound;
95}
96
97void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
98  for(size_t i = 0; i < Sources.size(); ++i)
99    Sources[i]->completeVisibleDeclsMap(DC);
100}
101
102ExternalLoadResult MultiplexExternalSemaSource::
103FindExternalLexicalDecls(const DeclContext *DC,
104                         bool (*isKindWeWant)(Decl::Kind),
105                         SmallVectorImpl<Decl*> &Result) {
106  for(size_t i = 0; i < Sources.size(); ++i)
107    // FIXME: The semantics of the return result is unclear to me...
108    Sources[i]->FindExternalLexicalDecls(DC, isKindWeWant, Result);
109
110  return ELR_Success;
111}
112
113void MultiplexExternalSemaSource::FindFileRegionDecls(FileID File,
114                                                      unsigned Offset,
115                                                      unsigned Length,
116                                                SmallVectorImpl<Decl *> &Decls){
117  for(size_t i = 0; i < Sources.size(); ++i)
118    Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls);
119}
120
121void MultiplexExternalSemaSource::CompleteType(TagDecl *Tag) {
122  for(size_t i = 0; i < Sources.size(); ++i)
123    Sources[i]->CompleteType(Tag);
124}
125
126void MultiplexExternalSemaSource::CompleteType(ObjCInterfaceDecl *Class) {
127  for(size_t i = 0; i < Sources.size(); ++i)
128    Sources[i]->CompleteType(Class);
129}
130
131void MultiplexExternalSemaSource::ReadComments() {
132  for(size_t i = 0; i < Sources.size(); ++i)
133    Sources[i]->ReadComments();
134}
135
136void MultiplexExternalSemaSource::StartedDeserializing() {
137  for(size_t i = 0; i < Sources.size(); ++i)
138    Sources[i]->StartedDeserializing();
139}
140
141void MultiplexExternalSemaSource::FinishedDeserializing() {
142  for(size_t i = 0; i < Sources.size(); ++i)
143    Sources[i]->FinishedDeserializing();
144}
145
146void MultiplexExternalSemaSource::StartTranslationUnit(ASTConsumer *Consumer) {
147  for(size_t i = 0; i < Sources.size(); ++i)
148    Sources[i]->StartTranslationUnit(Consumer);
149}
150
151void MultiplexExternalSemaSource::PrintStats() {
152  for(size_t i = 0; i < Sources.size(); ++i)
153    Sources[i]->PrintStats();
154}
155
156bool MultiplexExternalSemaSource::layoutRecordType(const RecordDecl *Record,
157                                                   uint64_t &Size,
158                                                   uint64_t &Alignment,
159                      llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
160                  llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
161          llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets){
162  for(size_t i = 0; i < Sources.size(); ++i)
163    if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets,
164                                     BaseOffsets, VirtualBaseOffsets))
165      return true;
166  return false;
167}
168
169void MultiplexExternalSemaSource::
170getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
171  for(size_t i = 0; i < Sources.size(); ++i)
172    Sources[i]->getMemoryBufferSizes(sizes);
173
174}
175
176//===----------------------------------------------------------------------===//
177// ExternalSemaSource.
178//===----------------------------------------------------------------------===//
179
180
181void MultiplexExternalSemaSource::InitializeSema(Sema &S) {
182  for(size_t i = 0; i < Sources.size(); ++i)
183    Sources[i]->InitializeSema(S);
184}
185
186void MultiplexExternalSemaSource::ForgetSema() {
187  for(size_t i = 0; i < Sources.size(); ++i)
188    Sources[i]->ForgetSema();
189}
190
191void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) {
192  for(size_t i = 0; i < Sources.size(); ++i)
193    Sources[i]->ReadMethodPool(Sel);
194}
195
196void MultiplexExternalSemaSource::ReadKnownNamespaces(
197                                   SmallVectorImpl<NamespaceDecl*> &Namespaces){
198  for(size_t i = 0; i < Sources.size(); ++i)
199    Sources[i]->ReadKnownNamespaces(Namespaces);
200}
201
202void MultiplexExternalSemaSource::ReadUndefinedButUsed(
203                         llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined){
204  for(size_t i = 0; i < Sources.size(); ++i)
205    Sources[i]->ReadUndefinedButUsed(Undefined);
206}
207
208bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){
209  for(size_t i = 0; i < Sources.size(); ++i)
210    Sources[i]->LookupUnqualified(R, S);
211
212  return !R.empty();
213}
214
215void MultiplexExternalSemaSource::ReadTentativeDefinitions(
216                                     SmallVectorImpl<VarDecl*> &TentativeDefs) {
217  for(size_t i = 0; i < Sources.size(); ++i)
218    Sources[i]->ReadTentativeDefinitions(TentativeDefs);
219}
220
221void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls(
222                                SmallVectorImpl<const DeclaratorDecl*> &Decls) {
223  for(size_t i = 0; i < Sources.size(); ++i)
224    Sources[i]->ReadUnusedFileScopedDecls(Decls);
225}
226
227void MultiplexExternalSemaSource::ReadDelegatingConstructors(
228                                  SmallVectorImpl<CXXConstructorDecl*> &Decls) {
229  for(size_t i = 0; i < Sources.size(); ++i)
230    Sources[i]->ReadDelegatingConstructors(Decls);
231}
232
233void MultiplexExternalSemaSource::ReadExtVectorDecls(
234                                     SmallVectorImpl<TypedefNameDecl*> &Decls) {
235  for(size_t i = 0; i < Sources.size(); ++i)
236    Sources[i]->ReadExtVectorDecls(Decls);
237}
238
239void MultiplexExternalSemaSource::ReadDynamicClasses(
240                                       SmallVectorImpl<CXXRecordDecl*> &Decls) {
241  for(size_t i = 0; i < Sources.size(); ++i)
242    Sources[i]->ReadDynamicClasses(Decls);
243}
244
245void MultiplexExternalSemaSource::ReadLocallyScopedExternCDecls(
246                                           SmallVectorImpl<NamedDecl*> &Decls) {
247  for(size_t i = 0; i < Sources.size(); ++i)
248    Sources[i]->ReadLocallyScopedExternCDecls(Decls);
249}
250
251void MultiplexExternalSemaSource::ReadReferencedSelectors(
252                  SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
253  for(size_t i = 0; i < Sources.size(); ++i)
254    Sources[i]->ReadReferencedSelectors(Sels);
255}
256
257void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers(
258                   SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) {
259  for(size_t i = 0; i < Sources.size(); ++i)
260    Sources[i]->ReadWeakUndeclaredIdentifiers(WI);
261}
262
263void MultiplexExternalSemaSource::ReadUsedVTables(
264                                  SmallVectorImpl<ExternalVTableUse> &VTables) {
265  for(size_t i = 0; i < Sources.size(); ++i)
266    Sources[i]->ReadUsedVTables(VTables);
267}
268
269void MultiplexExternalSemaSource::ReadPendingInstantiations(
270                                           SmallVectorImpl<std::pair<ValueDecl*,
271                                                   SourceLocation> > &Pending) {
272  for(size_t i = 0; i < Sources.size(); ++i)
273    Sources[i]->ReadPendingInstantiations(Pending);
274}
275
276void MultiplexExternalSemaSource::ReadLateParsedTemplates(
277    llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {
278  for (size_t i = 0; i < Sources.size(); ++i)
279    Sources[i]->ReadLateParsedTemplates(LPTMap);
280}
281
282TypoCorrection MultiplexExternalSemaSource::CorrectTypo(
283                                     const DeclarationNameInfo &Typo,
284                                     int LookupKind, Scope *S, CXXScopeSpec *SS,
285                                     CorrectionCandidateCallback &CCC,
286                                     DeclContext *MemberContext,
287                                     bool EnteringContext,
288                                     const ObjCObjectPointerType *OPT) {
289  for (size_t I = 0, E = Sources.size(); I < E; ++I) {
290    if (TypoCorrection C = Sources[I]->CorrectTypo(Typo, LookupKind, S, SS, CCC,
291                                                   MemberContext,
292                                                   EnteringContext, OPT))
293      return C;
294  }
295  return TypoCorrection();
296}
297
298bool MultiplexExternalSemaSource::MaybeDiagnoseMissingCompleteType(
299    SourceLocation Loc, QualType T) {
300  for (size_t I = 0, E = Sources.size(); I < E; ++I) {
301    if (Sources[I]->MaybeDiagnoseMissingCompleteType(Loc, T))
302      return true;
303  }
304  return false;
305}
306