diff options
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 660 |
1 files changed, 409 insertions, 251 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index efbaf92a849ae..7e2c4829b14ce 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1,4 +1,4 @@ -//===--- ASTReaderDecl.cpp - Decl Deserialization ---------------*- C++ -*-===// +//===- ASTReaderDecl.cpp - Decl Deserialization ---------------------------===// // // The LLVM Compiler Infrastructure // @@ -15,42 +15,89 @@ #include "ASTCommon.h" #include "ASTReaderInternals.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" +#include "clang/AST/AttrIterator.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclGroup.h" +#include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclVisitor.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExternalASTSource.h" +#include "clang/AST/LambdaCapture.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/Redeclarable.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" +#include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/AttrKinds.h" +#include "clang/Basic/ExceptionSpecificationType.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/Lambda.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/Linkage.h" +#include "clang/Basic/Module.h" +#include "clang/Basic/PragmaKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "clang/Sema/IdentifierResolver.h" #include "clang/Sema/SemaDiagnostic.h" +#include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Serialization/Module.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SaveAndRestore.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <cstring> +#include <string> +#include <utility> using namespace clang; -using namespace clang::serialization; +using namespace serialization; //===----------------------------------------------------------------------===// // Declaration deserialization //===----------------------------------------------------------------------===// namespace clang { + class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> { ASTReader &Reader; ASTRecordReader &Record; ASTReader::RecordLocation Loc; const DeclID ThisDeclID; const SourceLocation ThisDeclLoc; - typedef ASTReader::RecordData RecordData; - TypeID TypeIDForTypeDecl; + + using RecordData = ASTReader::RecordData; + + TypeID DeferredTypeID = 0; unsigned AnonymousDeclNumber; - GlobalDeclID NamedDeclForTagDecl; - IdentifierInfo *TypedefNameForLinkage; + GlobalDeclID NamedDeclForTagDecl = 0; + IdentifierInfo *TypedefNameForLinkage = nullptr; - bool HasPendingBody; + bool HasPendingBody = false; - ///\brief A flag to carry the information for a decl from the entity is + ///A flag to carry the information for a decl from the entity is /// used. We use it to delay the marking of the canonical decl as used until /// the entire declaration is deserialized and merged. - bool IsDeclMarkedUsed; + bool IsDeclMarkedUsed = false; uint64_t GetCurrentCursorOffset(); @@ -130,6 +177,8 @@ namespace clang { void MergeDefinitionData(ObjCProtocolDecl *D, struct ObjCProtocolDecl::DefinitionData &&NewDD); + static DeclContext *getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC); + static NamedDecl *getAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC, unsigned Index); @@ -144,39 +193,34 @@ namespace clang { public: RedeclarableResult(Decl *MergeWith, GlobalDeclID FirstID, bool IsKeyDecl) - : MergeWith(MergeWith), FirstID(FirstID), IsKeyDecl(IsKeyDecl) {} + : MergeWith(MergeWith), FirstID(FirstID), IsKeyDecl(IsKeyDecl) {} - /// \brief Retrieve the first ID. + /// Retrieve the first ID. GlobalDeclID getFirstID() const { return FirstID; } - /// \brief Is this declaration a key declaration? + /// Is this declaration a key declaration? bool isKeyDecl() const { return IsKeyDecl; } - /// \brief Get a known declaration that this should be merged with, if + /// Get a known declaration that this should be merged with, if /// any. Decl *getKnownMergeTarget() const { return MergeWith; } }; - /// \brief Class used to capture the result of searching for an existing + /// Class used to capture the result of searching for an existing /// declaration of a specific kind and name, along with the ability /// to update the place where this result was found (the declaration /// chain hanging off an identifier or the DeclContext we searched in) /// if requested. class FindExistingResult { ASTReader &Reader; - NamedDecl *New; - NamedDecl *Existing; - bool AddResult; - - unsigned AnonymousDeclNumber; - IdentifierInfo *TypedefNameForLinkage; - - void operator=(FindExistingResult &&) = delete; + NamedDecl *New = nullptr; + NamedDecl *Existing = nullptr; + bool AddResult = false; + unsigned AnonymousDeclNumber = 0; + IdentifierInfo *TypedefNameForLinkage = nullptr; public: - FindExistingResult(ASTReader &Reader) - : Reader(Reader), New(nullptr), Existing(nullptr), AddResult(false), - AnonymousDeclNumber(0), TypedefNameForLinkage(nullptr) {} + FindExistingResult(ASTReader &Reader) : Reader(Reader) {} FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing, unsigned AnonymousDeclNumber, @@ -193,9 +237,10 @@ namespace clang { Other.AddResult = false; } + FindExistingResult &operator=(FindExistingResult &&) = delete; ~FindExistingResult(); - /// \brief Suppress the addition of this result into the known set of + /// Suppress the addition of this result into the known set of /// names. void suppress() { AddResult = false; } @@ -213,11 +258,8 @@ namespace clang { ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record, ASTReader::RecordLocation Loc, DeclID thisDeclID, SourceLocation ThisDeclLoc) - : Reader(Reader), Record(Record), Loc(Loc), - ThisDeclID(thisDeclID), ThisDeclLoc(ThisDeclLoc), - TypeIDForTypeDecl(0), NamedDeclForTagDecl(0), - TypedefNameForLinkage(nullptr), HasPendingBody(false), - IsDeclMarkedUsed(false) {} + : Reader(Reader), Record(Record), Loc(Loc), ThisDeclID(thisDeclID), + ThisDeclLoc(ThisDeclLoc) {} template <typename T> static void AddLazySpecializations(T *D, @@ -232,7 +274,7 @@ namespace clang { if (auto &Old = LazySpecializations) { IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]); - std::sort(IDs.begin(), IDs.end()); + llvm::sort(IDs.begin(), IDs.end()); IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); } @@ -265,13 +307,13 @@ namespace clang { static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D); static void markIncompleteDeclChainImpl(...); - /// \brief Determine whether this declaration has a pending body. + /// Determine whether this declaration has a pending body. bool hasPendingBody() const { return HasPendingBody; } void ReadFunctionDefinition(FunctionDecl *FD); void Visit(Decl *D); - void UpdateDecl(Decl *D, llvm::SmallVectorImpl<serialization::DeclID>&); + void UpdateDecl(Decl *D, SmallVectorImpl<serialization::DeclID> &); static void setNextObjCCategory(ObjCCategoryDecl *Cat, ObjCCategoryDecl *Next) { @@ -300,19 +342,23 @@ namespace clang { void VisitCXXRecordDecl(CXXRecordDecl *D) { VisitCXXRecordDeclImpl(D); } RedeclarableResult VisitClassTemplateSpecializationDeclImpl( ClassTemplateSpecializationDecl *D); + void VisitClassTemplateSpecializationDecl( ClassTemplateSpecializationDecl *D) { VisitClassTemplateSpecializationDeclImpl(D); } + void VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D); void VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *D); RedeclarableResult VisitVarTemplateSpecializationDeclImpl(VarTemplateSpecializationDecl *D); + void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) { VisitVarTemplateSpecializationDeclImpl(D); } + void VisitVarTemplatePartialSpecializationDecl( VarTemplatePartialSpecializationDecl *D); void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); @@ -402,18 +448,22 @@ namespace clang { void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D); }; -} // end namespace clang + +} // namespace clang namespace { + /// Iterator over the redeclarations of a declaration that have already /// been merged into the same redeclaration chain. template<typename DeclT> class MergedRedeclIterator { - DeclT *Start, *Canonical, *Current; + DeclT *Start; + DeclT *Canonical = nullptr; + DeclT *Current = nullptr; + public: - MergedRedeclIterator() : Current(nullptr) {} - MergedRedeclIterator(DeclT *Start) - : Start(Start), Canonical(nullptr), Current(Start) {} + MergedRedeclIterator() = default; + MergedRedeclIterator(DeclT *Start) : Start(Start), Current(Start) {} DeclT *operator*() { return Current; } @@ -438,7 +488,8 @@ public: return A.Current != B.Current; } }; -} // end anonymous namespace + +} // namespace template <typename DeclT> static llvm::iterator_range<MergedRedeclIterator<DeclT>> @@ -472,30 +523,27 @@ void ASTDeclReader::Visit(Decl *D) { D->getCanonicalDecl()->Used |= IsDeclMarkedUsed; IsDeclMarkedUsed = false; - if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { - if (DD->DeclInfo) { - DeclaratorDecl::ExtInfo *Info = - DD->DeclInfo.get<DeclaratorDecl::ExtInfo *>(); - Info->TInfo = GetTypeSourceInfo(); - } - else { - DD->DeclInfo = GetTypeSourceInfo(); - } + if (auto *DD = dyn_cast<DeclaratorDecl>(D)) { + if (auto *TInfo = DD->getTypeSourceInfo()) + Record.readTypeLoc(TInfo->getTypeLoc()); } - if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) { + if (auto *TD = dyn_cast<TypeDecl>(D)) { // We have a fully initialized TypeDecl. Read its type now. - TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull()); + TD->setTypeForDecl(Reader.GetType(DeferredTypeID).getTypePtrOrNull()); // If this is a tag declaration with a typedef name for linkage, it's safe // to load that typedef now. if (NamedDeclForTagDecl) cast<TagDecl>(D)->TypedefNameDeclOrQualifier = cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl)); - } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { + } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) { // if we have a fully initialized TypeDecl, we can safely read its type now. - ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull(); - } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + ID->TypeForDecl = Reader.GetType(DeferredTypeID).getTypePtrOrNull(); + } else if (auto *FD = dyn_cast<FunctionDecl>(D)) { + if (DeferredTypeID) + FD->setType(Reader.GetType(DeferredTypeID)); + // FunctionDecl's body was written last after all other Stmts/Exprs. // We only read it if FD doesn't already have a body (e.g., from another // module). @@ -523,8 +571,8 @@ void ASTDeclReader::VisitDecl(Decl *D) { LexicalDCIDForTemplateParmDecl); D->setDeclContext(Reader.getContext().getTranslationUnitDecl()); } else { - DeclContext *SemaDC = ReadDeclAs<DeclContext>(); - DeclContext *LexicalDC = ReadDeclAs<DeclContext>(); + auto *SemaDC = ReadDeclAs<DeclContext>(); + auto *LexicalDC = ReadDeclAs<DeclContext>(); if (!LexicalDC) LexicalDC = SemaDC; DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC); @@ -615,7 +663,7 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { VisitNamedDecl(TD); TD->setLocStart(ReadSourceLocation()); // Delay type reading until after we have fully initialized the decl. - TypeIDForTypeDecl = Record.getGlobalTypeID(Record.readInt()); + DeferredTypeID = Record.getGlobalTypeID(Record.readInt()); } ASTDeclReader::RedeclarableResult @@ -667,7 +715,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) { case 0: break; case 1: { // ExtInfo - TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo(); + auto *Info = new (Reader.getContext()) TagDecl::ExtInfo(); ReadQualifierInfo(*Info); TD->TypedefNameDeclOrQualifier = Info; break; @@ -698,6 +746,9 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { ED->IsScopedUsingClassTag = Record.readInt(); ED->IsFixed = Record.readInt(); + ED->HasODRHash = true; + ED->ODRHash = Record.readInt(); + // If this is a definition subject to the ODR, and we already have a // definition, merge this one into it. if (ED->IsCompleteDefinition && @@ -718,14 +769,15 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef)); ED->IsCompleteDefinition = false; Reader.mergeDefinitionVisibility(OldDef, ED); + if (OldDef->getODRHash() != ED->getODRHash()) + Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED); } else { OldDef = ED; } } - if (EnumDecl *InstED = ReadDeclAs<EnumDecl>()) { - TemplateSpecializationKind TSK = - (TemplateSpecializationKind)Record.readInt(); + if (auto *InstED = ReadDeclAs<EnumDecl>()) { + auto TSK = (TemplateSpecializationKind)Record.readInt(); SourceLocation POI = ReadSourceLocation(); ED->setInstantiationOfMemberEnum(Reader.getContext(), InstED, TSK); ED->getMemberSpecializationInfo()->setPointOfInstantiation(POI); @@ -739,12 +791,23 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) { RD->setAnonymousStructOrUnion(Record.readInt()); RD->setHasObjectMember(Record.readInt()); RD->setHasVolatileMember(Record.readInt()); + RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt()); + RD->setNonTrivialToPrimitiveCopy(Record.readInt()); + RD->setNonTrivialToPrimitiveDestroy(Record.readInt()); + RD->setParamDestroyedInCallee(Record.readInt()); + RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)Record.readInt()); return Redecl; } void ASTDeclReader::VisitValueDecl(ValueDecl *VD) { VisitNamedDecl(VD); - VD->setType(Record.readType()); + // For function declarations, defer reading the type in case the function has + // a deduced return type that references an entity declared within the + // function. + if (isa<FunctionDecl>(VD)) + DeferredTypeID = Record.getGlobalTypeID(Record.readInt()); + else + VD->setType(Record.readType()); } void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) { @@ -759,17 +822,33 @@ void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) { VisitValueDecl(DD); DD->setInnerLocStart(ReadSourceLocation()); if (Record.readInt()) { // hasExtInfo - DeclaratorDecl::ExtInfo *Info - = new (Reader.getContext()) DeclaratorDecl::ExtInfo(); + auto *Info = new (Reader.getContext()) DeclaratorDecl::ExtInfo(); ReadQualifierInfo(*Info); DD->DeclInfo = Info; } + QualType TSIType = Record.readType(); + DD->setTypeSourceInfo( + TSIType.isNull() ? nullptr + : Reader.getContext().CreateTypeSourceInfo(TSIType)); } void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { RedeclarableResult Redecl = VisitRedeclarable(FD); VisitDeclaratorDecl(FD); + // Attach a type to this function. Use the real type if possible, but fall + // back to the type as written if it involves a deduced return type. + if (FD->getTypeSourceInfo() && + FD->getTypeSourceInfo()->getType()->castAs<FunctionType>() + ->getReturnType()->getContainedAutoType()) { + // We'll set up the real type in Visit, once we've finished loading the + // function. + FD->setType(FD->getTypeSourceInfo()->getType()); + } else { + FD->setType(Reader.GetType(DeferredTypeID)); + DeferredTypeID = 0; + } + ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName()); FD->IdentifierNamespace = Record.readInt(); @@ -786,12 +865,14 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->HasWrittenPrototype = Record.readInt(); FD->IsDeleted = Record.readInt(); FD->IsTrivial = Record.readInt(); + FD->IsTrivialForCall = Record.readInt(); FD->IsDefaulted = Record.readInt(); FD->IsExplicitlyDefaulted = Record.readInt(); FD->HasImplicitReturnZero = Record.readInt(); FD->IsConstexpr = Record.readInt(); FD->UsesSEHTry = Record.readInt(); FD->HasSkippedBody = Record.readInt(); + FD->IsMultiVersion = Record.readInt(); FD->IsLateTemplateParsed = Record.readInt(); FD->setCachedLinkage(Linkage(Record.readInt())); FD->EndRangeLoc = ReadSourceLocation(); @@ -808,9 +889,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>()); break; case FunctionDecl::TK_MemberSpecialization: { - FunctionDecl *InstFD = ReadDeclAs<FunctionDecl>(); - TemplateSpecializationKind TSK = - (TemplateSpecializationKind)Record.readInt(); + auto *InstFD = ReadDeclAs<FunctionDecl>(); + auto TSK = (TemplateSpecializationKind)Record.readInt(); SourceLocation POI = ReadSourceLocation(); FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK); FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI); @@ -818,9 +898,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { break; } case FunctionDecl::TK_FunctionTemplateSpecialization: { - FunctionTemplateDecl *Template = ReadDeclAs<FunctionTemplateDecl>(); - TemplateSpecializationKind TSK = - (TemplateSpecializationKind)Record.readInt(); + auto *Template = ReadDeclAs<FunctionTemplateDecl>(); + auto TSK = (TemplateSpecializationKind)Record.readInt(); // Template arguments. SmallVector<TemplateArgument, 8> TemplArgs; @@ -833,7 +912,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { if (HasTemplateArgumentsAsWritten) { unsigned NumTemplateArgLocs = Record.readInt(); TemplArgLocs.reserve(NumTemplateArgLocs); - for (unsigned i=0; i != NumTemplateArgLocs; ++i) + for (unsigned i = 0; i != NumTemplateArgLocs; ++i) TemplArgLocs.push_back(Record.readTemplateArgumentLoc()); LAngleLoc = ReadSourceLocation(); @@ -846,7 +925,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { TemplateArgumentList *TemplArgList = TemplateArgumentList::CreateCopy(C, TemplArgs); TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc); - for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i) + for (unsigned i = 0, e = TemplArgLocs.size(); i != e; ++i) TemplArgsInfo.addArgument(TemplArgLocs[i]); FunctionTemplateSpecializationInfo *FTInfo = FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK, @@ -859,7 +938,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { if (FD->isCanonicalDecl()) { // if canonical add to template's set. // The template that contains the specializations set. It's not safe to // use getCanonicalDecl on Template since it may still be initializing. - FunctionTemplateDecl *CanonTemplate = ReadDeclAs<FunctionTemplateDecl>(); + auto *CanonTemplate = ReadDeclAs<FunctionTemplateDecl>(); // Get the InsertPos by FindNodeOrInsertPos() instead of calling // InsertNode(FTInfo) directly to avoid the getASTContext() call in // FunctionTemplateSpecializationInfo's Profile(). @@ -981,7 +1060,7 @@ ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() { SmallVector<ObjCTypeParamDecl *, 4> typeParams; typeParams.reserve(numParams); for (unsigned i = 0; i != numParams; ++i) { - auto typeParam = ReadDeclAs<ObjCTypeParamDecl>(); + auto *typeParam = ReadDeclAs<ObjCTypeParamDecl>(); if (!typeParam) return nullptr; @@ -1034,7 +1113,7 @@ void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D, void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { RedeclarableResult Redecl = VisitRedeclarable(ID); VisitObjCContainerDecl(ID); - TypeIDForTypeDecl = Record.getGlobalTypeID(Record.readInt()); + DeferredTypeID = Record.getGlobalTypeID(Record.readInt()); mergeRedeclarable(ID, Redecl); ID->TypeParamList = ReadObjCTypeParamList(); @@ -1079,7 +1158,6 @@ void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) { void ASTDeclReader::ReadObjCDefinitionData( struct ObjCProtocolDecl::DefinitionData &Data) { - unsigned NumProtoRefs = Record.readInt(); SmallVector<ObjCProtocolDecl *, 16> ProtoRefs; ProtoRefs.reserve(NumProtoRefs); @@ -1155,6 +1233,12 @@ void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { ProtoLocs.push_back(ReadSourceLocation()); CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), Reader.getContext()); + + // Protocols in the class extension belong to the class. + if (NumProtoRefs > 0 && CD->ClassInterface && CD->IsClassExtension()) + CD->ClassInterface->mergeClassExtensionProtocolList( + (ObjCProtocolDecl *const *)ProtoRefs.data(), NumProtoRefs, + Reader.getContext()); } void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { @@ -1234,7 +1318,7 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) { FD->setBitWidth(BW); if (!FD->getDeclName()) { - if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>()) + if (auto *Tmpl = ReadDeclAs<FieldDecl>()) Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl); } mergeMergeable(FD); @@ -1272,6 +1356,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->NonParmVarDeclBits.ExceptionVar = Record.readInt(); VD->NonParmVarDeclBits.NRVOVariable = Record.readInt(); VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt(); + VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt(); VD->NonParmVarDeclBits.ARCPseudoStrong = Record.readInt(); VD->NonParmVarDeclBits.IsInline = Record.readInt(); VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt(); @@ -1280,7 +1365,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record.readInt(); VD->NonParmVarDeclBits.ImplicitParamKind = Record.readInt(); } - Linkage VarLinkage = Linkage(Record.readInt()); + auto VarLinkage = Linkage(Record.readInt()); VD->setCachedLinkage(VarLinkage); // Reconstruct the one piece of the IdentifierNamespace that we need. @@ -1316,9 +1401,8 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>()); break; case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo. - VarDecl *Tmpl = ReadDeclAs<VarDecl>(); - TemplateSpecializationKind TSK = - (TemplateSpecializationKind)Record.readInt(); + auto *Tmpl = ReadDeclAs<VarDecl>(); + auto TSK = (TemplateSpecializationKind)Record.readInt(); SourceLocation POI = ReadSourceLocation(); Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI); mergeRedeclarable(VD, Redecl); @@ -1357,7 +1441,7 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) { VisitVarDecl(DD); - BindingDecl **BDs = DD->getTrailingObjects<BindingDecl*>(); + auto **BDs = DD->getTrailingObjects<BindingDecl *>(); for (unsigned I = 0; I != DD->NumBindings; ++I) BDs[I] = ReadDeclAs<BindingDecl>(); } @@ -1393,7 +1477,7 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { SmallVector<BlockDecl::Capture, 16> captures; captures.reserve(numCaptures); for (unsigned i = 0; i != numCaptures; ++i) { - VarDecl *decl = ReadDeclAs<VarDecl>(); + auto *decl = ReadDeclAs<VarDecl>(); unsigned flags = Record.readInt(); bool byRef = (flags & 1); bool nested = (flags & 2); @@ -1460,7 +1544,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { // Each module has its own anonymous namespace, which is disjoint from // any other module's anonymous namespaces, so don't attach the anonymous // namespace at all. - NamespaceDecl *Anon = cast<NamespaceDecl>(Reader.GetDecl(AnonNamespace)); + auto *Anon = cast<NamespaceDecl>(Reader.GetDecl(AnonNamespace)); if (!Record.isModule()) D->setAnonymousNamespace(Anon); } @@ -1483,7 +1567,7 @@ void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { ReadDeclarationNameLoc(D->DNLoc, D->getDeclName()); D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>()); D->setTypename(Record.readInt()); - if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>()) + if (auto *Pattern = ReadDeclAs<NamedDecl>()) Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern); mergeMergeable(D); } @@ -1491,7 +1575,7 @@ void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) { VisitNamedDecl(D); D->InstantiatedFrom = ReadDeclAs<NamedDecl>(); - NamedDecl **Expansions = D->getTrailingObjects<NamedDecl*>(); + auto **Expansions = D->getTrailingObjects<NamedDecl *>(); for (unsigned I = 0; I != D->NumExpansions; ++I) Expansions[I] = ReadDeclAs<NamedDecl>(); mergeMergeable(D); @@ -1500,9 +1584,10 @@ void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) { void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { RedeclarableResult Redecl = VisitRedeclarable(D); VisitNamedDecl(D); - D->setTargetDecl(ReadDeclAs<NamedDecl>()); + D->Underlying = ReadDeclAs<NamedDecl>(); + D->IdentifierNamespace = Record.readInt(); D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(); - UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(); + auto *Pattern = ReadDeclAs<UsingShadowDecl>(); if (Pattern) Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern); mergeRedeclarable(D, Redecl); @@ -1554,7 +1639,9 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.Polymorphic = Record.readInt(); Data.Abstract = Record.readInt(); Data.IsStandardLayout = Record.readInt(); - Data.HasNoNonEmptyBases = Record.readInt(); + Data.IsCXX11StandardLayout = Record.readInt(); + Data.HasBasesWithFields = Record.readInt(); + Data.HasBasesWithNonStaticDataMembers = Record.readInt(); Data.HasPrivateFields = Record.readInt(); Data.HasProtectedFields = Record.readInt(); Data.HasPublicFields = Record.readInt(); @@ -1575,11 +1662,12 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.DefaultedMoveAssignmentIsDeleted = Record.readInt(); Data.DefaultedDestructorIsDeleted = Record.readInt(); Data.HasTrivialSpecialMembers = Record.readInt(); + Data.HasTrivialSpecialMembersForCall = Record.readInt(); Data.DeclaredNonTrivialSpecialMembers = Record.readInt(); + Data.DeclaredNonTrivialSpecialMembersForCall = Record.readInt(); Data.HasIrrelevantDestructor = Record.readInt(); Data.HasConstexprNonCopyMoveConstructor = Record.readInt(); Data.HasDefaultedDefaultConstructor = Record.readInt(); - Data.CanPassInRegisters = Record.readInt(); Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt(); Data.HasConstexprDefaultConstructor = Record.readInt(); Data.HasNonLiteralTypeFieldsOrBases = Record.readInt(); @@ -1610,9 +1698,9 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.FirstFriend = ReadDeclID(); if (Data.IsLambda) { - typedef LambdaCapture Capture; - CXXRecordDecl::LambdaDefinitionData &Lambda - = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data); + using Capture = LambdaCapture; + + auto &Lambda = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data); Lambda.Dependent = Record.readInt(); Lambda.IsGenericLambda = Record.readInt(); Lambda.CaptureDefault = Record.readInt(); @@ -1627,7 +1715,7 @@ void ASTDeclReader::ReadCXXDefinitionData( for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { SourceLocation Loc = ReadSourceLocation(); bool IsImplicit = Record.readInt(); - LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record.readInt()); + auto Kind = static_cast<LambdaCaptureKind>(Record.readInt()); switch (Kind) { case LCK_StarThis: case LCK_This: @@ -1636,7 +1724,7 @@ void ASTDeclReader::ReadCXXDefinitionData( break; case LCK_ByCopy: case LCK_ByRef: - VarDecl *Var = ReadDeclAs<VarDecl>(); + auto *Var = ReadDeclAs<VarDecl>(); SourceLocation EllipsisLoc = ReadSourceLocation(); *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc); break; @@ -1692,7 +1780,9 @@ void ASTDeclReader::MergeDefinitionData( MATCH_FIELD(Polymorphic) MATCH_FIELD(Abstract) MATCH_FIELD(IsStandardLayout) - MATCH_FIELD(HasNoNonEmptyBases) + MATCH_FIELD(IsCXX11StandardLayout) + MATCH_FIELD(HasBasesWithFields) + MATCH_FIELD(HasBasesWithNonStaticDataMembers) MATCH_FIELD(HasPrivateFields) MATCH_FIELD(HasProtectedFields) MATCH_FIELD(HasPublicFields) @@ -1713,11 +1803,12 @@ void ASTDeclReader::MergeDefinitionData( MATCH_FIELD(DefaultedMoveAssignmentIsDeleted) MATCH_FIELD(DefaultedDestructorIsDeleted) OR_FIELD(HasTrivialSpecialMembers) + OR_FIELD(HasTrivialSpecialMembersForCall) OR_FIELD(DeclaredNonTrivialSpecialMembers) + OR_FIELD(DeclaredNonTrivialSpecialMembersForCall) MATCH_FIELD(HasIrrelevantDestructor) OR_FIELD(HasConstexprNonCopyMoveConstructor) OR_FIELD(HasDefaultedDefaultConstructor) - MATCH_FIELD(CanPassInRegisters) MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr) OR_FIELD(HasConstexprDefaultConstructor) MATCH_FIELD(HasNonLiteralTypeFieldsOrBases) @@ -1775,29 +1866,31 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) { else DD = new (C) struct CXXRecordDecl::DefinitionData(D); + CXXRecordDecl *Canon = D->getCanonicalDecl(); + // Set decl definition data before reading it, so that during deserialization + // when we read CXXRecordDecl, it already has definition data and we don't + // set fake one. + if (!Canon->DefinitionData) + Canon->DefinitionData = DD; + D->DefinitionData = Canon->DefinitionData; ReadCXXDefinitionData(*DD, D); - // We might already have a definition for this record. This can happen either - // because we're reading an update record, or because we've already done some - // merging. Either way, just merge into it. - CXXRecordDecl *Canon = D->getCanonicalDecl(); - if (Canon->DefinitionData) { + // We might already have a different definition for this record. This can + // happen either because we're reading an update record, or because we've + // already done some merging. Either way, just merge into it. + if (Canon->DefinitionData != DD) { MergeDefinitionData(Canon, std::move(*DD)); - D->DefinitionData = Canon->DefinitionData; return; } // Mark this declaration as being a definition. D->IsCompleteDefinition = true; - D->DefinitionData = DD; // If this is not the first declaration or is an update record, we can have // other redeclarations already. Make a note that we need to propagate the // DefinitionData pointer onto them. - if (Update || Canon != D) { - Canon->DefinitionData = D->DefinitionData; + if (Update || Canon != D) Reader.PendingDefinitions.insert(D); - } } ASTDeclReader::RedeclarableResult @@ -1817,7 +1910,7 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { break; case CXXRecTemplate: { // Merged when we merge the template. - ClassTemplateDecl *Template = ReadDeclAs<ClassTemplateDecl>(); + auto *Template = ReadDeclAs<ClassTemplateDecl>(); D->TemplateOrInstantiation = Template; if (!Template->getTemplatedDecl()) { // We've not actually loaded the ClassTemplateDecl yet, because we're @@ -1826,14 +1919,13 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { // // Beware: we do not yet know our canonical declaration, and may still // get merged once the surrounding class template has got off the ground. - TypeIDForTypeDecl = 0; + DeferredTypeID = 0; } break; } case CXXRecMemberSpecialization: { - CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(); - TemplateSpecializationKind TSK = - (TemplateSpecializationKind)Record.readInt(); + auto *RD = ReadDeclAs<CXXRecordDecl>(); + auto TSK = (TemplateSpecializationKind)Record.readInt(); SourceLocation POI = ReadSourceLocation(); MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK); MSI->setPointOfInstantiation(POI); @@ -1877,7 +1969,7 @@ void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { while (NumOverridenMethods--) { // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod, // MD may be initializing. - if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>()) + if (auto *MD = ReadDeclAs<CXXMethodDecl>()) Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl()); } } else { @@ -1904,7 +1996,7 @@ void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { VisitCXXMethodDecl(D); if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>()) { - auto *Canon = cast<CXXDestructorDecl>(D->getCanonicalDecl()); + CXXDestructorDecl *Canon = D->getCanonicalDecl(); auto *ThisArg = Record.readExpr(); // FIXME: Check consistency if we have an old and new operator delete. if (!Canon->OperatorDelete) { @@ -1922,7 +2014,7 @@ void ASTDeclReader::VisitImportDecl(ImportDecl *D) { VisitDecl(D); D->ImportedAndComplete.setPointer(readModule()); D->ImportedAndComplete.setInt(Record.readInt()); - SourceLocation *StoredLocs = D->getTrailingObjects<SourceLocation>(); + auto *StoredLocs = D->getTrailingObjects<SourceLocation>(); for (unsigned I = 0, N = Record.back(); I != N; ++I) StoredLocs[I] = ReadSourceLocation(); Record.skipInts(1); // The number of stored source locations. @@ -1965,7 +2057,7 @@ DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { VisitNamedDecl(D); DeclID PatternID = ReadDeclID(); - NamedDecl *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID)); + auto *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID)); TemplateParameterList *TemplateParams = Record.readTemplateParameterList(); // FIXME handle associated constraints D->init(TemplatedDecl, TemplateParams); @@ -1989,8 +2081,7 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { // If this is the first declaration of the template, fill in the information // for the 'common' pointer. if (ThisDeclID == Redecl.getFirstID()) { - if (RedeclarableTemplateDecl *RTD - = ReadDeclAs<RedeclarableTemplateDecl>()) { + if (auto *RTD = ReadDeclAs<RedeclarableTemplateDecl>()) { assert(RTD->getKind() == D->getKind() && "InstantiatedFromMemberTemplate kind mismatch"); D->setInstantiatedFromMemberTemplate(RTD); @@ -2058,15 +2149,15 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( ASTContext &C = Reader.getContext(); if (Decl *InstD = ReadDecl()) { - if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) { + if (auto *CTD = dyn_cast<ClassTemplateDecl>(InstD)) { D->SpecializedTemplate = CTD; } else { SmallVector<TemplateArgument, 8> TemplArgs; Record.readTemplateArgumentList(TemplArgs); TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy(C, TemplArgs); - ClassTemplateSpecializationDecl::SpecializedPartialSpecialization *PS - = new (C) ClassTemplateSpecializationDecl:: + auto *PS = + new (C) ClassTemplateSpecializationDecl:: SpecializedPartialSpecialization(); PS->PartialSpecialization = cast<ClassTemplatePartialSpecializationDecl>(InstD); @@ -2083,12 +2174,11 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( bool writtenAsCanonicalDecl = Record.readInt(); if (writtenAsCanonicalDecl) { - ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(); + auto *CanonPattern = ReadDeclAs<ClassTemplateDecl>(); if (D->isCanonicalDecl()) { // It's kept in the folding set. // Set this as, or find, the canonical declaration for this specialization ClassTemplateSpecializationDecl *CanonSpec; - if (ClassTemplatePartialSpecializationDecl *Partial = - dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { + if (auto *Partial = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { CanonSpec = CanonPattern->getCommonPtr()->PartialSpecializations .GetOrInsertNode(Partial); } else { @@ -2114,8 +2204,8 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( // Explicit info. if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) { - ClassTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo - = new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo; + auto *ExplicitInfo = + new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo; ExplicitInfo->TypeAsWritten = TyInfo; ExplicitInfo->ExternLoc = ReadSourceLocation(); ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(); @@ -2169,14 +2259,14 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( ASTContext &C = Reader.getContext(); if (Decl *InstD = ReadDecl()) { - if (VarTemplateDecl *VTD = dyn_cast<VarTemplateDecl>(InstD)) { + if (auto *VTD = dyn_cast<VarTemplateDecl>(InstD)) { D->SpecializedTemplate = VTD; } else { SmallVector<TemplateArgument, 8> TemplArgs; Record.readTemplateArgumentList(TemplArgs); TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy( C, TemplArgs); - VarTemplateSpecializationDecl::SpecializedPartialSpecialization *PS = + auto *PS = new (C) VarTemplateSpecializationDecl::SpecializedPartialSpecialization(); PS->PartialSpecialization = @@ -2188,7 +2278,7 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( // Explicit info. if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) { - VarTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo = + auto *ExplicitInfo = new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo; ExplicitInfo->TypeAsWritten = TyInfo; ExplicitInfo->ExternLoc = ReadSourceLocation(); @@ -2205,11 +2295,10 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( bool writtenAsCanonicalDecl = Record.readInt(); if (writtenAsCanonicalDecl) { - VarTemplateDecl *CanonPattern = ReadDeclAs<VarTemplateDecl>(); + auto *CanonPattern = ReadDeclAs<VarTemplateDecl>(); if (D->isCanonicalDecl()) { // It's kept in the folding set. // FIXME: If it's already present, merge it. - if (VarTemplatePartialSpecializationDecl *Partial = - dyn_cast<VarTemplatePartialSpecializationDecl>(D)) { + if (auto *Partial = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) { CanonPattern->getCommonPtr()->PartialSpecializations .GetOrInsertNode(Partial); } else { @@ -2276,8 +2365,7 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { D->setDepth(Record.readInt()); D->setPosition(Record.readInt()); if (D->isExpandedParameterPack()) { - TemplateParameterList **Data = - D->getTrailingObjects<TemplateParameterList *>(); + auto **Data = D->getTrailingObjects<TemplateParameterList *>(); for (unsigned I = 0, N = D->getNumExpansionTemplateParameters(); I != N; ++I) Data[I] = Record.readTemplateParameterList(); @@ -2351,7 +2439,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { (void)ReadDecl(); } - T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID)); + auto *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID)); if (FirstDecl != D) { // We delay loading of the redeclaration chain to avoid deeply nested calls. // We temporarily set the first (canonical) declaration as the previous one @@ -2361,7 +2449,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { D->First = FirstDecl->getCanonicalDecl(); } - T *DAsT = static_cast<T*>(D); + auto *DAsT = static_cast<T *>(D); // Note that we need to load local redeclarations of this decl and build a // decl chain for them. This must happen *after* we perform the preloading @@ -2373,7 +2461,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { return RedeclarableResult(MergeWith, FirstDeclID, IsKeyDecl); } -/// \brief Attempts to merge the given declaration (D) with another declaration +/// Attempts to merge the given declaration (D) with another declaration /// of the same entity. template<typename T> void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, @@ -2387,7 +2475,7 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, if (!DBase->isFirstDecl()) return; - T *D = static_cast<T*>(DBase); + auto *D = static_cast<T *>(DBase); if (auto *Existing = Redecl.getKnownMergeTarget()) // We already know of an existing declaration we should merge with. @@ -2397,7 +2485,7 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, mergeRedeclarable(D, Existing, Redecl, TemplatePatternID); } -/// \brief "Cast" to type T, asserting if we don't have an implicit conversion. +/// "Cast" to type T, asserting if we don't have an implicit conversion. /// We use this to put code in a template that will only be valid for certain /// instantiations. template<typename T> static T assert_cast(T t) { return t; } @@ -2405,7 +2493,7 @@ template<typename T> static T assert_cast(...) { llvm_unreachable("bad assert_cast"); } -/// \brief Merge together the pattern declarations from two template +/// Merge together the pattern declarations from two template /// declarations. void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, RedeclarableTemplateDecl *Existing, @@ -2447,13 +2535,13 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, llvm_unreachable("merged an unknown kind of redeclarable template"); } -/// \brief Attempts to merge the given declaration (D) with another declaration +/// Attempts to merge the given declaration (D) with another declaration /// of the same entity. template<typename T> void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing, RedeclarableResult &Redecl, DeclID TemplatePatternID) { - T *D = static_cast<T*>(DBase); + auto *D = static_cast<T *>(DBase); T *ExistingCanon = Existing->getCanonicalDecl(); T *DCanon = D->getCanonicalDecl(); if (ExistingCanon != DCanon) { @@ -2487,7 +2575,21 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing, } } -/// \brief Attempts to merge the given declaration (D) with another declaration +/// ODR-like semantics for C/ObjC allow us to merge tag types and a structural +/// check in Sema guarantees the types can be merged (see C11 6.2.7/1 or C89 +/// 6.1.2.6/1). Although most merging is done in Sema, we need to guarantee +/// that some types are mergeable during deserialization, otherwise name +/// lookup fails. This is the case for EnumConstantDecl. +static bool allowODRLikeMergeInC(NamedDecl *ND) { + if (!ND) + return false; + // TODO: implement merge for other necessary decls. + if (isa<EnumConstantDecl>(ND)) + return true; + return false; +} + +/// Attempts to merge the given declaration (D) with another declaration /// of the same entity, for the case where the entity is not actually /// redeclarable. This happens, for instance, when merging the fields of /// identical class definitions from two different modules. @@ -2497,10 +2599,12 @@ void ASTDeclReader::mergeMergeable(Mergeable<T> *D) { if (!Reader.getContext().getLangOpts().Modules) return; - // ODR-based merging is only performed in C++. In C, identically-named things - // in different translation units are not redeclarations (but may still have - // compatible types). - if (!Reader.getContext().getLangOpts().CPlusPlus) + // ODR-based merging is performed in C++ and in some cases (tag types) in C. + // Note that C identically-named things in different translation units are + // not redeclarations, but may still have compatible types, where ODR-like + // semantics may apply. + if (!Reader.getContext().getLangOpts().CPlusPlus && + !allowODRLikeMergeInC(dyn_cast<NamedDecl>(static_cast<T*>(D)))) return; if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D))) @@ -2538,11 +2642,11 @@ void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { // Attribute Reading //===----------------------------------------------------------------------===// -/// \brief Reads attributes from the current stream position. +/// Reads attributes from the current stream position. void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs) { for (unsigned i = 0, e = Record.readInt(); i != e; ++i) { Attr *New = nullptr; - attr::Kind Kind = (attr::Kind)Record.readInt(); + auto Kind = (attr::Kind)Record.readInt(); SourceRange Range = Record.readSourceRange(); ASTContext &Context = getContext(); @@ -2557,7 +2661,7 @@ void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs) { // ASTReader Implementation //===----------------------------------------------------------------------===// -/// \brief Note that we have loaded the declaration with the given +/// Note that we have loaded the declaration with the given /// Index. /// /// This routine notes that this declaration has already been loaded, @@ -2568,8 +2672,7 @@ inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) { DeclsLoaded[Index] = D; } - -/// \brief Determine whether the consumer will be interested in seeing +/// Determine whether the consumer will be interested in seeing /// this declaration (via HandleTopLevelDecl). /// /// This routine should return true for anything that might affect @@ -2597,10 +2700,10 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { return true; if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D)) return !D->getDeclContext()->isFunctionOrMethod(); - if (VarDecl *Var = dyn_cast<VarDecl>(D)) + if (const auto *Var = dyn_cast<VarDecl>(D)) return Var->isFileVarDecl() && Var->isThisDeclarationADefinition() == VarDecl::Definition; - if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) + if (const auto *Func = dyn_cast<FunctionDecl>(D)) return Func->doesThisDeclarationHaveABody() || HasBody; if (auto *ES = D->getASTContext().getExternalSource()) @@ -2610,7 +2713,7 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { return false; } -/// \brief Get the correct cursor and offset for loading a declaration. +/// Get the correct cursor and offset for loading a declaration. ASTReader::RecordLocation ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) { GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID); @@ -2623,8 +2726,7 @@ ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) { } ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) { - ContinuousRangeMap<uint64_t, ModuleFile*, 4>::iterator I - = GlobalBitOffsetsMap.find(GlobalOffset); + auto I = GlobalBitOffsetsMap.find(GlobalOffset); assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map"); return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset); @@ -2637,26 +2739,26 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) { static bool isSameTemplateParameterList(const TemplateParameterList *X, const TemplateParameterList *Y); -/// \brief Determine whether two template parameters are similar enough +/// Determine whether two template parameters are similar enough /// that they may be used in declarations of the same template. static bool isSameTemplateParameter(const NamedDecl *X, const NamedDecl *Y) { if (X->getKind() != Y->getKind()) return false; - if (const TemplateTypeParmDecl *TX = dyn_cast<TemplateTypeParmDecl>(X)) { - const TemplateTypeParmDecl *TY = cast<TemplateTypeParmDecl>(Y); + if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) { + const auto *TY = cast<TemplateTypeParmDecl>(Y); return TX->isParameterPack() == TY->isParameterPack(); } - if (const NonTypeTemplateParmDecl *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { - const NonTypeTemplateParmDecl *TY = cast<NonTypeTemplateParmDecl>(Y); + if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { + const auto *TY = cast<NonTypeTemplateParmDecl>(Y); return TX->isParameterPack() == TY->isParameterPack() && TX->getASTContext().hasSameType(TX->getType(), TY->getType()); } - const TemplateTemplateParmDecl *TX = cast<TemplateTemplateParmDecl>(X); - const TemplateTemplateParmDecl *TY = cast<TemplateTemplateParmDecl>(Y); + const auto *TX = cast<TemplateTemplateParmDecl>(X); + const auto *TY = cast<TemplateTemplateParmDecl>(Y); return TX->isParameterPack() == TY->isParameterPack() && isSameTemplateParameterList(TX->getTemplateParameters(), TY->getTemplateParameters()); @@ -2709,7 +2811,7 @@ static bool isSameQualifier(const NestedNameSpecifier *X, return !PX && !PY; } -/// \brief Determine whether two template parameter lists are similar enough +/// Determine whether two template parameter lists are similar enough /// that they may be used in declarations of the same template. static bool isSameTemplateParameterList(const TemplateParameterList *X, const TemplateParameterList *Y) { @@ -2762,7 +2864,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A, return true; } -/// \brief Determine whether the two declarations refer to the same entity. +/// Determine whether the two declarations refer to the same entity. static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!"); @@ -2770,14 +2872,18 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { return true; // Must be in the same context. - if (!X->getDeclContext()->getRedeclContext()->Equals( - Y->getDeclContext()->getRedeclContext())) + // + // Note that we can't use DeclContext::Equals here, because the DeclContexts + // could be two different declarations of the same function. (We will fix the + // semantic DC to refer to the primary definition after merging.) + if (!declaresSameEntity(cast<Decl>(X->getDeclContext()->getRedeclContext()), + cast<Decl>(Y->getDeclContext()->getRedeclContext()))) return false; // Two typedefs refer to the same entity if they have the same underlying // type. - if (TypedefNameDecl *TypedefX = dyn_cast<TypedefNameDecl>(X)) - if (TypedefNameDecl *TypedefY = dyn_cast<TypedefNameDecl>(Y)) + if (const auto *TypedefX = dyn_cast<TypedefNameDecl>(X)) + if (const auto *TypedefY = dyn_cast<TypedefNameDecl>(Y)) return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(), TypedefY->getUnderlyingType()); @@ -2796,8 +2902,8 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { } // Compatible tags match. - if (TagDecl *TagX = dyn_cast<TagDecl>(X)) { - TagDecl *TagY = cast<TagDecl>(Y); + if (const auto *TagX = dyn_cast<TagDecl>(X)) { + const auto *TagY = cast<TagDecl>(Y); return (TagX->getTagKind() == TagY->getTagKind()) || ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class || TagX->getTagKind() == TTK_Interface) && @@ -2808,28 +2914,51 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { // Functions with the same type and linkage match. // FIXME: This needs to cope with merging of prototyped/non-prototyped // functions, etc. - if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) { - FunctionDecl *FuncY = cast<FunctionDecl>(Y); - if (CXXConstructorDecl *CtorX = dyn_cast<CXXConstructorDecl>(X)) { - CXXConstructorDecl *CtorY = cast<CXXConstructorDecl>(Y); + if (const auto *FuncX = dyn_cast<FunctionDecl>(X)) { + const auto *FuncY = cast<FunctionDecl>(Y); + if (const auto *CtorX = dyn_cast<CXXConstructorDecl>(X)) { + const auto *CtorY = cast<CXXConstructorDecl>(Y); if (CtorX->getInheritedConstructor() && !isSameEntity(CtorX->getInheritedConstructor().getConstructor(), CtorY->getInheritedConstructor().getConstructor())) return false; } + + if (FuncX->isMultiVersion() != FuncY->isMultiVersion()) + return false; + + // Multiversioned functions with different feature strings are represented + // as separate declarations. + if (FuncX->isMultiVersion()) { + const auto *TAX = FuncX->getAttr<TargetAttr>(); + const auto *TAY = FuncY->getAttr<TargetAttr>(); + assert(TAX && TAY && "Multiversion Function without target attribute"); + + if (TAX->getFeaturesStr() != TAY->getFeaturesStr()) + return false; + } + ASTContext &C = FuncX->getASTContext(); - if (!C.hasSameType(FuncX->getType(), FuncY->getType())) { + auto GetTypeAsWritten = [](const FunctionDecl *FD) { + // Map to the first declaration that we've already merged into this one. + // The TSI of redeclarations might not match (due to calling conventions + // being inherited onto the type but not the TSI), but the TSI type of + // the first declaration of the function should match across modules. + FD = FD->getCanonicalDecl(); + return FD->getTypeSourceInfo() ? FD->getTypeSourceInfo()->getType() + : FD->getType(); + }; + QualType XT = GetTypeAsWritten(FuncX), YT = GetTypeAsWritten(FuncY); + if (!C.hasSameType(XT, YT)) { // We can get functions with different types on the redecl chain in C++17 // if they have differing exception specifications and at least one of // the excpetion specs is unresolved. - // FIXME: Do we need to check for C++14 deduced return types here too? - auto *XFPT = FuncX->getType()->getAs<FunctionProtoType>(); - auto *YFPT = FuncY->getType()->getAs<FunctionProtoType>(); + auto *XFPT = XT->getAs<FunctionProtoType>(); + auto *YFPT = YT->getAs<FunctionProtoType>(); if (C.getLangOpts().CPlusPlus17 && XFPT && YFPT && (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) || isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) && - C.hasSameFunctionTypeIgnoringExceptionSpec(FuncX->getType(), - FuncY->getType())) + C.hasSameFunctionTypeIgnoringExceptionSpec(XT, YT)) return true; return false; } @@ -2838,8 +2967,8 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { } // Variables with the same type and linkage match. - if (VarDecl *VarX = dyn_cast<VarDecl>(X)) { - VarDecl *VarY = cast<VarDecl>(Y); + if (const auto *VarX = dyn_cast<VarDecl>(X)) { + const auto *VarY = cast<VarDecl>(Y); if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) { ASTContext &C = VarX->getASTContext(); if (C.hasSameType(VarX->getType(), VarY->getType())) @@ -2861,15 +2990,15 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { } // Namespaces with the same name and inlinedness match. - if (NamespaceDecl *NamespaceX = dyn_cast<NamespaceDecl>(X)) { - NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y); + if (const auto *NamespaceX = dyn_cast<NamespaceDecl>(X)) { + const auto *NamespaceY = cast<NamespaceDecl>(Y); return NamespaceX->isInline() == NamespaceY->isInline(); } // Identical template names and kinds match if their template parameter lists // and patterns match. - if (TemplateDecl *TemplateX = dyn_cast<TemplateDecl>(X)) { - TemplateDecl *TemplateY = cast<TemplateDecl>(Y); + if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) { + const auto *TemplateY = cast<TemplateDecl>(Y); return isSameEntity(TemplateX->getTemplatedDecl(), TemplateY->getTemplatedDecl()) && isSameTemplateParameterList(TemplateX->getTemplateParameters(), @@ -2877,15 +3006,15 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { } // Fields with the same name and the same type match. - if (FieldDecl *FDX = dyn_cast<FieldDecl>(X)) { - FieldDecl *FDY = cast<FieldDecl>(Y); + if (const auto *FDX = dyn_cast<FieldDecl>(X)) { + const auto *FDY = cast<FieldDecl>(Y); // FIXME: Also check the bitwidth is odr-equivalent, if any. return X->getASTContext().hasSameType(FDX->getType(), FDY->getType()); } // Indirect fields with the same target field match. - if (auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) { - auto *IFDY = cast<IndirectFieldDecl>(Y); + if (const auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) { + const auto *IFDY = cast<IndirectFieldDecl>(Y); return IFDX->getAnonField()->getCanonicalDecl() == IFDY->getAnonField()->getCanonicalDecl(); } @@ -2896,32 +3025,32 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { return true; // Using shadow declarations with the same target match. - if (UsingShadowDecl *USX = dyn_cast<UsingShadowDecl>(X)) { - UsingShadowDecl *USY = cast<UsingShadowDecl>(Y); + if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) { + const auto *USY = cast<UsingShadowDecl>(Y); return USX->getTargetDecl() == USY->getTargetDecl(); } // Using declarations with the same qualifier match. (We already know that // the name matches.) - if (auto *UX = dyn_cast<UsingDecl>(X)) { - auto *UY = cast<UsingDecl>(Y); + if (const auto *UX = dyn_cast<UsingDecl>(X)) { + const auto *UY = cast<UsingDecl>(Y); return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && UX->hasTypename() == UY->hasTypename() && UX->isAccessDeclaration() == UY->isAccessDeclaration(); } - if (auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) { - auto *UY = cast<UnresolvedUsingValueDecl>(Y); + if (const auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) { + const auto *UY = cast<UnresolvedUsingValueDecl>(Y); return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && UX->isAccessDeclaration() == UY->isAccessDeclaration(); } - if (auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) + if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) return isSameQualifier( UX->getQualifier(), cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier()); // Namespace alias definitions with the same target match. - if (auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) { - auto *NAY = cast<NamespaceAliasDecl>(Y); + if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) { + const auto *NAY = cast<NamespaceAliasDecl>(Y); return NAX->getNamespace()->Equals(NAY->getNamespace()); } @@ -2932,10 +3061,10 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { /// looking for declarations to merge. DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader, DeclContext *DC) { - if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC)) + if (auto *ND = dyn_cast<NamespaceDecl>(DC)) return ND->getOriginalNamespace(); - if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) { + if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) { // Try to dig out the definition. auto *DD = RD->DefinitionData; if (!DD) @@ -2959,7 +3088,7 @@ DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader, return DD->Definition; } - if (EnumDecl *ED = dyn_cast<EnumDecl>(DC)) + if (auto *ED = dyn_cast<EnumDecl>(DC)) return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition() : nullptr; @@ -3021,23 +3150,50 @@ static NamedDecl *getDeclForMerging(NamedDecl *Found, return nullptr; } +/// Find the declaration to use to populate the anonymous declaration table +/// for the given lexical DeclContext. We only care about finding local +/// definitions of the context; we'll merge imported ones as we go. +DeclContext * +ASTDeclReader::getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC) { + // For classes, we track the definition as we merge. + if (auto *RD = dyn_cast<CXXRecordDecl>(LexicalDC)) { + auto *DD = RD->getCanonicalDecl()->DefinitionData; + return DD ? DD->Definition : nullptr; + } + + // For anything else, walk its merged redeclarations looking for a definition. + // Note that we can't just call getDefinition here because the redeclaration + // chain isn't wired up. + for (auto *D : merged_redecls(cast<Decl>(LexicalDC))) { + if (auto *FD = dyn_cast<FunctionDecl>(D)) + if (FD->isThisDeclarationADefinition()) + return FD; + if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) + if (MD->isThisDeclarationADefinition()) + return MD; + } + + // No merged definition yet. + return nullptr; +} + NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC, unsigned Index) { // If the lexical context has been merged, look into the now-canonical // definition. - if (auto *Merged = Reader.MergedDeclContexts.lookup(DC)) - DC = Merged; + auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl(); // If we've seen this before, return the canonical declaration. - auto &Previous = Reader.AnonymousDeclarationsForMerging[DC]; + auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC]; if (Index < Previous.size() && Previous[Index]) return Previous[Index]; // If this is the first time, but we have parsed a declaration of the context, // build the anonymous declaration list from the parsed declaration. - if (!cast<Decl>(DC)->isFromASTFile()) { - numberAnonymousDeclsWithin(DC, [&](NamedDecl *ND, unsigned Number) { + auto *PrimaryDC = getPrimaryDCForAnonymousDecl(DC); + if (PrimaryDC && !cast<Decl>(PrimaryDC)->isFromASTFile()) { + numberAnonymousDeclsWithin(PrimaryDC, [&](NamedDecl *ND, unsigned Number) { if (Previous.size() == Number) Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl())); else @@ -3051,10 +3207,9 @@ NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader, void ASTDeclReader::setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC, unsigned Index, NamedDecl *D) { - if (auto *Merged = Reader.MergedDeclContexts.lookup(DC)) - DC = Merged; + auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl(); - auto &Previous = Reader.AnonymousDeclarationsForMerging[DC]; + auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC]; if (Index >= Previous.size()) Previous.resize(Index + 1); if (!Previous[Index]) @@ -3102,12 +3257,10 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { // cause additional lookups here. class UpToDateIdentifierRAII { IdentifierInfo *II; - bool WasOutToDate; + bool WasOutToDate = false; public: - explicit UpToDateIdentifierRAII(IdentifierInfo *II) - : II(II), WasOutToDate(false) - { + explicit UpToDateIdentifierRAII(IdentifierInfo *II) : II(II) { if (II) { WasOutToDate = II->isOutOfDate(); if (WasOutToDate) @@ -3160,6 +3313,7 @@ template<typename DeclT> Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *D) { return D->RedeclLink.getLatestNotUpdated(); } + Decl *ASTDeclReader::getMostRecentDeclImpl(...) { llvm_unreachable("getMostRecentDecl on non-redeclarable declaration"); } @@ -3190,12 +3344,13 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, } namespace clang { + template<> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable<VarDecl> *D, Decl *Previous, Decl *Canon) { - VarDecl *VD = static_cast<VarDecl*>(D); - VarDecl *PrevVD = cast<VarDecl>(Previous); + auto *VD = static_cast<VarDecl *>(D); + auto *PrevVD = cast<VarDecl>(Previous); D->RedeclLink.setPrevious(PrevVD); D->First = PrevVD->First; @@ -3217,8 +3372,8 @@ template<> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable<FunctionDecl> *D, Decl *Previous, Decl *Canon) { - FunctionDecl *FD = static_cast<FunctionDecl*>(D); - FunctionDecl *PrevFD = cast<FunctionDecl>(Previous); + auto *FD = static_cast<FunctionDecl *>(D); + auto *PrevFD = cast<FunctionDecl>(Previous); FD->RedeclLink.setPrevious(PrevFD); FD->First = PrevFD->First; @@ -3257,7 +3412,8 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, std::make_pair(Canon, IsUnresolved ? PrevFD : FD)); } } -} // end namespace clang + +} // namespace clang void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) { llvm_unreachable("attachPreviousDecl on non-redeclarable declaration"); @@ -3326,7 +3482,7 @@ void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D, // If the declaration declares a template, it may inherit default arguments // from the previous declaration. - if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) + if (auto *TD = dyn_cast<TemplateDecl>(D)) inheritDefaultTemplateArguments(Reader.getContext(), cast<TemplateDecl>(Previous), TD); } @@ -3335,6 +3491,7 @@ template<typename DeclT> void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) { D->RedeclLink.setLatest(cast<DeclT>(Latest)); } + void ASTDeclReader::attachLatestDeclImpl(...) { llvm_unreachable("attachLatestDecl on non-redeclarable declaration"); } @@ -3356,6 +3513,7 @@ template<typename DeclT> void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) { D->RedeclLink.markIncomplete(); } + void ASTDeclReader::markIncompleteDeclChainImpl(...) { llvm_unreachable("markIncompleteDeclChain on non-redeclarable declaration"); } @@ -3371,7 +3529,7 @@ void ASTReader::markIncompleteDeclChain(Decl *D) { } } -/// \brief Read the declaration at the given offset from the AST file. +/// Read the declaration at the given offset from the AST file. Decl *ASTReader::ReadDeclRecord(DeclID ID) { unsigned Index = ID - NUM_PREDEF_DECL_IDS; SourceLocation DeclLoc; @@ -3639,7 +3797,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // If this declaration is also a declaration context, get the // offsets for its tables of lexical and visible declarations. - if (DeclContext *DC = dyn_cast<DeclContext>(D)) { + if (auto *DC = dyn_cast<DeclContext>(D)) { std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC); if (Offsets.first && ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, Offsets.first, DC)) @@ -3655,7 +3813,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { PendingUpdateRecord(ID, D, /*JustLoaded=*/true)); // Load the categories after recursive loading is finished. - if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D)) + if (auto *Class = dyn_cast<ObjCInterfaceDecl>(D)) // If we already have a definition when deserializing the ObjCInterfaceDecl, // we put the Decl in PendingDefinitions so we can pull the categories here. if (Class->isThisDeclarationADefinition() || @@ -3706,7 +3864,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { ProcessingUpdatesRAIIObj ProcessingUpdates(*this); DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); - llvm::SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs; + SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs; if (UpdI != DeclUpdateOffsets.end()) { auto UpdateOffsets = std::move(UpdI->second); @@ -3763,7 +3921,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { PendingVisibleUpdates.erase(I); auto *DC = cast<DeclContext>(D)->getPrimaryContext(); - for (const PendingVisibleUpdate &Update : VisibleUpdates) + for (const auto &Update : VisibleUpdates) Lookups[DC].Table.add( Update.Mod, Update.Data, reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod)); @@ -3812,13 +3970,14 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) { } namespace { - /// \brief Given an ObjC interface, goes through the modules and links to the + + /// Given an ObjC interface, goes through the modules and links to the /// interface all the categories for it. class ObjCCategoriesVisitor { ASTReader &Reader; ObjCInterfaceDecl *Interface; llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized; - ObjCCategoryDecl *Tail; + ObjCCategoryDecl *Tail = nullptr; llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap; serialization::GlobalDeclID InterfaceID; unsigned PreviousGeneration; @@ -3868,10 +4027,8 @@ namespace { llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized, serialization::GlobalDeclID InterfaceID, unsigned PreviousGeneration) - : Reader(Reader), Interface(Interface), Deserialized(Deserialized), - Tail(nullptr), InterfaceID(InterfaceID), - PreviousGeneration(PreviousGeneration) - { + : Reader(Reader), Interface(Interface), Deserialized(Deserialized), + InterfaceID(InterfaceID), PreviousGeneration(PreviousGeneration) { // Populate the name -> category map with the set of known categories. for (auto *Cat : Interface->known_categories()) { if (Cat->getDeclName()) @@ -3920,7 +4077,8 @@ namespace { return true; } }; -} // end anonymous namespace + +} // namespace void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, @@ -3973,13 +4131,13 @@ void ASTDeclReader::UpdateDecl(Decl *D, break; case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: { - NamespaceDecl *Anon = ReadDeclAs<NamespaceDecl>(); + auto *Anon = ReadDeclAs<NamespaceDecl>(); // Each module has its own anonymous namespace, which is disjoint from // any other module's anonymous namespaces, so don't attach the anonymous // namespace at all. if (!Record.isModule()) { - if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D)) + if (auto *TU = dyn_cast<TranslationUnitDecl>(D)) TU->setAnonymousNamespace(Anon); else cast<NamespaceDecl>(D)->setAnonymousNamespace(Anon); @@ -3988,7 +4146,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, } case UPD_CXX_ADDED_VAR_DEFINITION: { - VarDecl *VD = cast<VarDecl>(D); + auto *VD = cast<VarDecl>(D); VD->NonParmVarDeclBits.IsInline = Record.readInt(); VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt(); uint64_t Val = Record.readInt(); @@ -4005,8 +4163,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, case UPD_CXX_POINT_OF_INSTANTIATION: { SourceLocation POI = Record.readSourceLocation(); - if (VarTemplateSpecializationDecl *VTSD = - dyn_cast<VarTemplateSpecializationDecl>(D)) { + if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) { VTSD->setPointOfInstantiation(POI); } else if (auto *VD = dyn_cast<VarDecl>(D)) { VD->getMemberSpecializationInfo()->setPointOfInstantiation(POI); @@ -4023,12 +4180,12 @@ void ASTDeclReader::UpdateDecl(Decl *D, } case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: { - auto Param = cast<ParmVarDecl>(D); + auto *Param = cast<ParmVarDecl>(D); // We have to read the default argument regardless of whether we use it // so that hypothetical further update records aren't messed up. // TODO: Add a function to skip over the next expr record. - auto DefaultArg = Record.readExpr(); + auto *DefaultArg = Record.readExpr(); // Only apply the update if the parameter still has an uninstantiated // default argument. @@ -4038,8 +4195,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, } case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER: { - auto FD = cast<FieldDecl>(D); - auto DefaultInit = Record.readExpr(); + auto *FD = cast<FieldDecl>(D); + auto *DefaultInit = Record.readExpr(); // Only apply the update if the field still has an uninstantiated // default member initializer. @@ -4055,7 +4212,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, } case UPD_CXX_ADDED_FUNCTION_DEFINITION: { - FunctionDecl *FD = cast<FunctionDecl>(D); + auto *FD = cast<FunctionDecl>(D); if (Reader.PendingBodies[FD]) { // FIXME: Maybe check for ODR violations. // It's safe to stop now because this update record is always last. @@ -4082,6 +4239,9 @@ void ASTDeclReader::UpdateDecl(Decl *D, bool HadRealDefinition = OldDD && (OldDD->Definition != RD || !Reader.PendingFakeDefinitionData.count(OldDD)); + RD->setParamDestroyedInCallee(Record.readInt()); + RD->setArgPassingRestrictions( + (RecordDecl::ArgPassingKind)Record.readInt()); ReadCXXRecordDefinition(RD, /*Update*/true); // Visible update is handled separately. @@ -4098,13 +4258,12 @@ void ASTDeclReader::UpdateDecl(Decl *D, MSInfo->setTemplateSpecializationKind(TSK); MSInfo->setPointOfInstantiation(POI); } else { - ClassTemplateSpecializationDecl *Spec = - cast<ClassTemplateSpecializationDecl>(RD); + auto *Spec = cast<ClassTemplateSpecializationDecl>(RD); Spec->setTemplateSpecializationKind(TSK); Spec->setPointOfInstantiation(POI); if (Record.readInt()) { - auto PartialSpec = + auto *PartialSpec = ReadDeclAs<ClassTemplatePartialSpecializationDecl>(); SmallVector<TemplateArgument, 8> TemplArgs; Record.readTemplateArgumentList(TemplArgs); @@ -4177,18 +4336,17 @@ void ASTDeclReader::UpdateDecl(Decl *D, QualType DeducedResultType = Record.readType(); for (auto *Redecl : merged_redecls(D)) { // FIXME: If the return type is already deduced, check that it matches. - FunctionDecl *FD = cast<FunctionDecl>(Redecl); + auto *FD = cast<FunctionDecl>(Redecl); Reader.getContext().adjustDeducedFunctionResultType(FD, DeducedResultType); } break; } - case UPD_DECL_MARKED_USED: { + case UPD_DECL_MARKED_USED: // Maintain AST consistency: any later redeclarations are used too. D->markUsed(Reader.getContext()); break; - } case UPD_MANGLING_NUMBER: Reader.getContext().setManglingNumber(cast<NamedDecl>(D), |