diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp | 264 |
1 files changed, 164 insertions, 100 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp index c97c2d8..0fa4f93 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp @@ -133,11 +133,66 @@ namespace clang { void AddFunctionDefinition(const FunctionDecl *FD) { assert(FD->doesThisDeclarationHaveABody()); - if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) - Writer.AddCXXCtorInitializers(CD->CtorInitializers, - CD->NumCtorInitializers, Record); + if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) { + Record.push_back(CD->NumCtorInitializers); + if (CD->NumCtorInitializers) + Writer.AddCXXCtorInitializersRef( + llvm::makeArrayRef(CD->init_begin(), CD->init_end()), Record); + } Writer.AddStmt(FD->getBody()); } + + /// Get the specialization decl from an entry in the specialization list. + template <typename EntryType> + typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * + getSpecializationDecl(EntryType &T) { + return RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::getDecl(&T); + } + + /// Get the list of partial specializations from a template's common ptr. + template<typename T> + decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) { + return Common->PartialSpecializations; + } + ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) { + return None; + } + + template<typename Decl> + void AddTemplateSpecializations(Decl *D) { + auto *Common = D->getCommonPtr(); + + // If we have any lazy specializations, and the external AST source is + // our chained AST reader, we can just write out the DeclIDs. Otherwise, + // we need to resolve them to actual declarations. + if (Writer.Chain != Writer.Context->getExternalSource() && + Common->LazySpecializations) { + D->LoadLazySpecializations(); + assert(!Common->LazySpecializations); + } + + auto &Specializations = Common->Specializations; + auto &&PartialSpecializations = getPartialSpecializations(Common); + ArrayRef<DeclID> LazySpecializations; + if (auto *LS = Common->LazySpecializations) + LazySpecializations = ArrayRef<DeclID>(LS + 1, LS + 1 + LS[0]); + + Record.push_back(Specializations.size() + + PartialSpecializations.size() + + LazySpecializations.size()); + for (auto &Entry : Specializations) { + auto *D = getSpecializationDecl(Entry); + assert(D->isCanonicalDecl() && "non-canonical decl in set"); + Writer.AddDeclRef(D, Record); + } + for (auto &Entry : PartialSpecializations) { + auto *D = getSpecializationDecl(Entry); + assert(D->isCanonicalDecl() && "non-canonical decl in set"); + Writer.AddDeclRef(D, Record); + } + for (DeclID ID : LazySpecializations) + Record.push_back(ID); + } }; } @@ -157,7 +212,7 @@ void ASTDeclWriter::Visit(Decl *D) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { Record.push_back(FD->doesThisDeclarationHaveABody()); if (FD->doesThisDeclarationHaveABody()) - Writer.AddStmt(FD->getBody()); + AddFunctionDefinition(FD); } } @@ -188,7 +243,7 @@ void ASTDeclWriter::VisitDecl(Decl *D) { while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) { if (!NS->isFromASTFile()) break; - Writer.AddUpdatedDeclContext(NS->getPrimaryContext()); + Writer.UpdatedDeclContexts.insert(NS->getPrimaryContext()); if (!NS->isInlineNamespace()) break; DC = NS->getParent(); @@ -203,8 +258,9 @@ void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) { VisitDecl(D); Writer.AddDeclarationName(D->getDeclName(), Record); - if (needsAnonymousDeclarationNumber(D)) - Record.push_back(Writer.getAnonymousDeclarationNumber(D)); + Record.push_back(needsAnonymousDeclarationNumber(D) + ? Writer.getAnonymousDeclarationNumber(D) + : 0); } void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) { @@ -658,8 +714,10 @@ void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record); Record.push_back(D->hasNonZeroConstructors()); Record.push_back(D->hasDestructors()); - Writer.AddCXXCtorInitializers(D->IvarInitializers, D->NumIvarInitializers, - Record); + Record.push_back(D->NumIvarInitializers); + if (D->NumIvarInitializers) + Writer.AddCXXCtorInitializersRef( + llvm::makeArrayRef(D->init_begin(), D->init_end()), Record); Code = serialization::DECL_OBJC_IMPLEMENTATION; } @@ -732,13 +790,15 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(D->getStorageClass()); Record.push_back(D->getTSCSpec()); Record.push_back(D->getInitStyle()); - Record.push_back(D->isExceptionVariable()); - Record.push_back(D->isNRVOVariable()); - Record.push_back(D->isCXXForRangeDecl()); - Record.push_back(D->isARCPseudoStrong()); - Record.push_back(D->isConstexpr()); - Record.push_back(D->isInitCapture()); - Record.push_back(D->isPreviousDeclInSameBlockScope()); + if (!isa<ParmVarDecl>(D)) { + Record.push_back(D->isExceptionVariable()); + Record.push_back(D->isNRVOVariable()); + Record.push_back(D->isCXXForRangeDecl()); + Record.push_back(D->isARCPseudoStrong()); + Record.push_back(D->isConstexpr()); + Record.push_back(D->isInitCapture()); + Record.push_back(D->isPreviousDeclInSameBlockScope()); + } Record.push_back(D->getLinkageInternal()); if (D->getInit()) { @@ -920,17 +980,34 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { if (Writer.hasChain() && !D->isOriginalNamespace() && D->getOriginalNamespace()->isFromASTFile()) { NamespaceDecl *NS = D->getOriginalNamespace(); - Writer.AddUpdatedDeclContext(NS); - - // Make sure all visible decls are written. They will be recorded later. - if (StoredDeclsMap *Map = NS->buildLookup()) { - for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); - D != DEnd; ++D) { - DeclContext::lookup_result R = D->second.getLookupResult(); - for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; - ++I) - Writer.GetDeclRef(*I); + Writer.UpdatedDeclContexts.insert(NS); + + // Make sure all visible decls are written. They will be recorded later. We + // do this using a side data structure so we can sort the names into + // a deterministic order. + StoredDeclsMap *Map = NS->buildLookup(); + SmallVector<std::pair<DeclarationName, DeclContext::lookup_result>, 16> + LookupResults; + LookupResults.reserve(Map->size()); + for (auto &Entry : *Map) + LookupResults.push_back( + std::make_pair(Entry.first, Entry.second.getLookupResult())); + + std::sort(LookupResults.begin(), LookupResults.end(), llvm::less_first()); + for (auto &NameAndResult : LookupResults) { + DeclarationName Name = NameAndResult.first; + DeclContext::lookup_result Result = NameAndResult.second; + if (Name.getNameKind() == DeclarationName::CXXConstructorName || + Name.getNameKind() == DeclarationName::CXXConversionFunctionName) { + // We have to work around a name lookup bug here where negative lookup + // results for these names get cached in namespace lookup tables. + assert(Result.empty() && "Cannot have a constructor or conversion " + "function name in a namespace!"); + continue; } + + for (NamedDecl *ND : Result) + Writer.GetDeclRef(ND); } } @@ -1067,8 +1144,6 @@ void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { Writer.AddDeclRef(D->getInheritedConstructor(), Record); Record.push_back(D->IsExplicitSpecified); - Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers, - Record); Code = serialization::DECL_CXX_CONSTRUCTOR; } @@ -1076,7 +1151,7 @@ void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) { VisitCXXMethodDecl(D); - Writer.AddDeclRef(D->OperatorDelete, Record); + Writer.AddDeclRef(D->getOperatorDelete(), Record); Code = serialization::DECL_CXX_DESTRUCTOR; } @@ -1171,24 +1246,8 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDecl()) { - typedef llvm::FoldingSetVector<ClassTemplateSpecializationDecl> CTSDSetTy; - CTSDSetTy &CTSDSet = D->getSpecializations(); - Record.push_back(CTSDSet.size()); - for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - - typedef llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> - CTPSDSetTy; - CTPSDSetTy &CTPSDSet = D->getPartialSpecializations(); - Record.push_back(CTPSDSet.size()); - for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E=CTPSDSet.end(); I!=E; ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - } + if (D->isFirstDecl()) + AddTemplateSpecializations(D); Code = serialization::DECL_CLASS_TEMPLATE; } @@ -1246,26 +1305,8 @@ void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl( void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDecl()) { - typedef llvm::FoldingSetVector<VarTemplateSpecializationDecl> VTSDSetTy; - VTSDSetTy &VTSDSet = D->getSpecializations(); - Record.push_back(VTSDSet.size()); - for (VTSDSetTy::iterator I = VTSDSet.begin(), E = VTSDSet.end(); I != E; - ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - - typedef llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> - VTPSDSetTy; - VTPSDSetTy &VTPSDSet = D->getPartialSpecializations(); - Record.push_back(VTPSDSet.size()); - for (VTPSDSetTy::iterator I = VTPSDSet.begin(), E = VTPSDSet.end(); I != E; - ++I) { - assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); - Writer.AddDeclRef(&*I, Record); - } - } + if (D->isFirstDecl()) + AddTemplateSpecializations(D); Code = serialization::DECL_VAR_TEMPLATE; } @@ -1330,19 +1371,8 @@ void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDecl()) { - // This FunctionTemplateDecl owns the CommonPtr; write it. - - // Write the function specialization declarations. - Record.push_back(D->getSpecializations().size()); - for (llvm::FoldingSetVector<FunctionTemplateSpecializationInfo>::iterator - I = D->getSpecializations().begin(), - E = D->getSpecializations().end() ; I != E; ++I) { - assert(I->Function->isCanonicalDecl() && - "Expected only canonical decls in set"); - Writer.AddDeclRef(I->Function, Record); - } - } + if (D->isFirstDecl()) + AddTemplateSpecializations(D); Code = serialization::DECL_FUNCTION_TEMPLATE; } @@ -1448,25 +1478,59 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, template <typename T> void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { T *First = D->getFirstDecl(); - if (First->getMostRecentDecl() != First) { + T *MostRecent = First->getMostRecentDecl(); + if (MostRecent != First) { assert(isRedeclarableDeclKind(static_cast<T *>(D)->getKind()) && "Not considered redeclarable?"); - + // There is more than one declaration of this entity, so we will need to // write a redeclaration chain. Writer.AddDeclRef(First, Record); Writer.Redeclarations.insert(First); + auto *Previous = D->getPreviousDecl(); + + // In a modules build, we can have imported declarations after a local + // canonical declaration. If this is the first local declaration, emit + // a list of all such imported declarations so that we can ensure they + // are loaded before we are. This allows us to rebuild the redecl chain + // in the right order on reload (all declarations imported by a module + // should be before all declarations provided by that module). + bool EmitImportedMergedCanonicalDecls = false; + if (Context.getLangOpts().Modules && Writer.Chain) { + auto *PreviousLocal = Previous; + while (PreviousLocal && PreviousLocal->isFromASTFile()) + PreviousLocal = PreviousLocal->getPreviousDecl(); + if (!PreviousLocal) + EmitImportedMergedCanonicalDecls = true; + } + if (EmitImportedMergedCanonicalDecls) { + llvm::SmallMapVector<ModuleFile*, Decl*, 16> FirstInModule; + for (auto *Redecl = MostRecent; Redecl; + Redecl = Redecl->getPreviousDecl()) + if (Redecl->isFromASTFile()) + FirstInModule[Writer.Chain->getOwningModuleFile(Redecl)] = Redecl; + // FIXME: If FirstInModule has entries for modules A and B, and B imports + // A (directly or indirectly), we don't need to write the entry for A. + Record.push_back(FirstInModule.size()); + for (auto I = FirstInModule.rbegin(), E = FirstInModule.rend(); + I != E; ++I) + Writer.AddDeclRef(I->second, Record); + } else + Record.push_back(0); + // Make sure that we serialize both the previous and the most-recent // declarations, which (transitively) ensures that all declarations in the // chain get serialized. - (void)Writer.GetDeclRef(D->getPreviousDecl()); - (void)Writer.GetDeclRef(First->getMostRecentDecl()); + // + // FIXME: This is not correct; when we reach an imported declaration we + // won't emit its previous declaration. + (void)Writer.GetDeclRef(Previous); + (void)Writer.GetDeclRef(MostRecent); } else { // We use the sentinel value 0 to indicate an only declaration. Record.push_back(0); } - } void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { @@ -1504,6 +1568,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // ValueDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DeclaratorDecl @@ -1536,6 +1601,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // ValueDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DeclaratorDecl @@ -1573,6 +1639,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // TypeDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref @@ -1620,6 +1687,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // TypeDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref @@ -1662,6 +1730,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // ValueDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DeclaratorDecl @@ -1671,13 +1740,6 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // StorageClass Abv->Add(BitCodeAbbrevOp(0)); // getTSCSpec Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer - Abv->Add(BitCodeAbbrevOp(0)); // isExceptionVariable - Abv->Add(BitCodeAbbrevOp(0)); // isNRVOVariable - Abv->Add(BitCodeAbbrevOp(0)); // isCXXForRangeDecl - Abv->Add(BitCodeAbbrevOp(0)); // isARCPseudoStrong - Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr - Abv->Add(BitCodeAbbrevOp(0)); // isInitCapture - Abv->Add(BitCodeAbbrevOp(0)); // isPrevDeclInSameScope Abv->Add(BitCodeAbbrevOp(0)); // Linkage Abv->Add(BitCodeAbbrevOp(0)); // HasInit Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo @@ -1715,6 +1777,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // TypeDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref @@ -1743,6 +1806,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // ValueDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DeclaratorDecl @@ -1788,6 +1852,7 @@ void ASTWriter::WriteDeclAbbrevs() { // NamedDecl Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber // ValueDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DeclaratorDecl @@ -1948,9 +2013,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Determine the ID for this declaration. serialization::DeclID ID; - if (D->isFromASTFile()) + if (D->isFromASTFile()) { + assert(isRewritten(D) && "should not be emitting imported decl"); ID = getDeclID(D); - else { + } else { serialization::DeclID &IDR = DeclIDs[D]; if (IDR == 0) IDR = NextDeclID++; @@ -2015,12 +2081,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { D->getDeclKindName() + "'"); Stream.EmitRecord(W.Code, Record, W.AbbrevToUse); - // Flush any expressions that were written as part of this declaration. - FlushStmts(); - - // Flush C++ base specifiers, if there are any. - FlushCXXBaseSpecifiers(); - + // Flush any expressions, base specifiers, and ctor initializers that + // were written as part of this declaration. + FlushPendingAfterDecl(); + // Note declarations that should be deserialized eagerly so that we can add // them to a record in the AST file later. if (isRequiredDecl(D, Context)) |