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
89CXXCtorInitializer **
90MultiplexExternalSemaSource::GetExternalCXXCtorInitializers(uint64_t Offset) {
91  for (auto *S : Sources)
92    if (auto *R = S->GetExternalCXXCtorInitializers(Offset))
93      return R;
94  return nullptr;
95}
96
97bool MultiplexExternalSemaSource::
98FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
99  bool AnyDeclsFound = false;
100  for (size_t i = 0; i < Sources.size(); ++i)
101    AnyDeclsFound |= Sources[i]->FindExternalVisibleDeclsByName(DC, Name);
102  return AnyDeclsFound;
103}
104
105void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){
106  for(size_t i = 0; i < Sources.size(); ++i)
107    Sources[i]->completeVisibleDeclsMap(DC);
108}
109
110ExternalLoadResult MultiplexExternalSemaSource::
111FindExternalLexicalDecls(const DeclContext *DC,
112                         bool (*isKindWeWant)(Decl::Kind),
113                         SmallVectorImpl<Decl*> &Result) {
114  for(size_t i = 0; i < Sources.size(); ++i)
115    // FIXME: The semantics of the return result is unclear to me...
116    Sources[i]->FindExternalLexicalDecls(DC, isKindWeWant, Result);
117
118  return ELR_Success;
119}
120
121void MultiplexExternalSemaSource::FindFileRegionDecls(FileID File,
122                                                      unsigned Offset,
123                                                      unsigned Length,
124                                                SmallVectorImpl<Decl *> &Decls){
125  for(size_t i = 0; i < Sources.size(); ++i)
126    Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls);
127}
128
129void MultiplexExternalSemaSource::CompleteType(TagDecl *Tag) {
130  for(size_t i = 0; i < Sources.size(); ++i)
131    Sources[i]->CompleteType(Tag);
132}
133
134void MultiplexExternalSemaSource::CompleteType(ObjCInterfaceDecl *Class) {
135  for(size_t i = 0; i < Sources.size(); ++i)
136    Sources[i]->CompleteType(Class);
137}
138
139void MultiplexExternalSemaSource::ReadComments() {
140  for(size_t i = 0; i < Sources.size(); ++i)
141    Sources[i]->ReadComments();
142}
143
144void MultiplexExternalSemaSource::StartedDeserializing() {
145  for(size_t i = 0; i < Sources.size(); ++i)
146    Sources[i]->StartedDeserializing();
147}
148
149void MultiplexExternalSemaSource::FinishedDeserializing() {
150  for(size_t i = 0; i < Sources.size(); ++i)
151    Sources[i]->FinishedDeserializing();
152}
153
154void MultiplexExternalSemaSource::StartTranslationUnit(ASTConsumer *Consumer) {
155  for(size_t i = 0; i < Sources.size(); ++i)
156    Sources[i]->StartTranslationUnit(Consumer);
157}
158
159void MultiplexExternalSemaSource::PrintStats() {
160  for(size_t i = 0; i < Sources.size(); ++i)
161    Sources[i]->PrintStats();
162}
163
164bool MultiplexExternalSemaSource::layoutRecordType(const RecordDecl *Record,
165                                                   uint64_t &Size,
166                                                   uint64_t &Alignment,
167                      llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
168                  llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
169          llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets){
170  for(size_t i = 0; i < Sources.size(); ++i)
171    if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets,
172                                     BaseOffsets, VirtualBaseOffsets))
173      return true;
174  return false;
175}
176
177void MultiplexExternalSemaSource::
178getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
179  for(size_t i = 0; i < Sources.size(); ++i)
180    Sources[i]->getMemoryBufferSizes(sizes);
181
182}
183
184//===----------------------------------------------------------------------===//
185// ExternalSemaSource.
186//===----------------------------------------------------------------------===//
187
188
189void MultiplexExternalSemaSource::InitializeSema(Sema &S) {
190  for(size_t i = 0; i < Sources.size(); ++i)
191    Sources[i]->InitializeSema(S);
192}
193
194void MultiplexExternalSemaSource::ForgetSema() {
195  for(size_t i = 0; i < Sources.size(); ++i)
196    Sources[i]->ForgetSema();
197}
198
199void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) {
200  for(size_t i = 0; i < Sources.size(); ++i)
201    Sources[i]->ReadMethodPool(Sel);
202}
203
204void MultiplexExternalSemaSource::ReadKnownNamespaces(
205                                   SmallVectorImpl<NamespaceDecl*> &Namespaces){
206  for(size_t i = 0; i < Sources.size(); ++i)
207    Sources[i]->ReadKnownNamespaces(Namespaces);
208}
209
210void MultiplexExternalSemaSource::ReadUndefinedButUsed(
211                         llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined){
212  for(size_t i = 0; i < Sources.size(); ++i)
213    Sources[i]->ReadUndefinedButUsed(Undefined);
214}
215
216bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){
217  for(size_t i = 0; i < Sources.size(); ++i)
218    Sources[i]->LookupUnqualified(R, S);
219
220  return !R.empty();
221}
222
223void MultiplexExternalSemaSource::ReadTentativeDefinitions(
224                                     SmallVectorImpl<VarDecl*> &TentativeDefs) {
225  for(size_t i = 0; i < Sources.size(); ++i)
226    Sources[i]->ReadTentativeDefinitions(TentativeDefs);
227}
228
229void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls(
230                                SmallVectorImpl<const DeclaratorDecl*> &Decls) {
231  for(size_t i = 0; i < Sources.size(); ++i)
232    Sources[i]->ReadUnusedFileScopedDecls(Decls);
233}
234
235void MultiplexExternalSemaSource::ReadDelegatingConstructors(
236                                  SmallVectorImpl<CXXConstructorDecl*> &Decls) {
237  for(size_t i = 0; i < Sources.size(); ++i)
238    Sources[i]->ReadDelegatingConstructors(Decls);
239}
240
241void MultiplexExternalSemaSource::ReadExtVectorDecls(
242                                     SmallVectorImpl<TypedefNameDecl*> &Decls) {
243  for(size_t i = 0; i < Sources.size(); ++i)
244    Sources[i]->ReadExtVectorDecls(Decls);
245}
246
247void MultiplexExternalSemaSource::ReadUnusedLocalTypedefNameCandidates(
248    llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
249  for(size_t i = 0; i < Sources.size(); ++i)
250    Sources[i]->ReadUnusedLocalTypedefNameCandidates(Decls);
251}
252
253void MultiplexExternalSemaSource::ReadReferencedSelectors(
254                  SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {
255  for(size_t i = 0; i < Sources.size(); ++i)
256    Sources[i]->ReadReferencedSelectors(Sels);
257}
258
259void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers(
260                   SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) {
261  for(size_t i = 0; i < Sources.size(); ++i)
262    Sources[i]->ReadWeakUndeclaredIdentifiers(WI);
263}
264
265void MultiplexExternalSemaSource::ReadUsedVTables(
266                                  SmallVectorImpl<ExternalVTableUse> &VTables) {
267  for(size_t i = 0; i < Sources.size(); ++i)
268    Sources[i]->ReadUsedVTables(VTables);
269}
270
271void MultiplexExternalSemaSource::ReadPendingInstantiations(
272                                           SmallVectorImpl<std::pair<ValueDecl*,
273                                                   SourceLocation> > &Pending) {
274  for(size_t i = 0; i < Sources.size(); ++i)
275    Sources[i]->ReadPendingInstantiations(Pending);
276}
277
278void MultiplexExternalSemaSource::ReadLateParsedTemplates(
279    llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {
280  for (size_t i = 0; i < Sources.size(); ++i)
281    Sources[i]->ReadLateParsedTemplates(LPTMap);
282}
283
284TypoCorrection MultiplexExternalSemaSource::CorrectTypo(
285                                     const DeclarationNameInfo &Typo,
286                                     int LookupKind, Scope *S, CXXScopeSpec *SS,
287                                     CorrectionCandidateCallback &CCC,
288                                     DeclContext *MemberContext,
289                                     bool EnteringContext,
290                                     const ObjCObjectPointerType *OPT) {
291  for (size_t I = 0, E = Sources.size(); I < E; ++I) {
292    if (TypoCorrection C = Sources[I]->CorrectTypo(Typo, LookupKind, S, SS, CCC,
293                                                   MemberContext,
294                                                   EnteringContext, OPT))
295      return C;
296  }
297  return TypoCorrection();
298}
299
300bool MultiplexExternalSemaSource::MaybeDiagnoseMissingCompleteType(
301    SourceLocation Loc, QualType T) {
302  for (size_t I = 0, E = Sources.size(); I < E; ++I) {
303    if (Sources[I]->MaybeDiagnoseMissingCompleteType(Loc, T))
304      return true;
305  }
306  return false;
307}
308