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/AST/DeclContextInternals.h" 14 #include "clang/Sema/Lookup.h" 15 16 using namespace clang; 17 18 ///Constructs a new multiplexing external sema source and appends the 19 /// given element to it. 20 /// 21 MultiplexExternalSemaSource::MultiplexExternalSemaSource(ExternalSemaSource &s1, 22 ExternalSemaSource &s2){ 23 Sources.push_back(&s1); 24 Sources.push_back(&s2); 25 } 26 27 // pin the vtable here. 28 MultiplexExternalSemaSource::~MultiplexExternalSemaSource() {} 29 30 ///Appends new source to the source list. 31 /// 32 ///\param[in] source - An ExternalSemaSource. 33 /// 34 void MultiplexExternalSemaSource::addSource(ExternalSemaSource &source) { 35 Sources.push_back(&source); 36 } 37 38 //===----------------------------------------------------------------------===// 39 // ExternalASTSource. 40 //===----------------------------------------------------------------------===// 41 42 Decl *MultiplexExternalSemaSource::GetExternalDecl(uint32_t ID) { 43 for(size_t i = 0; i < Sources.size(); ++i) 44 if (Decl *Result = Sources[i]->GetExternalDecl(ID)) 45 return Result; 46 return nullptr; 47 } 48 49 void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) { 50 for (size_t i = 0; i < Sources.size(); ++i) 51 Sources[i]->CompleteRedeclChain(D); 52 } 53 54 Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) { 55 Selector Sel; 56 for(size_t i = 0; i < Sources.size(); ++i) { 57 Sel = Sources[i]->GetExternalSelector(ID); 58 if (!Sel.isNull()) 59 return Sel; 60 } 61 return Sel; 62 } 63 64 uint32_t MultiplexExternalSemaSource::GetNumExternalSelectors() { 65 uint32_t total = 0; 66 for(size_t i = 0; i < Sources.size(); ++i) 67 total += Sources[i]->GetNumExternalSelectors(); 68 return total; 69 } 70 71 Stmt *MultiplexExternalSemaSource::GetExternalDeclStmt(uint64_t Offset) { 72 for(size_t i = 0; i < Sources.size(); ++i) 73 if (Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset)) 74 return Result; 75 return nullptr; 76 } 77 78 CXXBaseSpecifier *MultiplexExternalSemaSource::GetExternalCXXBaseSpecifiers( 79 uint64_t Offset){ 80 for(size_t i = 0; i < Sources.size(); ++i) 81 if (CXXBaseSpecifier *R = Sources[i]->GetExternalCXXBaseSpecifiers(Offset)) 82 return R; 83 return nullptr; 84 } 85 86 CXXCtorInitializer ** 87 MultiplexExternalSemaSource::GetExternalCXXCtorInitializers(uint64_t Offset) { 88 for (auto *S : Sources) 89 if (auto *R = S->GetExternalCXXCtorInitializers(Offset)) 90 return R; 91 return nullptr; 92 } 93 94 ExternalASTSource::ExtKind 95 MultiplexExternalSemaSource::hasExternalDefinitions(const Decl *D) { 96 for (const auto &S : Sources) 97 if (auto EK = S->hasExternalDefinitions(D)) 98 if (EK != EK_ReplyHazy) 99 return EK; 100 return EK_ReplyHazy; 101 } 102 103 bool MultiplexExternalSemaSource:: 104 FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { 105 bool AnyDeclsFound = false; 106 for (size_t i = 0; i < Sources.size(); ++i) 107 AnyDeclsFound |= Sources[i]->FindExternalVisibleDeclsByName(DC, Name); 108 return AnyDeclsFound; 109 } 110 111 void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){ 112 for(size_t i = 0; i < Sources.size(); ++i) 113 Sources[i]->completeVisibleDeclsMap(DC); 114 } 115 116 void MultiplexExternalSemaSource::FindExternalLexicalDecls( 117 const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, 118 SmallVectorImpl<Decl *> &Result) { 119 for(size_t i = 0; i < Sources.size(); ++i) 120 Sources[i]->FindExternalLexicalDecls(DC, IsKindWeWant, Result); 121 } 122 123 void MultiplexExternalSemaSource::FindFileRegionDecls(FileID File, 124 unsigned Offset, 125 unsigned Length, 126 SmallVectorImpl<Decl *> &Decls){ 127 for(size_t i = 0; i < Sources.size(); ++i) 128 Sources[i]->FindFileRegionDecls(File, Offset, Length, Decls); 129 } 130 131 void MultiplexExternalSemaSource::CompleteType(TagDecl *Tag) { 132 for(size_t i = 0; i < Sources.size(); ++i) 133 Sources[i]->CompleteType(Tag); 134 } 135 136 void MultiplexExternalSemaSource::CompleteType(ObjCInterfaceDecl *Class) { 137 for(size_t i = 0; i < Sources.size(); ++i) 138 Sources[i]->CompleteType(Class); 139 } 140 141 void MultiplexExternalSemaSource::ReadComments() { 142 for(size_t i = 0; i < Sources.size(); ++i) 143 Sources[i]->ReadComments(); 144 } 145 146 void MultiplexExternalSemaSource::StartedDeserializing() { 147 for(size_t i = 0; i < Sources.size(); ++i) 148 Sources[i]->StartedDeserializing(); 149 } 150 151 void MultiplexExternalSemaSource::FinishedDeserializing() { 152 for(size_t i = 0; i < Sources.size(); ++i) 153 Sources[i]->FinishedDeserializing(); 154 } 155 156 void MultiplexExternalSemaSource::StartTranslationUnit(ASTConsumer *Consumer) { 157 for(size_t i = 0; i < Sources.size(); ++i) 158 Sources[i]->StartTranslationUnit(Consumer); 159 } 160 161 void MultiplexExternalSemaSource::PrintStats() { 162 for(size_t i = 0; i < Sources.size(); ++i) 163 Sources[i]->PrintStats(); 164 } 165 166 Module *MultiplexExternalSemaSource::getModule(unsigned ID) { 167 for (size_t i = 0; i < Sources.size(); ++i) 168 if (auto M = Sources[i]->getModule(ID)) 169 return M; 170 return nullptr; 171 } 172 173 bool MultiplexExternalSemaSource::DeclIsFromPCHWithObjectFile(const Decl *D) { 174 for (auto *S : Sources) 175 if (S->DeclIsFromPCHWithObjectFile(D)) 176 return true; 177 return false; 178 } 179 180 bool MultiplexExternalSemaSource::layoutRecordType(const RecordDecl *Record, 181 uint64_t &Size, 182 uint64_t &Alignment, 183 llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets, 184 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets, 185 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets){ 186 for(size_t i = 0; i < Sources.size(); ++i) 187 if (Sources[i]->layoutRecordType(Record, Size, Alignment, FieldOffsets, 188 BaseOffsets, VirtualBaseOffsets)) 189 return true; 190 return false; 191 } 192 193 void MultiplexExternalSemaSource:: 194 getMemoryBufferSizes(MemoryBufferSizes &sizes) const { 195 for(size_t i = 0; i < Sources.size(); ++i) 196 Sources[i]->getMemoryBufferSizes(sizes); 197 198 } 199 200 //===----------------------------------------------------------------------===// 201 // ExternalSemaSource. 202 //===----------------------------------------------------------------------===// 203 204 205 void MultiplexExternalSemaSource::InitializeSema(Sema &S) { 206 for(size_t i = 0; i < Sources.size(); ++i) 207 Sources[i]->InitializeSema(S); 208 } 209 210 void MultiplexExternalSemaSource::ForgetSema() { 211 for(size_t i = 0; i < Sources.size(); ++i) 212 Sources[i]->ForgetSema(); 213 } 214 215 void MultiplexExternalSemaSource::ReadMethodPool(Selector Sel) { 216 for(size_t i = 0; i < Sources.size(); ++i) 217 Sources[i]->ReadMethodPool(Sel); 218 } 219 220 void MultiplexExternalSemaSource::updateOutOfDateSelector(Selector Sel) { 221 for(size_t i = 0; i < Sources.size(); ++i) 222 Sources[i]->updateOutOfDateSelector(Sel); 223 } 224 225 void MultiplexExternalSemaSource::ReadKnownNamespaces( 226 SmallVectorImpl<NamespaceDecl*> &Namespaces){ 227 for(size_t i = 0; i < Sources.size(); ++i) 228 Sources[i]->ReadKnownNamespaces(Namespaces); 229 } 230 231 void MultiplexExternalSemaSource::ReadUndefinedButUsed( 232 llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) { 233 for(size_t i = 0; i < Sources.size(); ++i) 234 Sources[i]->ReadUndefinedButUsed(Undefined); 235 } 236 237 void MultiplexExternalSemaSource::ReadMismatchingDeleteExpressions( 238 llvm::MapVector<FieldDecl *, 239 llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & 240 Exprs) { 241 for (auto &Source : Sources) 242 Source->ReadMismatchingDeleteExpressions(Exprs); 243 } 244 245 bool MultiplexExternalSemaSource::LookupUnqualified(LookupResult &R, Scope *S){ 246 for(size_t i = 0; i < Sources.size(); ++i) 247 Sources[i]->LookupUnqualified(R, S); 248 249 return !R.empty(); 250 } 251 252 void MultiplexExternalSemaSource::ReadTentativeDefinitions( 253 SmallVectorImpl<VarDecl*> &TentativeDefs) { 254 for(size_t i = 0; i < Sources.size(); ++i) 255 Sources[i]->ReadTentativeDefinitions(TentativeDefs); 256 } 257 258 void MultiplexExternalSemaSource::ReadUnusedFileScopedDecls( 259 SmallVectorImpl<const DeclaratorDecl*> &Decls) { 260 for(size_t i = 0; i < Sources.size(); ++i) 261 Sources[i]->ReadUnusedFileScopedDecls(Decls); 262 } 263 264 void MultiplexExternalSemaSource::ReadDelegatingConstructors( 265 SmallVectorImpl<CXXConstructorDecl*> &Decls) { 266 for(size_t i = 0; i < Sources.size(); ++i) 267 Sources[i]->ReadDelegatingConstructors(Decls); 268 } 269 270 void MultiplexExternalSemaSource::ReadExtVectorDecls( 271 SmallVectorImpl<TypedefNameDecl*> &Decls) { 272 for(size_t i = 0; i < Sources.size(); ++i) 273 Sources[i]->ReadExtVectorDecls(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