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