diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 13cc256e404620c1de0cbcc4e43ce1e2dbbc4898 (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /lib/Serialization/ASTReaderDecl.cpp | |
parent | 657bc3d9848e3be92029b2416031340988cd0111 (diff) | |
download | src-test2-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.tar.gz src-test2-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.zip |
Notes
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 151 |
1 files changed, 95 insertions, 56 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index cb21f82600e0..c42944df6344 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -37,7 +37,6 @@ namespace clang { class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> { ASTReader &Reader; ModuleFile &F; - llvm::BitstreamCursor &Cursor; const DeclID ThisDeclID; const unsigned RawLocation; typedef ASTReader::RecordData RecordData; @@ -48,6 +47,8 @@ namespace clang { DeclID DeclContextIDForTemplateParmDecl; DeclID LexicalDeclContextIDForTemplateParmDecl; + bool HasPendingBody; + uint64_t GetCurrentCursorOffset(); SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) { @@ -116,7 +117,7 @@ namespace clang { GlobalDeclID FirstID; mutable bool Owning; - RedeclarableResult &operator=(RedeclarableResult&); // DO NOT IMPLEMENT + void operator=(RedeclarableResult &) LLVM_DELETED_FUNCTION; public: RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID) @@ -162,7 +163,7 @@ namespace clang { NamedDecl *Existing; mutable bool AddResult; - FindExistingResult &operator=(FindExistingResult&); // DO NOT IMPLEMENT + void operator=(FindExistingResult&) LLVM_DELETED_FUNCTION; public: FindExistingResult(ASTReader &Reader) @@ -194,16 +195,19 @@ namespace clang { public: ASTDeclReader(ASTReader &Reader, ModuleFile &F, - llvm::BitstreamCursor &Cursor, DeclID thisDeclID, + DeclID thisDeclID, unsigned RawLocation, const RecordData &Record, unsigned &Idx) - : Reader(Reader), F(F), Cursor(Cursor), ThisDeclID(thisDeclID), + : Reader(Reader), F(F), ThisDeclID(thisDeclID), RawLocation(RawLocation), Record(Record), Idx(Idx), - TypeIDForTypeDecl(0) { } + TypeIDForTypeDecl(0), HasPendingBody(false) { } static void attachPreviousDecl(Decl *D, Decl *previous); static void attachLatestDecl(Decl *D, Decl *latest); + /// \brief Determine whether this declaration has a pending body. + bool hasPendingBody() const { return HasPendingBody; } + void Visit(Decl *D); void UpdateDecl(Decl *D, ModuleFile &ModuleFile, @@ -321,8 +325,14 @@ void ASTDeclReader::Visit(Decl *D) { ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull(); } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { // FunctionDecl's body was written last after all other Stmts/Exprs. - if (Record[Idx++]) - FD->setLazyBody(GetCurrentCursorOffset()); + // We only read it if FD doesn't already have a body (e.g., from another + // module). + // FIXME: Also consider = default and = delete. + // FIXME: Can we diagnose ODR violations somehow? + if (Record[Idx++]) { + Reader.PendingBodies[FD] = GetCurrentCursorOffset(); + HasPendingBody = true; + } } else if (D->isTemplateParameter()) { // If we have a fully initialized template parameter, we can now // set its DeclContext. @@ -590,8 +600,10 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { TemplArgs.size(), C); void *InsertPos = 0; CanonTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); - assert(InsertPos && "Another specialization already inserted!"); - CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos); + if (InsertPos) + CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos); + else + assert(0 && "Another specialization already inserted!"); } break; } @@ -628,19 +640,16 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { VisitNamedDecl(MD); if (Record[Idx++]) { - // In practice, this won't be executed (since method definitions - // don't occur in header files). - // Switch case IDs for this method body. - ASTReader::SwitchCaseMapTy SwitchCaseStmtsForObjCMethod; - SaveAndRestore<ASTReader::SwitchCaseMapTy *> - SCFOM(Reader.CurrSwitchCaseStmts, &SwitchCaseStmtsForObjCMethod); - MD->setBody(Reader.ReadStmt(F)); + // Load the body on-demand. Most clients won't care, because method + // definitions rarely show up in headers. + Reader.PendingBodies[MD] = GetCurrentCursorOffset(); + HasPendingBody = true; MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx)); MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx)); } MD->setInstanceMethod(Record[Idx++]); MD->setVariadic(Record[Idx++]); - MD->setSynthesized(Record[Idx++]); + MD->setPropertyAccessor(Record[Idx++]); MD->setDefined(Record[Idx++]); MD->IsOverriding = Record[Idx++]; @@ -846,6 +855,8 @@ void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx)); D->setIvarLBraceLoc(ReadSourceLocation(Record, Idx)); D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx)); + D->setHasNonZeroConstructors(Record[Idx++]); + D->setHasDestructors(Record[Idx++]); llvm::tie(D->IvarInitializers, D->NumIvarInitializers) = Reader.ReadCXXCtorInitializers(F, Record, Idx); } @@ -897,7 +908,8 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) { VD->VarDeclBits.NRVOVariable = Record[Idx++]; VD->VarDeclBits.CXXForRangeDecl = Record[Idx++]; VD->VarDeclBits.ARCPseudoStrong = Record[Idx++]; - + VD->VarDeclBits.IsConstexpr = Record[Idx++]; + // Only true variables (not parameters or implicit parameters) can be merged. if (VD->getKind() == Decl::Var) mergeRedeclarable(VD, Redecl); @@ -1135,6 +1147,7 @@ void ASTDeclReader::ReadCXXDefinitionData( Lambda.Captures = (Capture*)Reader.Context.Allocate(sizeof(Capture)*Lambda.NumCaptures); Capture *ToCapture = Lambda.Captures; + Lambda.MethodTyInfo = GetTypeSourceInfo(Record, Idx); for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { SourceLocation Loc = ReadSourceLocation(Record, Idx); bool IsImplicit = Record[Idx++]; @@ -1155,7 +1168,8 @@ void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { // allocate the appropriate DefinitionData structure. bool IsLambda = Record[Idx++]; if (IsLambda) - D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D, false); + D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D, 0, + false); else D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); @@ -1242,6 +1256,7 @@ void ASTDeclReader::VisitImportDecl(ImportDecl *D) { SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(D + 1); for (unsigned I = 0, N = Record.back(); I != N; ++I) StoredLocs[I] = ReadSourceLocation(Record, Idx); + ++Idx; // The number of stored source locations. } void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) { @@ -1308,10 +1323,12 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { D->setMemberSpecialization(); } } - + VisitTemplateDecl(D); D->IdentifierNamespace = Record[Idx++]; - + + mergeRedeclarable(D, Redecl); + return Redecl; } @@ -1336,10 +1353,10 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { for (unsigned I = 0; I != Size; ++I) SpecIDs.push_back(ReadDeclID(Record, Idx)); + ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr(); if (SpecIDs[0]) { typedef serialization::DeclID DeclID; - ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr(); // FIXME: Append specializations! CommonPtr->LazySpecializations = new (Reader.getContext()) DeclID [SpecIDs.size()]; @@ -1347,7 +1364,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { SpecIDs.size() * sizeof(DeclID)); } - // InjectedClassNameType is computed. + CommonPtr->InjectedClassNameType = Reader.readType(F, Record, Idx); } } @@ -1391,14 +1408,17 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl( TemplArgs.size()); D->PointOfInstantiation = ReadSourceLocation(Record, Idx); D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++]; - - if (D->isCanonicalDecl()) { // It's kept in the folding set. + + bool writtenAsCanonicalDecl = Record[Idx++]; + if (writtenAsCanonicalDecl) { ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(Record,Idx); - if (ClassTemplatePartialSpecializationDecl *Partial - = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { - CanonPattern->getCommonPtr()->PartialSpecializations.InsertNode(Partial); - } else { - CanonPattern->getCommonPtr()->Specializations.InsertNode(D); + if (D->isCanonicalDecl()) { // It's kept in the folding set. + if (ClassTemplatePartialSpecializationDecl *Partial + = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { + CanonPattern->getCommonPtr()->PartialSpecializations.GetOrInsertNode(Partial); + } else { + CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); + } } } } @@ -1486,11 +1506,18 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { // TemplateParmPosition. D->setDepth(Record[Idx++]); D->setPosition(Record[Idx++]); - // Rest of TemplateTemplateParmDecl. - TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(F, Record, Idx); - bool IsInherited = Record[Idx++]; - D->setDefaultArgument(Arg, IsInherited); - D->ParameterPack = Record[Idx++]; + if (D->isExpandedParameterPack()) { + void **Data = reinterpret_cast<void **>(D + 1); + for (unsigned I = 0, N = D->getNumExpansionTemplateParameters(); + I != N; ++I) + Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx); + } else { + // Rest of TemplateTemplateParmDecl. + TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(F, Record, Idx); + bool IsInherited = Record[Idx++]; + D->setDefaultArgument(Arg, IsInherited); + D->ParameterPack = Record[Idx++]; + } } void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { @@ -1640,7 +1667,7 @@ inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) { /// This routine should return true for anything that might affect /// code generation, e.g., inline function definitions, Objective-C /// declarations with metadata, etc. -static bool isConsumerInterestedIn(Decl *D) { +static bool isConsumerInterestedIn(Decl *D, bool HasBody) { // An ObjCMethodDecl is never considered as "interesting" because its // implementation container always is. @@ -1652,7 +1679,7 @@ static bool isConsumerInterestedIn(Decl *D) { return Var->isFileVarDecl() && Var->isThisDeclarationADefinition() == VarDecl::Definition; if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) - return Func->doesThisDeclarationHaveABody(); + return Func->doesThisDeclarationHaveABody() || HasBody; return false; } @@ -1719,8 +1746,10 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { if (TagDecl *TagX = dyn_cast<TagDecl>(X)) { TagDecl *TagY = cast<TagDecl>(Y); return (TagX->getTagKind() == TagY->getTagKind()) || - ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class) && - (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class)); + ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class || + TagX->getTagKind() == TTK_Interface) && + (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class || + TagY->getTagKind() == TTK_Interface)); } // Functions with the same type and linkage match. @@ -1731,7 +1760,7 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { return (FuncX->getLinkage() == FuncY->getLinkage()) && FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType()); } - + // Variables with the same type and linkage match. if (VarDecl *VarX = dyn_cast<VarDecl>(X)) { VarDecl *VarY = cast<VarDecl>(Y); @@ -1744,7 +1773,11 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y); return NamespaceX->isInline() == NamespaceY->isInline(); } - + + // Identical template names and kinds match. + if (isa<TemplateDecl>(X)) + return true; + // FIXME: Many other cases to implement. return false; } @@ -1753,11 +1786,13 @@ ASTDeclReader::FindExistingResult::~FindExistingResult() { if (!AddResult || Existing) return; - DeclContext *DC = New->getDeclContext()->getRedeclContext(); - if (DC->isTranslationUnit() && Reader.SemaObj) { + if (New->getDeclContext()->getRedeclContext()->isTranslationUnit() + && Reader.SemaObj) { Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, New->getDeclName()); - } else if (DC->isNamespace()) { - DC->addDecl(New); + } else { + DeclContext *DC = New->getLexicalDeclContext(); + if (DC->isNamespace()) + DC->addDecl(New); } } @@ -1899,7 +1934,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { RecordData Record; unsigned Code = DeclsCursor.ReadCode(); unsigned Idx = 0; - ASTDeclReader Reader(*this, *Loc.F, DeclsCursor, ID, RawLocation, Record,Idx); + ASTDeclReader Reader(*this, *Loc.F, ID, RawLocation, Record,Idx); Decl *D = 0; switch ((DeclCode)DeclsCursor.ReadRecord(Code, Record)) { @@ -2002,6 +2037,10 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_TEMPLATE_TEMPLATE_PARM: D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID); break; + case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK: + D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID, + Record[Idx++]); + break; case DECL_TYPE_ALIAS_TEMPLATE: D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID); break; @@ -2110,6 +2149,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { } PendingVisibleUpdates.erase(I); } + + if (!DC->hasExternalVisibleStorage() && DC->hasExternalLexicalStorage()) + DC->setMustBuildLookupTable(); } assert(Idx == Record.size()); @@ -2125,9 +2167,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // AST consumer might need to know about, queue it. // We don't pass it to the consumer immediately because we may be in recursive // loading, and some declarations may still be initializing. - if (isConsumerInterestedIn(D)) + if (isConsumerInterestedIn(D, Reader.hasPendingBody())) InterestingDecls.push_back(D); - + return D; } @@ -2152,7 +2194,7 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!"); unsigned Idx = 0; - ASTDeclReader Reader(*this, *F, Cursor, ID, 0, Record, Idx); + ASTDeclReader Reader(*this, *F, ID, 0, Record, Idx); Reader.UpdateDecl(D, *F, Record); } } @@ -2207,10 +2249,8 @@ namespace { if (!D) return; - if (Deserialized.count(D)) { - Deserialized.erase(D); + if (Deserialized.erase(D)) Chain.push_back(D); - } } void searchForID(ModuleFile &M, GlobalDeclID GlobalID) { @@ -2275,7 +2315,7 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { } MergedDeclsMap::iterator MergedPos = combineStoredMergedDecls(CanonDecl, ID); if (MergedPos != MergedDecls.end()) - SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end()); + SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end()); // Build up the list of redeclarations. RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID); @@ -2331,9 +2371,8 @@ namespace { void add(ObjCCategoryDecl *Cat) { // Only process each category once. - if (!Deserialized.count(Cat)) + if (!Deserialized.erase(Cat)) return; - Deserialized.erase(Cat); // Check for duplicate categories. if (Cat->getDeclName()) { |