diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp | 293 |
1 files changed, 223 insertions, 70 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp index 22caeb8..4d1b4b9 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp @@ -210,6 +210,8 @@ bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts, namespace { typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> > MacroDefinitionsMap; + typedef llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > + DeclsMap; } /// \brief Collect the macro definitions provided by the given preprocessor @@ -377,12 +379,6 @@ bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, PP.getLangOpts()); } -void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI, - unsigned ID) { - PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID); - ++NumHeaderInfos; -} - void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) { PP.setCounterValue(Value); } @@ -765,6 +761,10 @@ bool ASTReader::ReadDeclContextStorage(ModuleFile &M, void ASTReader::Error(StringRef Msg) { Error(diag::err_fe_pch_malformed, Msg); + if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight()) { + Diag(diag::note_module_cache_path) + << PP.getHeaderSearchInfo().getModuleCachePath(); + } } void ASTReader::Error(unsigned DiagID, @@ -1103,7 +1103,7 @@ bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) { } } -Token ASTReader::ReadToken(ModuleFile &F, const RecordData &Record, +Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record, unsigned &Idx) { Token Tok; Tok.startToken(); @@ -1283,6 +1283,8 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, using namespace clang::io; HeaderFileInfo HFI; unsigned Flags = *d++; + HFI.HeaderRole = static_cast<ModuleMap::ModuleHeaderRole> + ((Flags >> 6) & 0x03); HFI.isImport = (Flags >> 5) & 0x01; HFI.isPragmaOnce = (Flags >> 4) & 0x01; HFI.DirInfo = (Flags >> 2) & 0x03; @@ -1309,7 +1311,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, FileManager &FileMgr = Reader.getFileManager(); ModuleMap &ModMap = Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - ModMap.addHeader(Mod, FileMgr.getFile(key.Filename), /*Excluded=*/false); + ModMap.addHeader(Mod, FileMgr.getFile(key.Filename), HFI.getHeaderRole()); } } @@ -1587,18 +1589,21 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II, /// \brief For the given macro definitions, check if they are both in system /// modules. static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI, - Module *NewOwner, ASTReader &Reader) { + Module *NewOwner, ASTReader &Reader) { assert(PrevMI && NewMI); - if (!NewOwner) - return false; Module *PrevOwner = 0; if (SubmoduleID PrevModID = PrevMI->getOwningModuleID()) PrevOwner = Reader.getSubmodule(PrevModID); - if (!PrevOwner) - return false; - if (PrevOwner == NewOwner) + SourceManager &SrcMgr = Reader.getSourceManager(); + bool PrevInSystem + = PrevOwner? PrevOwner->IsSystem + : SrcMgr.isInSystemHeader(PrevMI->getDefinitionLoc()); + bool NewInSystem + = NewOwner? NewOwner->IsSystem + : SrcMgr.isInSystemHeader(NewMI->getDefinitionLoc()); + if (PrevOwner && PrevOwner == NewOwner) return false; - return PrevOwner->IsSystem && NewOwner->IsSystem; + return PrevInSystem && NewInSystem; } void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD, @@ -1721,6 +1726,10 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { )) { if (Complain) { Error(diag::err_fe_pch_file_modified, Filename, F.FileName); + if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight()) { + Diag(diag::note_module_cache_path) + << PP.getHeaderSearchInfo().getModuleCachePath(); + } } IsOutOfDate = true; @@ -2515,9 +2524,10 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) { break; case SEMA_DECL_REFS: - // Later tables overwrite earlier ones. - // FIXME: Modules will have some trouble with this. - SemaDeclRefs.clear(); + if (Record.size() != 2) { + Error("Invalid SEMA_DECL_REFS block"); + return true; + } for (unsigned I = 0, N = Record.size(); I != N; ++I) SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I])); break; @@ -2742,6 +2752,11 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) { // FIXME: Not used yet. break; } + + case LATE_PARSED_TEMPLATE: { + LateParsedTemplates.append(Record.begin(), Record.end()); + break; + } } } } @@ -2805,13 +2820,12 @@ void ASTReader::makeModuleVisible(Module *Mod, bool Complain) { llvm::SmallPtrSet<Module *, 4> Visited; SmallVector<Module *, 4> Stack; - Stack.push_back(Mod); + Stack.push_back(Mod); while (!Stack.empty()) { - Mod = Stack.back(); - Stack.pop_back(); + Mod = Stack.pop_back_val(); if (NameVisibility <= Mod->NameVisibility) { - // This module already has this level of visibility (or greater), so + // This module already has this level of visibility (or greater), so // there is nothing more to do. continue; } @@ -2831,16 +2845,7 @@ void ASTReader::makeModuleVisible(Module *Mod, makeNamesVisible(Hidden->second, Hidden->first); HiddenNamesMap.erase(Hidden); } - - // Push any non-explicit submodules onto the stack to be marked as - // visible. - for (Module::submodule_iterator Sub = Mod->submodule_begin(), - SubEnd = Mod->submodule_end(); - Sub != SubEnd; ++Sub) { - if (!(*Sub)->IsExplicit && Visited.insert(*Sub)) - Stack.push_back(*Sub); - } - + // Push any exported modules onto the stack to be marked as visible. SmallVector<Module *, 16> Exports; Mod->getExportedModules(Exports); @@ -2898,6 +2903,9 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, ModuleKind Type, SourceLocation ImportLoc, unsigned ClientLoadCapabilities) { + llvm::SaveAndRestore<SourceLocation> + SetCurImportLocRAII(CurrentImportLoc, ImportLoc); + // Bump the generation number. unsigned PreviousGeneration = CurrentGeneration++; @@ -3012,9 +3020,16 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, } } UnresolvedModuleRefs.clear(); + + // FIXME: How do we load the 'use'd modules? They may not be submodules. + // Might be unnecessary as use declarations are only used to build the + // module itself. InitializeContext(); + if (SemaObj) + UpdateSema(); + if (DeserializationListener) DeserializationListener->ReaderInitialized(this); @@ -3759,6 +3774,21 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) { break; } + case SUBMODULE_PRIVATE_HEADER: { + if (First) { + Error("missing submodule metadata record at beginning of block"); + return true; + } + + if (!CurrentModule) + break; + + // We lazily associate headers with their modules via the HeaderInfoTable. + // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead + // of complete filenames or remove it entirely. + break; + } + case SUBMODULE_TOPHEADER: { if (First) { Error("missing submodule metadata record at beginning of block"); @@ -3873,7 +3903,7 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) { if (!CurrentModule) break; - CurrentModule->addRequirement(Blob, Context.getLangOpts(), + CurrentModule->addRequirement(Blob, Record[0], Context.getLangOpts(), Context.getTargetInfo()); break; } @@ -4394,11 +4424,8 @@ namespace { HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { HeaderFileInfoVisitor Visitor(FE); ModuleMgr.visit(&HeaderFileInfoVisitor::visit, &Visitor); - if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) { - if (Listener) - Listener->ReadHeaderFileInfo(*HFI, FE->getUID()); + if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) return *HFI; - } return HeaderFileInfo(); } @@ -4509,6 +4536,18 @@ QualType ASTReader::readTypeRecord(unsigned Index) { return Context.getPointerType(PointeeType); } + case TYPE_DECAYED: { + if (Record.size() != 1) { + Error("Incorrect encoding of decayed type"); + return QualType(); + } + QualType OriginalType = readType(*Loc.F, Record, Idx); + QualType DT = Context.getAdjustedParameterType(OriginalType); + if (!isa<DecayedType>(DT)) + Error("Decayed type does not decay"); + return DT; + } + case TYPE_BLOCK_POINTER: { if (Record.size() != 1) { Error("Incorrect encoding of block pointer type"); @@ -4955,6 +4994,9 @@ void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) { void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) { TL.setStarLoc(ReadSourceLocation(Record, Idx)); } +void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) { + // nothing to do +} void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { TL.setCaretLoc(ReadSourceLocation(Record, Idx)); } @@ -5315,6 +5357,19 @@ ASTReader::ReadTemplateArgumentLoc(ModuleFile &F, Record, Index)); } +const ASTTemplateArgumentListInfo* +ASTReader::ReadASTTemplateArgumentListInfo(ModuleFile &F, + const RecordData &Record, + unsigned &Index) { + SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Index); + SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Index); + unsigned NumArgsAsWritten = Record[Index++]; + TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc); + for (unsigned i = 0; i != NumArgsAsWritten; ++i) + TemplArgsInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Index)); + return ASTTemplateArgumentListInfo::Create(getContext(), TemplArgsInfo); +} + Decl *ASTReader::GetExternalDecl(uint32_t ID) { return GetDecl(ID); } @@ -5775,15 +5830,13 @@ namespace { class DeclContextAllNamesVisitor { ASTReader &Reader; SmallVectorImpl<const DeclContext *> &Contexts; - llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls; + DeclsMap &Decls; bool VisitAll; public: DeclContextAllNamesVisitor(ASTReader &Reader, SmallVectorImpl<const DeclContext *> &Contexts, - llvm::DenseMap<DeclarationName, - SmallVector<NamedDecl *, 8> > &Decls, - bool VisitAll) + DeclsMap &Decls, bool VisitAll) : Reader(Reader), Contexts(Contexts), Decls(Decls), VisitAll(VisitAll) { } static bool visit(ModuleFile &M, void *UserData) { @@ -5834,7 +5887,7 @@ namespace { void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) { if (!DC->hasExternalVisibleStorage()) return; - llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > Decls; + DeclsMap Decls; // Compute the declaration contexts we need to look into. Multiple such // declaration contexts occur when two declaration contexts from disjoint @@ -5857,9 +5910,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) { ModuleMgr.visit(&DeclContextAllNamesVisitor::visit, &Visitor); ++NumVisibleDeclContextsRead; - for (llvm::DenseMap<DeclarationName, - SmallVector<NamedDecl *, 8> >::iterator - I = Decls.begin(), E = Decls.end(); I != E; ++I) { + for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) { SetExternalVisibleDeclsForName(DC, I->first, I->second); } const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false); @@ -6080,21 +6131,13 @@ void ASTReader::InitializeSema(Sema &S) { } PreloadedDecls.clear(); - // Load the offsets of the declarations that Sema references. - // They will be lazily deserialized when needed. - if (!SemaDeclRefs.empty()) { - assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!"); - if (!SemaObj->StdNamespace) - SemaObj->StdNamespace = SemaDeclRefs[0]; - if (!SemaObj->StdBadAlloc) - SemaObj->StdBadAlloc = SemaDeclRefs[1]; - } - + // FIXME: What happens if these are changed by a module import? if (!FPPragmaOptions.empty()) { assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS"); SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0]; } + // FIXME: What happens if these are changed by a module import? if (!OpenCLExtensions.empty()) { unsigned I = 0; #define OPENCLEXT(nm) SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++]; @@ -6102,6 +6145,25 @@ void ASTReader::InitializeSema(Sema &S) { assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS"); } + + UpdateSema(); +} + +void ASTReader::UpdateSema() { + assert(SemaObj && "no Sema to update"); + + // Load the offsets of the declarations that Sema references. + // They will be lazily deserialized when needed. + if (!SemaDeclRefs.empty()) { + assert(SemaDeclRefs.size() % 2 == 0); + for (unsigned I = 0; I != SemaDeclRefs.size(); I += 2) { + if (!SemaObj->StdNamespace) + SemaObj->StdNamespace = SemaDeclRefs[I]; + if (!SemaObj->StdBadAlloc) + SemaObj->StdBadAlloc = SemaDeclRefs[I+1]; + } + SemaDeclRefs.clear(); + } } IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) { @@ -6440,6 +6502,29 @@ void ASTReader::ReadPendingInstantiations( PendingInstantiations.clear(); } +void ASTReader::ReadLateParsedTemplates( + llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) { + for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N; + /* In loop */) { + FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++])); + + LateParsedTemplate *LT = new LateParsedTemplate; + LT->D = GetDecl(LateParsedTemplates[Idx++]); + + ModuleFile *F = getOwningModuleFile(LT->D); + assert(F && "No module"); + + unsigned TokN = LateParsedTemplates[Idx++]; + LT->Toks.reserve(TokN); + for (unsigned T = 0; T < TokN; ++T) + LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx)); + + LPTMap[FD] = LT; + } + + LateParsedTemplates.clear(); +} + void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel); @@ -6887,7 +6972,7 @@ ASTReader::ReadTemplateParameterList(ModuleFile &F, void ASTReader:: -ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs, +ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, ModuleFile &F, const RecordData &Record, unsigned &Idx) { unsigned NumTemplateArgs = Record[Idx++]; @@ -6897,14 +6982,14 @@ ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs, } /// \brief Read a UnresolvedSet structure. -void ASTReader::ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set, +void ASTReader::ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set, const RecordData &Record, unsigned &Idx) { unsigned NumDecls = Record[Idx++]; Set.reserve(Context, NumDecls); while (NumDecls--) { - NamedDecl *D = ReadDeclAs<NamedDecl>(F, Record, Idx); + DeclID ID = ReadDeclID(F, Record, Idx); AccessSpecifier AS = (AccessSpecifier)Record[Idx++]; - Set.addDecl(Context, D, AS); + Set.addLazyDecl(Context, ID, AS); } } @@ -6991,9 +7076,16 @@ ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc); } else { - BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc, - LParenLoc, Init, RParenLoc, - Indices.data(), Indices.size()); + if (IndirectMember) { + assert(Indices.empty() && "Indirect field improperly initialized"); + BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember, + MemberOrEllipsisLoc, LParenLoc, + Init, RParenLoc); + } else { + BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc, + LParenLoc, Init, RParenLoc, + Indices.data(), Indices.size()); + } } if (IsWritten) @@ -7168,7 +7260,7 @@ CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F, } DiagnosticBuilder ASTReader::Diag(unsigned DiagID) { - return Diag(SourceLocation(), DiagID); + return Diag(CurrentImportLoc, DiagID); } DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) { @@ -7251,10 +7343,14 @@ void ASTReader::ReadComments() { void ASTReader::finishPendingActions() { while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() || - !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty()) { + !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() || + !PendingOdrMergeChecks.empty()) { // If any identifiers with corresponding top-level declarations have // been loaded, load those declarations now. - llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> > TopLevelDecls; + typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> > + TopLevelDeclsMap; + TopLevelDeclsMap TopLevelDecls; + while (!PendingIdentifierInfos.empty()) { // FIXME: std::move IdentifierInfo *II = PendingIdentifierInfos.back().first; @@ -7272,9 +7368,8 @@ void ASTReader::finishPendingActions() { PendingDeclChains.clear(); // Make the most recent of the top-level declarations visible. - for (llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> >::iterator - TLD = TopLevelDecls.begin(), TLDEnd = TopLevelDecls.end(); - TLD != TLDEnd; ++TLD) { + for (TopLevelDeclsMap::iterator TLD = TopLevelDecls.begin(), + TLDEnd = TopLevelDecls.end(); TLD != TLDEnd; ++TLD) { IdentifierInfo *II = TLD->first; for (unsigned I = 0, N = TLD->second.size(); I != N; ++I) { pushExternalDeclIntoScope(cast<NamedDecl>(TLD->second[I]), II); @@ -7312,6 +7407,64 @@ void ASTReader::finishPendingActions() { DeclContext *LexicalDC = cast<DeclContext>(GetDecl(Info.LexicalDC)); Info.D->setDeclContextsImpl(SemaDC, LexicalDC, getContext()); } + + // For each declaration from a merged context, check that the canonical + // definition of that context also contains a declaration of the same + // entity. + while (!PendingOdrMergeChecks.empty()) { + NamedDecl *D = PendingOdrMergeChecks.pop_back_val(); + + // FIXME: Skip over implicit declarations for now. This matters for things + // like implicitly-declared special member functions. This isn't entirely + // correct; we can end up with multiple unmerged declarations of the same + // implicit entity. + if (D->isImplicit()) + continue; + + DeclContext *CanonDef = D->getDeclContext(); + DeclContext::lookup_result R = CanonDef->lookup(D->getDeclName()); + + bool Found = false; + const Decl *DCanon = D->getCanonicalDecl(); + + llvm::SmallVector<const NamedDecl*, 4> Candidates; + for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); + !Found && I != E; ++I) { + for (Decl::redecl_iterator RI = (*I)->redecls_begin(), + RE = (*I)->redecls_end(); + RI != RE; ++RI) { + if ((*RI)->getLexicalDeclContext() == CanonDef) { + // This declaration is present in the canonical definition. If it's + // in the same redecl chain, it's the one we're looking for. + if ((*RI)->getCanonicalDecl() == DCanon) + Found = true; + else + Candidates.push_back(cast<NamedDecl>(*RI)); + break; + } + } + } + + if (!Found) { + D->setInvalidDecl(); + + Module *CanonDefModule = cast<Decl>(CanonDef)->getOwningModule(); + Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl) + << D << D->getOwningModule()->getFullModuleName() + << CanonDef << !CanonDefModule + << (CanonDefModule ? CanonDefModule->getFullModuleName() : ""); + + if (Candidates.empty()) + Diag(cast<Decl>(CanonDef)->getLocation(), + diag::note_module_odr_violation_no_possible_decls) << D; + else { + for (unsigned I = 0, N = Candidates.size(); I != N; ++I) + Diag(Candidates[I]->getLocation(), + diag::note_module_odr_violation_possible_decl) + << Candidates[I]; + } + } + } } // If we deserialized any C++ or Objective-C class definitions, any @@ -7418,7 +7571,7 @@ void ASTReader::FinishedDeserializing() { } void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { - D = cast<NamedDecl>(D->getMostRecentDecl()); + D = D->getMostRecentDecl(); if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) { SemaObj->TUScope->AddDecl(D); @@ -7454,7 +7607,7 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0), TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0), PassingDeclsToConsumer(false), - NumCXXBaseSpecifiersLoaded(0) + NumCXXBaseSpecifiersLoaded(0), ReadingKind(Read_None) { SourceMgr.setExternalSLocEntrySource(this); } |