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