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