diff options
Diffstat (limited to 'clang')
27 files changed, 681 insertions, 309 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 70c3d5bbad6..229ac9fba97 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -19,6 +19,7 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/Decl.h" +#include "clang/AST/ExternalASTSource.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RawCommentList.h" @@ -51,7 +52,6 @@ namespace clang { class CharUnits; class DiagnosticsEngine; class Expr; - class ExternalASTSource; class ASTMutationListener; class IdentifierTable; class MaterializeTemporaryExpr; @@ -849,7 +849,7 @@ public: /// \brief Retrieve the declaration for a 128-bit float stub type. TypeDecl *getFloat128StubType() const; - + //===--------------------------------------------------------------------===// // Type Constructors //===--------------------------------------------------------------------===// @@ -2395,4 +2395,18 @@ inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) { C.Deallocate(Ptr); } +/// \brief Create the representation of a LazyGenerationalUpdatePtr. +template <typename Owner, typename T, + void (clang::ExternalASTSource::*Update)(Owner)> +typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType + clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue( + const clang::ASTContext &Ctx, T Value) { + // Note, this is implemented here so that ExternalASTSource.h doesn't need to + // include ASTContext.h. We explicitly instantiate it for all relevant types + // in ASTContext.cpp. + if (auto *Source = Ctx.getExternalSource()) + return new (Ctx) LazyData(Source, Value); + return Value; +} + #endif diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 94950b162fd..3618fa417be 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -355,9 +355,9 @@ class NamespaceDecl : public NamedDecl, public DeclContext, /// boolean value indicating whether this is an inline namespace. llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline; - NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - NamespaceDecl *PrevDecl); + NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, NamespaceDecl *PrevDecl); typedef Redeclarable<NamespaceDecl> redeclarable_base; NamespaceDecl *getNextRedeclarationImpl() override; @@ -769,7 +769,7 @@ protected: ParmVarDeclBitfields ParmVarDeclBits; }; - VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass SC); @@ -1214,10 +1214,10 @@ public: QualType T); static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc, + + ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType Type) - : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type, + : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type, /*tinfo*/ nullptr, SC_None) { setImplicit(); } @@ -1234,11 +1234,10 @@ public: enum { MaxFunctionScopeIndex = 255 }; protected: - ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, - StorageClass S, Expr *DefArg) - : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) { + ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) + : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); @@ -1535,7 +1534,7 @@ private: void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo); protected: - FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, + FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, @@ -1543,6 +1542,7 @@ protected: : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), DeclContext(DK), + redeclarable_base(C), ParamInfo(nullptr), Body(), SClass(S), IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), @@ -2405,10 +2405,11 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo; protected: - TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - TypeSourceInfo *TInfo) - : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {} + TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C), + MaybeModedTInfo(TInfo) {} typedef Redeclarable<TypedefNameDecl> redeclarable_base; TypedefNameDecl *getNextRedeclarationImpl() override { @@ -2464,9 +2465,9 @@ public: /// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef' /// type specifier. class TypedefDecl : public TypedefNameDecl { - TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {} + TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {} public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, @@ -2484,9 +2485,9 @@ public: /// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x /// alias-declaration. class TypeAliasDecl : public TypedefNameDecl { - TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {} + TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) + : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {} public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, @@ -2582,10 +2583,11 @@ private: } protected: - TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL) - : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK), - IsCompleteDefinition(false), IsBeingDefined(false), + TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, + SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C), + TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false), IsEmbeddedInDeclarator(false), IsFreeStanding(false), IsCompleteDefinitionRequired(false), NamedDeclOrQualifier((NamedDecl *)nullptr) { @@ -2632,8 +2634,8 @@ public: SourceLocation getOuterLocStart() const; SourceRange getSourceRange() const override LLVM_READONLY; - TagDecl* getCanonicalDecl() override; - const TagDecl* getCanonicalDecl() const { + TagDecl *getCanonicalDecl() override; + const TagDecl *getCanonicalDecl() const { return const_cast<TagDecl*>(this)->getCanonicalDecl(); } @@ -2828,11 +2830,11 @@ class EnumDecl : public TagDecl { /// information. MemberSpecializationInfo *SpecializationInfo; - EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, EnumDecl *PrevDecl, + EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, bool Scoped, bool ScopedUsingClassTag, bool Fixed) - : TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc), - SpecializationInfo(nullptr) { + : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc), + SpecializationInfo(nullptr) { assert(Scoped || !ScopedUsingClassTag); IntegerType = (const Type *)nullptr; NumNegativeBits = 0; @@ -3061,7 +3063,7 @@ class RecordDecl : public TagDecl { friend class DeclContext; protected: - RecordDecl(Kind DK, TagKind TK, DeclContext *DC, + RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl); @@ -3582,6 +3584,8 @@ template<typename decl_type> void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { // Note: This routine is implemented here because we need both NamedDecl // and Redeclarable to be defined. + assert(RedeclLink.NextIsLatest() && + "setPreviousDecl on a decl already in a redeclaration chain"); decl_type *First; @@ -3591,7 +3595,7 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. First = PrevDecl->getFirstDecl(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); - decl_type *MostRecent = First->RedeclLink.getNext(); + decl_type *MostRecent = First->getNextRedeclaration(); RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent)); // If the declaration was previously visible, a redeclaration of it remains @@ -3605,7 +3609,8 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { } // First one will point to this one as latest. - First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this)); + First->RedeclLink.setLatest(static_cast<decl_type*>(this)); + assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) || cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid()); } diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 8f0b36cb6b0..0ce0ddf1af2 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -494,7 +494,13 @@ class CXXRecordDecl : public RecordDecl { private: CXXBaseSpecifier *getBasesSlowCase() const; CXXBaseSpecifier *getVBasesSlowCase() const; - } *DefinitionData; + }; + + typedef LazyGenerationalUpdatePtr<const Decl*, struct DefinitionData*, + &ExternalASTSource::CompleteRedeclChain> + DefinitionDataPtr; + + mutable DefinitionDataPtr DefinitionData; /// \brief Describes a C++ closure type (generated by a lambda expression). struct LambdaDefinitionData : public DefinitionData { @@ -551,21 +557,16 @@ class CXXRecordDecl : public RecordDecl { }; - struct DefinitionData &data() { - assert(DefinitionData && "queried property of class with no definition"); - return *DefinitionData; - } - - const struct DefinitionData &data() const { - assert(DefinitionData && "queried property of class with no definition"); - return *DefinitionData; + struct DefinitionData &data() const { + auto *DD = DefinitionData.get(this); + assert(DD && "queried property of class with no definition"); + return *DD; } struct LambdaDefinitionData &getLambdaData() const { - assert(DefinitionData && "queried property of lambda with no definition"); - assert(DefinitionData->IsLambda && - "queried lambda property of non-lambda class"); - return static_cast<LambdaDefinitionData &>(*DefinitionData); + auto &DD = data(); + assert(DD.IsLambda && "queried lambda property of non-lambda class"); + return static_cast<LambdaDefinitionData&>(DD); } /// \brief The template or declaration that this declaration @@ -604,7 +605,7 @@ class CXXRecordDecl : public RecordDecl { FriendDecl *getFirstFriend() const; protected: - CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, + CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl); @@ -640,11 +641,11 @@ public: } CXXRecordDecl *getDefinition() const { - if (!DefinitionData) return nullptr; - return data().Definition; + auto *DD = DefinitionData.get(this); + return DD ? DD->Definition : nullptr; } - bool hasDefinition() const { return DefinitionData != nullptr; } + bool hasDefinition() const { return DefinitionData.get(this); } static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -653,7 +654,7 @@ public: bool DelayTypeCreation = false); static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC, TypeSourceInfo *Info, SourceLocation Loc, - bool DependentLambda, bool IsGeneric, + bool DependentLambda, bool IsGeneric, LambdaCaptureDefault CaptureDefault); static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); @@ -1658,12 +1659,12 @@ public: class CXXMethodDecl : public FunctionDecl { void anchor() override; protected: - CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, + CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD, + SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInline, bool isConstexpr, SourceLocation EndLocation) - : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo, + : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline, isConstexpr) { if (EndLocation.isValid()) setRangeEnd(EndLocation); @@ -2098,12 +2099,12 @@ class CXXConstructorDecl : public CXXMethodDecl { unsigned NumCtorInitializers; /// \} - CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, + CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, bool isConstexpr) - : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, + : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, SourceLocation()), IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr), NumCtorInitializers(0) { @@ -2298,11 +2299,11 @@ class CXXDestructorDecl : public CXXMethodDecl { FunctionDecl *OperatorDelete; - CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc, + CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, + : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), OperatorDelete(nullptr) { setImplicit(isImplicitlyDeclared); @@ -2349,12 +2350,12 @@ class CXXConversionDecl : public CXXMethodDecl { /// explicitly wrote a cast. This is a C++0x feature. bool IsExplicitSpecified : 1; - CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc, + CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isExplicitSpecified, bool isConstexpr, SourceLocation EndLocation) - : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, + : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, EndLocation), IsExplicitSpecified(isExplicitSpecified) { } @@ -2706,10 +2707,10 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> { NamedDecl *UsingOrNextShadow; friend class UsingDecl; - UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using, - NamedDecl *Target) + UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc, + UsingDecl *Using, NamedDecl *Target) : NamedDecl(UsingShadow, DC, Loc, DeclarationName()), - Underlying(Target), + redeclarable_base(C), Underlying(Target), UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) { if (Target) { setDeclName(Target->getDeclName()); @@ -2733,7 +2734,7 @@ public: static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target) { - return new (C, DC) UsingShadowDecl(DC, Loc, Using, Target); + return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target); } static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index f613f185f96..4ca02d2388e 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -734,9 +734,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl InheritedDesignatedInitializers(IDI_Unknown) { } }; - ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, - SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, - bool isInternal); + ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, + IdentifierInfo *Id, SourceLocation CLoc, + ObjCInterfaceDecl *PrevDecl, bool IsInternal); void LoadExternalDefinition() const; @@ -774,7 +774,7 @@ public: SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID); SourceRange getSourceRange() const override LLVM_READONLY { if (isThisDeclarationADefinition()) @@ -1524,7 +1524,7 @@ class ObjCProtocolDecl : public ObjCContainerDecl, return *Data.getPointer(); } - ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, + ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); @@ -1549,7 +1549,7 @@ public: ObjCProtocolDecl *PrevDecl); static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "No definition available!"); return data().ReferencedProtocols; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e9a0175854c..483ea7941f6 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -624,10 +624,11 @@ protected: virtual CommonBase *newCommon(ASTContext &C) const = 0; // Construct a template decl with name, parameters, and templated element. - RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName Name, TemplateParameterList *Params, - NamedDecl *Decl) - : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { } + RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C), + Common() {} public: template <class decl_type> friend class RedeclarableTemplate; @@ -775,9 +776,11 @@ protected: uint32_t *LazySpecializations; }; - FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, - TemplateParameterList *Params, NamedDecl *Decl) - : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } + FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, + DeclarationName Name, TemplateParameterList *Params, + NamedDecl *Decl) + : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params, + Decl) {} CommonBase *newCommon(ASTContext &C) const override; @@ -1438,7 +1441,7 @@ protected: unsigned NumArgs, ClassTemplateSpecializationDecl *PrevDecl); - explicit ClassTemplateSpecializationDecl(Kind DK); + explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK); public: static ClassTemplateSpecializationDecl * @@ -1676,8 +1679,8 @@ class ClassTemplatePartialSpecializationDecl const ASTTemplateArgumentListInfo *ArgsAsWritten, ClassTemplatePartialSpecializationDecl *PrevDecl); - ClassTemplatePartialSpecializationDecl() - : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization), + ClassTemplatePartialSpecializationDecl(ASTContext &C) + : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization), TemplateParams(nullptr), ArgsAsWritten(nullptr), InstantiatedFromMember(nullptr, false) {} @@ -1838,13 +1841,10 @@ protected: llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & getPartialSpecializations(); - ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, - TemplateParameterList *Params, NamedDecl *Decl) - : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { } - - ClassTemplateDecl(EmptyShell Empty) - : RedeclarableTemplateDecl(ClassTemplate, nullptr, SourceLocation(), - DeclarationName(), nullptr, nullptr) { } + ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, + DeclarationName Name, TemplateParameterList *Params, + NamedDecl *Decl) + : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {} CommonBase *newCommon(ASTContext &C) const override; @@ -2105,9 +2105,11 @@ class TypeAliasTemplateDecl : public RedeclarableTemplateDecl { protected: typedef CommonBase Common; - TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, - TemplateParameterList *Params, NamedDecl *Decl) - : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { } + TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, + DeclarationName Name, TemplateParameterList *Params, + NamedDecl *Decl) + : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params, + Decl) {} CommonBase *newCommon(ASTContext &C) const override; @@ -2297,14 +2299,14 @@ class VarTemplateSpecializationDecl : public VarDecl, unsigned SpecializationKind : 3; protected: - VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC, + VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, unsigned NumArgs); - explicit VarTemplateSpecializationDecl(Kind DK); + explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context); public: static VarTemplateSpecializationDecl * @@ -2532,8 +2534,8 @@ class VarTemplatePartialSpecializationDecl StorageClass S, const TemplateArgument *Args, unsigned NumArgs, const ASTTemplateArgumentListInfo *ArgInfos); - VarTemplatePartialSpecializationDecl() - : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization), + VarTemplatePartialSpecializationDecl(ASTContext &Context) + : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context), TemplateParams(nullptr), ArgsAsWritten(nullptr), InstantiatedFromMember(nullptr, false) {} @@ -2676,13 +2678,10 @@ protected: llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & getPartialSpecializations(); - VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, - TemplateParameterList *Params, NamedDecl *Decl) - : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {} - - VarTemplateDecl(EmptyShell Empty) - : RedeclarableTemplateDecl(VarTemplate, nullptr, SourceLocation(), - DeclarationName(), nullptr, nullptr) {} + VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, + DeclarationName Name, TemplateParameterList *Params, + NamedDecl *Decl) + : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {} CommonBase *newCommon(ASTContext &C) const override; diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 584f4adedd6..41176841394 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -45,7 +45,7 @@ enum ExternalLoadResult { /// no additional processing is required. ELR_AlreadyLoaded }; - + /// \brief Abstract interface for external sources of AST nodes. /// /// External AST sources provide AST nodes constructed from some @@ -54,6 +54,10 @@ enum ExternalLoadResult { /// actual type and declaration nodes, and read parts of declaration /// contexts. class ExternalASTSource : public RefCountedBase<ExternalASTSource> { + /// Generation number for this external AST source. Must be increased + /// whenever we might have added new redeclarations for existing decls. + uint32_t CurrentGeneration; + /// \brief Whether this AST source also provides information for /// semantic analysis. bool SemaSource; @@ -61,7 +65,7 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> { friend class ExternalSemaSource; public: - ExternalASTSource() : SemaSource(false) { } + ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { } virtual ~ExternalASTSource(); @@ -79,6 +83,11 @@ public: } }; + /// \brief Get the current generation of this AST source. This number + /// is incremented each time the AST source lazily extends an existing + /// entity. + uint32_t getGeneration() const { return CurrentGeneration; } + /// \brief Resolve a declaration ID into a declaration, potentially /// building a new declaration. /// @@ -176,6 +185,12 @@ public: SmallVectorImpl<Decl *> &Decls) {} /// \brief Gives the external AST source an opportunity to complete + /// the redeclaration chain for a declaration. Called each time we + /// need the most recent declaration of a declaration after the + /// generation count is incremented. + virtual void CompleteRedeclChain(const Decl *D) {} + + /// \brief Gives the external AST source an opportunity to complete /// an incomplete type. virtual void CompleteType(TagDecl *Tag) {} @@ -284,6 +299,9 @@ protected: static DeclContextLookupResult SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name); + + /// \brief Increment the current generation. + uint32_t incrementGeneration(ASTContext &C); }; /// \brief A lazy pointer to an AST node (of base type T) that resides @@ -354,6 +372,97 @@ public: } }; +/// \brief A lazy value (of type T) that is within an AST node of type Owner, +/// where the value might change in later generations of the external AST +/// source. +template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)> +struct LazyGenerationalUpdatePtr { + /// A cache of the value of this pointer, in the most recent generation in + /// which we queried it. + struct LazyData { + LazyData(ExternalASTSource *Source, T Value) + : ExternalSource(Source), LastGeneration(Source->getGeneration()), + LastValue(Value) {} + ExternalASTSource *ExternalSource; + uint32_t LastGeneration; + T LastValue; + }; + + // Our value is represented as simply T if there is no external AST source. + typedef llvm::PointerUnion<T, LazyData*> ValueType; + ValueType Value; + + LazyGenerationalUpdatePtr(ValueType V) : Value(V) {} + + // Defined in ASTContext.h + static ValueType makeValue(const ASTContext &Ctx, T Value); + +public: + explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T()) + : Value(makeValue(Ctx, Value)) {} + + /// Create a pointer that is not potentially updated by later generations of + /// the external AST source. + enum NotUpdatedTag { NotUpdated }; + LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T()) + : Value(Value) {} + + /// Set the value of this pointer, in the current generation. + void set(T NewValue) { + if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) { + LazyVal->LastValue = NewValue; + LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration(); + return; + } + Value = NewValue; + } + + /// Set the value of this pointer, for this and all future generations. + void setNotUpdated(T NewValue) { Value = NewValue; } + + /// Get the value of this pointer, updating its owner if necessary. + T get(Owner O) { + if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) { + if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) { + LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration(); + (LazyVal->ExternalSource->*Update)(O); + } + return LazyVal->LastValue; + } + return Value.template get<T>(); + } + + /// Get the most recently computed value of this pointer without updating it. + T getNotUpdated() const { + if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) + return LazyVal->LastValue; + return Value.template get<T>(); + } + + void *getOpaqueValue() { return Value.getOpaqueValue(); } + static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) { + return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr)); + } +}; +} // end namespace clang + +/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be +/// placed into a PointerUnion. +namespace llvm { +template<typename Owner, typename T, + void (clang::ExternalASTSource::*Update)(Owner)> +struct PointerLikeTypeTraits< + clang::LazyGenerationalUpdatePtr<Owner, T, Update>> { + typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr; + static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } + static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } + enum { + NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1 + }; +}; +} + +namespace clang { /// \brief Represents a lazily-loaded vector of data. /// /// The lazily-loaded vector of data contains data that is partially loaded diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h index 9fbc88e9585..73095d46f7b 100644 --- a/clang/include/clang/AST/Redeclarable.h +++ b/clang/include/clang/AST/Redeclarable.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_REDECLARABLE_H #define LLVM_CLANG_AST_REDECLARABLE_H +#include "clang/AST/ExternalASTSource.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Casting.h" #include <iterator> @@ -25,23 +26,78 @@ template<typename decl_type> class Redeclarable { protected: class DeclLink { - llvm::PointerIntPair<decl_type *, 1, bool> NextAndIsPrevious; + /// A pointer to a known latest declaration, either statically known or + /// generationally updated as decls are added by an external source. + typedef LazyGenerationalUpdatePtr<const Decl*, Decl*, + &ExternalASTSource::CompleteRedeclChain> + KnownLatest; + + typedef const ASTContext *UninitializedLatest; + typedef Decl *Previous; + + /// A pointer to either an uninitialized latest declaration (where either + /// we've not yet set the previous decl or there isn't one), or to a known + /// previous declaration. + typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest; + + mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next; + public: - DeclLink(decl_type *D, bool isLatest) - : NextAndIsPrevious(D, isLatest) { } + enum PreviousTag { PreviousLink }; + enum LatestTag { LatestLink }; + + DeclLink(LatestTag, const ASTContext &Ctx) + : Next(NotKnownLatest(&Ctx)) {} + DeclLink(PreviousTag, decl_type *D) + : Next(NotKnownLatest(Previous(D))) {} + + bool NextIsPrevious() const { + return Next.is<NotKnownLatest>() && + // FIXME: 'template' is required on the next line due to an + // apparent clang bug. + Next.get<NotKnownLatest>().template is<Previous>(); + } + + bool NextIsLatest() const { return !NextIsPrevious(); } + + decl_type *getNext(const decl_type *D) const { + if (Next.is<NotKnownLatest>()) { + NotKnownLatest NKL = Next.get<NotKnownLatest>(); + if (NKL.is<Previous>()) + return static_cast<decl_type*>(NKL.get<Previous>()); + + // Allocate the generational 'most recent' cache now, if needed. + Next = KnownLatest(*NKL.get<UninitializedLatest>(), + const_cast<decl_type *>(D)); + } + + return static_cast<decl_type*>(Next.get<KnownLatest>().get(D)); + } + + void setPrevious(decl_type *D) { + assert(NextIsPrevious() && "decl became non-canonical unexpectedly"); + Next = Previous(D); + } - bool NextIsPrevious() const { return !NextAndIsPrevious.getInt(); } - bool NextIsLatest() const { return NextAndIsPrevious.getInt(); } - decl_type *getNext() const { return NextAndIsPrevious.getPointer(); } - void setNext(decl_type *D) { NextAndIsPrevious.setPointer(D); } + void setLatest(decl_type *D) { + assert(NextIsLatest() && "decl became canonical unexpectedly"); + if (Next.is<NotKnownLatest>()) { + NotKnownLatest NKL = Next.get<NotKnownLatest>(); + Next = KnownLatest(*NKL.get<UninitializedLatest>(), D); + } else { + auto Latest = Next.get<KnownLatest>(); + Latest.set(D); + Next = Latest; + } + } }; static DeclLink PreviousDeclLink(decl_type *D) { - return DeclLink(D, false); + return DeclLink(DeclLink::PreviousLink, D); } - static DeclLink LatestDeclLink(decl_type *D) { - return DeclLink(D, true); + static DeclLink LatestDeclLink(const ASTContext &Ctx) { + return DeclLink(DeclLink::LatestLink, Ctx); } /// \brief Points to the next redeclaration in the chain. @@ -58,11 +114,12 @@ protected: DeclLink RedeclLink; decl_type *getNextRedeclaration() const { - return RedeclLink.getNext(); + return RedeclLink.getNext(static_cast<const decl_type *>(this)); } public: - Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { } + Redeclarable(const ASTContext &Ctx) + : RedeclLink(LatestDeclLink(Ctx)) {} /// \brief Return the previous declaration of this declaration or NULL if this /// is the first declaration. @@ -106,7 +163,7 @@ public: const decl_type *getMostRecentDecl() const { return getFirstDecl()->getNextRedeclaration(); } - + /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the /// first and only declaration. void setPreviousDecl(decl_type *PrevDecl); diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 050f6c972d6..7860b6da06a 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -67,6 +67,10 @@ public: /// building a new declaration. Decl *GetExternalDecl(uint32_t ID) override; + /// \brief Complete the redeclaration chain if it's been extended since the + /// previous generation of the AST source. + void CompleteRedeclChain(const Decl *D) override; + /// \brief Resolve a selector ID into a selector. Selector GetExternalSelector(uint32_t ID) override; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index ba02e30c14c..bb1741ba06b 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -821,10 +821,6 @@ private: /// \brief Whether we have tried loading the global module index yet. bool TriedLoadingGlobalIndex; - /// \brief The current "generation" of the module file import stack, which - /// indicates how many separate module file load operations have occurred. - unsigned CurrentGeneration; - typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy; /// \brief Mapping from switch-case IDs in the chain to switch-case statements /// @@ -1641,6 +1637,11 @@ public: return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I))); } + /// \brief If any redeclarations of \p D have been imported since it was + /// last checked, this digs out those redeclarations and adds them to the + /// redeclaration chain for \p D. + void CompleteRedeclChain(const Decl *D) override; + /// \brief Read a CXXBaseSpecifiers ID form the given record and /// return its global bit offset. uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 2f406166690..fe735dc92fc 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8239,3 +8239,12 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, return (MethodDecl->isVariadic() == MethodImpl->isVariadic()); } + +// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that +// doesn't include ASTContext.h +template +clang::LazyGenerationalUpdatePtr< + const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType +clang::LazyGenerationalUpdatePtr< + const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue( + const clang::ASTContext &Ctx, Decl *Value); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 101b1646248..fc15bdee010 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1616,10 +1616,12 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) { llvm_unreachable("Invalid storage class"); } -VarDecl::VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo, StorageClass SC) - : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { +VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, + StorageClass SC) + : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), + redeclarable_base(C), Init() { static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned), "VarDeclBitfields too large!"); static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned), @@ -1633,12 +1635,13 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, SourceLocation IdL, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S) { - return new (C, DC) VarDecl(Var, DC, StartL, IdL, Id, T, TInfo, S); + return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); } VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) VarDecl(Var, nullptr, SourceLocation(), SourceLocation(), - nullptr, QualType(), nullptr, SC_None); + return new (C, ID) + VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, + QualType(), nullptr, SC_None); } void VarDecl::setStorageClass(StorageClass SC) { @@ -2114,7 +2117,7 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) { - return new (C, DC) ParmVarDecl(ParmVar, DC, StartLoc, IdLoc, Id, T, TInfo, + return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo, S, DefArg); } @@ -2127,9 +2130,9 @@ QualType ParmVarDecl::getOriginalType() const { } ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) ParmVarDecl(ParmVar, nullptr, SourceLocation(), - SourceLocation(), nullptr, QualType(), - nullptr, SC_None, nullptr); + return new (C, ID) + ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), + nullptr, QualType(), nullptr, SC_None, nullptr); } SourceRange ParmVarDecl::getSourceRange() const { @@ -3234,10 +3237,10 @@ void TagDecl::startDefinition() { IsBeingDefined = true; if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) { - struct CXXRecordDecl::DefinitionData *Data = + struct CXXRecordDecl::DefinitionData *Data = new (getASTContext()) struct CXXRecordDecl::DefinitionData(D); for (auto I : redecls()) - cast<CXXRecordDecl>(I)->DefinitionData = Data; + cast<CXXRecordDecl>(I)->DefinitionData.setNotUpdated(Data); } } @@ -3319,7 +3322,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed) { - EnumDecl *Enum = new (C, DC) EnumDecl(DC, StartLoc, IdLoc, Id, PrevDecl, + EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl, IsScoped, IsScopedUsingClassTag, IsFixed); Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules; @@ -3328,9 +3331,9 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, } EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - EnumDecl *Enum = new (C, ID) EnumDecl(nullptr, SourceLocation(), - SourceLocation(), nullptr, nullptr, - false, false, false); + EnumDecl *Enum = + new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), + nullptr, nullptr, false, false, false); Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules; return Enum; } @@ -3389,10 +3392,11 @@ void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, // RecordDecl Implementation //===----------------------------------------------------------------------===// -RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, - SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, RecordDecl *PrevDecl) - : TagDecl(DK, TK, DC, IdLoc, Id, PrevDecl, StartLoc) { +RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C, + DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + RecordDecl *PrevDecl) + : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) { HasFlexibleArrayMember = false; AnonymousStructOrUnion = false; HasObjectMember = false; @@ -3404,8 +3408,8 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl* PrevDecl) { - RecordDecl* R = new (C, DC) RecordDecl(Record, TK, DC, StartLoc, IdLoc, Id, - PrevDecl); + RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC, + StartLoc, IdLoc, Id, PrevDecl); R->MayHaveOutOfDateDef = C.getLangOpts().Modules; C.getTypeDeclType(R, PrevDecl); @@ -3413,9 +3417,9 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, } RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { - RecordDecl *R = new (C, ID) RecordDecl(Record, TTK_Struct, nullptr, - SourceLocation(), SourceLocation(), - nullptr, nullptr); + RecordDecl *R = + new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(), + SourceLocation(), nullptr, nullptr); R->MayHaveOutOfDateDef = C.getLangOpts().Modules; return R; } @@ -3577,12 +3581,12 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType Type) { - return new (C, DC) ImplicitParamDecl(DC, IdLoc, Id, Type); + return new (C, DC) ImplicitParamDecl(C, DC, IdLoc, Id, Type); } ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) ImplicitParamDecl(nullptr, SourceLocation(), nullptr, + return new (C, ID) ImplicitParamDecl(C, nullptr, SourceLocation(), nullptr, QualType()); } @@ -3595,14 +3599,14 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, bool hasWrittenPrototype, bool isConstexprSpecified) { FunctionDecl *New = - new (C, DC) FunctionDecl(Function, DC, StartLoc, NameInfo, T, TInfo, SC, - isInlineSpecified, isConstexprSpecified); + new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo, + SC, isInlineSpecified, isConstexprSpecified); New->HasWrittenPrototype = hasWrittenPrototype; return New; } FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) FunctionDecl(Function, nullptr, SourceLocation(), + return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false); } @@ -3668,13 +3672,13 @@ void TypeDecl::anchor() { } TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) { - return new (C, DC) TypedefDecl(DC, StartLoc, IdLoc, Id, TInfo); + return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } void TypedefNameDecl::anchor() { } TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) TypedefDecl(nullptr, SourceLocation(), SourceLocation(), + return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -3682,12 +3686,12 @@ TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) { - return new (C, DC) TypeAliasDecl(DC, StartLoc, IdLoc, Id, TInfo); + return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) TypeAliasDecl(nullptr, SourceLocation(), SourceLocation(), - nullptr, nullptr); + return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), + SourceLocation(), nullptr, nullptr); } SourceRange TypedefDecl::getSourceRange() const { diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 4cd35fc462b..1c416282759 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -82,19 +82,21 @@ CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const { return VBases.get(Definition->getASTContext().getExternalSource()); } -CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, - SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, CXXRecordDecl *PrevDecl) - : RecordDecl(K, TK, DC, StartLoc, IdLoc, Id, PrevDecl), - DefinitionData(PrevDecl ? PrevDecl->DefinitionData : nullptr), - TemplateOrInstantiation() { } +CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, + DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, + CXXRecordDecl *PrevDecl) + : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl), + DefinitionData(PrevDecl ? PrevDecl->DefinitionData + : DefinitionDataPtr(C)), + TemplateOrInstantiation() {} CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl* PrevDecl, bool DelayTypeCreation) { - CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, DC, StartLoc, + CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl); R->MayHaveOutOfDateDef = C.getLangOpts().Modules; @@ -104,18 +106,18 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, return R; } -CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, - TypeSourceInfo *Info, SourceLocation Loc, - bool Dependent, bool IsGeneric, - LambdaCaptureDefault CaptureDefault) { +CXXRecordDecl * +CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, + TypeSourceInfo *Info, SourceLocation Loc, + bool Dependent, bool IsGeneric, + LambdaCaptureDefault CaptureDefault) { CXXRecordDecl *R = - new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc, nullptr, - nullptr); + new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc, + nullptr, nullptr); R->IsBeingDefined = true; - R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, - Dependent, - IsGeneric, - CaptureDefault); + R->DefinitionData.setNotUpdated( + new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric, + CaptureDefault)); R->MayHaveOutOfDateDef = false; R->setImplicit(true); C.getTypeDeclType(R, /*PrevDecl=*/nullptr); @@ -125,7 +127,7 @@ CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, CXXRecordDecl * CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { CXXRecordDecl *R = new (C, ID) CXXRecordDecl( - CXXRecord, TTK_Struct, nullptr, SourceLocation(), SourceLocation(), + CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); R->MayHaveOutOfDateDef = false; return R; @@ -1410,12 +1412,13 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInline, bool isConstexpr, SourceLocation EndLocation) { - return new (C, RD) CXXMethodDecl(CXXMethod, RD, StartLoc, NameInfo, T, TInfo, - SC, isInline, isConstexpr, EndLocation); + return new (C, RD) CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo, + T, TInfo, SC, isInline, isConstexpr, + EndLocation); } CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXMethodDecl(CXXMethod, nullptr, SourceLocation(), + return new (C, ID) CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, SourceLocation()); } @@ -1680,7 +1683,7 @@ void CXXConstructorDecl::anchor() { } CXXConstructorDecl * CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXConstructorDecl(nullptr, SourceLocation(), + return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, false); } @@ -1695,7 +1698,7 @@ CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, assert(NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor"); - return new (C, RD) CXXConstructorDecl(RD, StartLoc, NameInfo, T, TInfo, + return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, isExplicit, isInline, isImplicitlyDeclared, isConstexpr); } @@ -1830,9 +1833,9 @@ void CXXDestructorDecl::anchor() { } CXXDestructorDecl * CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXDestructorDecl( - nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, - false, false); + return new (C, ID) + CXXDestructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(), + QualType(), nullptr, false, false); } CXXDestructorDecl * @@ -1844,7 +1847,7 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, assert(NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && "Name must refer to a destructor"); - return new (C, RD) CXXDestructorDecl(RD, StartLoc, NameInfo, T, TInfo, + return new (C, RD) CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, isImplicitlyDeclared); } @@ -1852,7 +1855,7 @@ void CXXConversionDecl::anchor() { } CXXConversionDecl * CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) CXXConversionDecl(nullptr, SourceLocation(), + return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, SourceLocation()); @@ -1868,7 +1871,7 @@ CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, assert(NameInfo.getName().getNameKind() == DeclarationName::CXXConversionFunctionName && "Name must refer to a conversion function"); - return new (C, RD) CXXConversionDecl(RD, StartLoc, NameInfo, T, TInfo, + return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, isExplicit, isConstexpr, EndLocation); } @@ -1925,15 +1928,14 @@ NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { return cast_or_null<NamespaceDecl>(NominatedNamespace); } -NamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline, - SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - NamespaceDecl *PrevDecl) - : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace), - LocStart(StartLoc), RBraceLoc(), - AnonOrFirstNamespaceAndInline(nullptr, Inline) { +NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, NamespaceDecl *PrevDecl) + : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace), + redeclarable_base(C), LocStart(StartLoc), RBraceLoc(), + AnonOrFirstNamespaceAndInline(nullptr, Inline) { setPreviousDecl(PrevDecl); - + if (PrevDecl) AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace()); } @@ -1942,11 +1944,12 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, NamespaceDecl *PrevDecl) { - return new (C, DC) NamespaceDecl(DC, Inline, StartLoc, IdLoc, Id, PrevDecl); + return new (C, DC) NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, + PrevDecl); } NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) NamespaceDecl(nullptr, false, SourceLocation(), + return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -1987,8 +1990,8 @@ void UsingShadowDecl::anchor() { } UsingShadowDecl * UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) UsingShadowDecl(nullptr, SourceLocation(), nullptr, - nullptr); + return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(), + nullptr, nullptr); } UsingDecl *UsingShadowDecl::getUsingDecl() const { diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 42462a1b140..186a7417b65 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -1134,15 +1134,15 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C, SourceLocation ClassLoc, bool isInternal){ ObjCInterfaceDecl *Result = new (C, DC) - ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, PrevDecl, isInternal); + ObjCInterfaceDecl(C, DC, atLoc, Id, ClassLoc, PrevDecl, isInternal); Result->Data.setInt(!C.getLangOpts().Modules); C.getObjCInterfaceType(Result, PrevDecl); return Result; } -ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C, +ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { - ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(nullptr, + ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, SourceLocation(), @@ -1151,20 +1151,20 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C, return Result; } -ObjCInterfaceDecl:: -ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, - SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, - bool isInternal) - : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc), - TypeForDecl(nullptr), Data() -{ +ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, + SourceLocation AtLoc, IdentifierInfo *Id, + SourceLocation CLoc, + ObjCInterfaceDecl *PrevDecl, + bool IsInternal) + : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc), + redeclarable_base(C), TypeForDecl(nullptr), Data() { setPreviousDecl(PrevDecl); // Copy the 'data' pointer over. if (PrevDecl) Data = PrevDecl->Data; - setImplicit(isInternal); + setImplicit(IsInternal); } void ObjCInterfaceDecl::LoadExternalDefinition() const { @@ -1487,12 +1487,12 @@ ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, void ObjCProtocolDecl::anchor() { } -ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, - SourceLocation nameLoc, +ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC, + IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl) - : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data() -{ + : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), + redeclarable_base(C), Data() { setPreviousDecl(PrevDecl); if (PrevDecl) Data = PrevDecl->Data; @@ -1504,7 +1504,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl) { ObjCProtocolDecl *Result = - new (C, DC) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl); + new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl); Result->Data.setInt(!C.getLangOpts().Modules); return Result; } @@ -1512,7 +1512,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, unsigned ID) { ObjCProtocolDecl *Result = - new (C, ID) ObjCProtocolDecl(nullptr, nullptr, SourceLocation(), + new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), SourceLocation(), nullptr); Result->Data.setInt(!C.getLangOpts().Modules); return Result; diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 4a934747e94..a69146b5b88 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -229,12 +229,12 @@ FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, TemplateParameterList *Params, NamedDecl *Decl) { AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); - return new (C, DC) FunctionTemplateDecl(DC, L, Name, Params, Decl); + return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl); } FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) FunctionTemplateDecl(nullptr, SourceLocation(), + return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -307,15 +307,16 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, NamedDecl *Decl, ClassTemplateDecl *PrevDecl) { AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); - ClassTemplateDecl *New = - new (C, DC) ClassTemplateDecl(DC, L, Name, Params, Decl); + ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name, + Params, Decl); New->setPreviousDecl(PrevDecl); return New; } -ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, +ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) ClassTemplateDecl(EmptyShell()); + return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), + DeclarationName(), nullptr, nullptr); } void ClassTemplateDecl::LoadLazySpecializations() const { @@ -695,7 +696,7 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, const TemplateArgument *Args, unsigned NumArgs, ClassTemplateSpecializationDecl *PrevDecl) - : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc, + : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), PrevDecl), SpecializedTemplate(SpecializedTemplate), @@ -704,12 +705,11 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, SpecializationKind(TSK_Undeclared) { } -ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK) - : CXXRecordDecl(DK, TTK_Struct, nullptr, SourceLocation(), SourceLocation(), - nullptr, nullptr), - ExplicitInfo(nullptr), - SpecializationKind(TSK_Undeclared) { -} +ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, + Kind DK) + : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), + SourceLocation(), nullptr, nullptr), + ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} ClassTemplateSpecializationDecl * ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, @@ -734,7 +734,7 @@ ClassTemplateSpecializationDecl * ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { ClassTemplateSpecializationDecl *Result = - new (C, ID) ClassTemplateSpecializationDecl(ClassTemplateSpecialization); + new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); Result->MayHaveOutOfDateDef = false; return Result; } @@ -851,7 +851,7 @@ ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { ClassTemplatePartialSpecializationDecl *Result = - new (C, ID) ClassTemplatePartialSpecializationDecl(); + new (C, ID) ClassTemplatePartialSpecializationDecl(C); Result->MayHaveOutOfDateDef = false; return Result; } @@ -889,12 +889,12 @@ TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, TemplateParameterList *Params, NamedDecl *Decl) { AdoptTemplateParameterList(Params, DC); - return new (C, DC) TypeAliasTemplateDecl(DC, L, Name, Params, Decl); + return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); } TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) TypeAliasTemplateDecl(nullptr, SourceLocation(), + return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -943,12 +943,13 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl) { - return new (C, DC) VarTemplateDecl(DC, L, Name, Params, Decl); + return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); } VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) VarTemplateDecl(EmptyShell()); + return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), + DeclarationName(), nullptr, nullptr); } // TODO: Unify across class, function and variable templates? @@ -1057,18 +1058,19 @@ VarTemplateDecl::findPartialSpecInstantiatedFromMember( // VarTemplateSpecializationDecl Implementation //===----------------------------------------------------------------------===// VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( - ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc, + Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, unsigned NumArgs) - : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T, - TInfo, S), + : VarDecl(DK, Context, DC, StartLoc, IdLoc, + SpecializedTemplate->getIdentifier(), T, TInfo, S), SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr), TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), SpecializationKind(TSK_Undeclared) {} -VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK) - : VarDecl(DK, nullptr, SourceLocation(), SourceLocation(), nullptr, +VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, + ASTContext &C) + : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None), ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} @@ -1078,13 +1080,14 @@ VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, unsigned NumArgs) { return new (Context, DC) VarTemplateSpecializationDecl( - Context, VarTemplateSpecialization, DC, StartLoc, IdLoc, + VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, SpecializedTemplate, T, TInfo, S, Args, NumArgs); } VarTemplateSpecializationDecl * VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization); + return new (C, ID) + VarTemplateSpecializationDecl(VarTemplateSpecialization, C); } void VarTemplateSpecializationDecl::getNameForDiagnostic( @@ -1123,7 +1126,7 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, unsigned NumArgs, const ASTTemplateArgumentListInfo *ArgInfos) - : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization, + : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, DC, StartLoc, IdLoc, SpecializedTemplate, T, TInfo, S, Args, NumArgs), TemplateParams(Params), ArgsAsWritten(ArgInfos), @@ -1153,5 +1156,5 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl * VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) VarTemplatePartialSpecializationDecl(); + return new (C, ID) VarTemplatePartialSpecializationDecl(C); } diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index 05a17db6bf0..ae8297cecd1 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -14,7 +14,9 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/DeclarationName.h" +#include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -60,3 +62,21 @@ ExternalASTSource::FindExternalLexicalDecls(const DeclContext *DC, } void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { } + +uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) { + uint32_t OldGeneration = CurrentGeneration; + + // Make sure the generation of the topmost external source for the context is + // incremented. That might not be us. + auto *P = C.getExternalSource(); + if (P && P != this) + CurrentGeneration = P->incrementGeneration(C); + else { + // FIXME: Only bump the generation counter if the current generation number + // has been observed? + if (!++CurrentGeneration) + llvm::report_fatal_error("generation counter overflowed", false); + } + + return OldGeneration; +} diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 941410a7416..56c8a07140b 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -841,8 +841,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { } else { // Fake up a new variable so that EmitScalarInit doesn't think // we're referring to the variable in its own initializer. - ImplicitParamDecl blockFieldPseudoVar(/*DC*/ 0, SourceLocation(), - /*name*/ 0, type); + ImplicitParamDecl blockFieldPseudoVar(getContext(), /*DC*/ 0, + SourceLocation(), /*name*/ 0, type); // We use one of these or the other depending on whether the // reference is nested. @@ -1108,7 +1108,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, QualType selfTy = getContext().VoidPtrTy; IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor"); - ImplicitParamDecl selfDecl(const_cast<BlockDecl*>(blockDecl), + ImplicitParamDecl selfDecl(getContext(), const_cast<BlockDecl*>(blockDecl), SourceLocation(), II, selfTy); args.push_back(&selfDecl); @@ -1279,9 +1279,9 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { ASTContext &C = getContext(); FunctionArgList args; - ImplicitParamDecl dstDecl(0, SourceLocation(), 0, C.VoidPtrTy); + ImplicitParamDecl dstDecl(getContext(), 0, SourceLocation(), 0, C.VoidPtrTy); args.push_back(&dstDecl); - ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy); + ImplicitParamDecl srcDecl(getContext(), 0, SourceLocation(), 0, C.VoidPtrTy); args.push_back(&srcDecl); const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( @@ -1453,7 +1453,7 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { ASTContext &C = getContext(); FunctionArgList args; - ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy); + ImplicitParamDecl srcDecl(getContext(), 0, SourceLocation(), 0, C.VoidPtrTy); args.push_back(&srcDecl); const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( @@ -1738,10 +1738,12 @@ generateByrefCopyHelper(CodeGenFunction &CGF, QualType R = Context.VoidTy; FunctionArgList args; - ImplicitParamDecl dst(0, SourceLocation(), 0, Context.VoidPtrTy); + ImplicitParamDecl dst(CGF.getContext(), 0, SourceLocation(), 0, + Context.VoidPtrTy); args.push_back(&dst); - ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy); + ImplicitParamDecl src(CGF.getContext(), 0, SourceLocation(), 0, + Context.VoidPtrTy); args.push_back(&src); const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration( @@ -1810,7 +1812,8 @@ generateByrefDisposeHelper(CodeGenFunction &CGF, QualType R = Context.VoidTy; FunctionArgList args; - ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy); + ImplicitParamDecl src(CGF.getContext(), 0, SourceLocation(), 0, + Context.VoidPtrTy); args.push_back(&src); const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration( diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 59129f6aeea..0cc9330a866 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -522,7 +522,8 @@ llvm::Function *CodeGenFunction::generateDestroyHelper( llvm::Constant *addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const VarDecl *VD) { FunctionArgList args; - ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy); + ImplicitParamDecl dst(getContext(), 0, SourceLocation(), 0, + getContext().VoidPtrTy); args.push_back(&dst); const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 47a096d5404..d1cfddce9f1 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -2901,9 +2901,9 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( SrcTy = C.getPointerType(SrcTy); FunctionArgList args; - ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy); + ImplicitParamDecl dstDecl(getContext(), FD, SourceLocation(), 0, DestTy); args.push_back(&dstDecl); - ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy); + ImplicitParamDecl srcDecl(getContext(), FD, SourceLocation(), 0, SrcTy); args.push_back(&srcDecl); const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( @@ -2980,9 +2980,9 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( SrcTy = C.getPointerType(SrcTy); FunctionArgList args; - ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy); + ImplicitParamDecl dstDecl(getContext(), FD, SourceLocation(), 0, DestTy); args.push_back(&dstDecl); - ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy); + ImplicitParamDecl srcDecl(getContext(), FD, SourceLocation(), 0, SrcTy); args.push_back(&srcDecl); const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 77eb1a14434..ade23b87d17 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -358,8 +358,21 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // source. if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) { Preprocessor &PP = CI.getPreprocessor(); + + // If modules are enabled, create the module manager before creating + // any builtins, so that all declarations know that they might be + // extended by an external source. + if (CI.getLangOpts().Modules) + CI.createModuleManager(); + PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), PP.getLangOpts()); + } else { + // FIXME: If this is a problem, recover from it by creating a multiplex + // source. + assert((!CI.getLangOpts().Modules || CI.getModuleManager()) && + "modules enabled but created an external source that " + "doesn't support modules"); } // If there is a layout overrides file, attach an external AST source that @@ -371,7 +384,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, CI.getFrontendOpts().OverrideRecordLayoutsFile)); CI.getASTContext().setExternalSource(Override); } - + return true; // If we failed, reset state since the client will not end up calling the diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index ad7627a4571..35072a5faca 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -49,6 +49,11 @@ Decl *MultiplexExternalSemaSource::GetExternalDecl(uint32_t ID) { return 0; } +void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) { + for (size_t i = 0; i < Sources.size(); ++i) + Sources[i]->CompleteRedeclChain(D); +} + Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) { Selector Sel; for(size_t i = 0; i < Sources.size(); ++i) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index d61372cc1bd..eb151ef16f6 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1707,7 +1707,7 @@ void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) { // Update the generation for this identifier. if (getContext().getLangOpts().Modules) - IdentifierGeneration[II] = CurrentGeneration; + IdentifierGeneration[II] = getGeneration(); } struct ASTReader::ModuleMacroInfo { @@ -3435,7 +3435,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, Deserializing AnASTFile(this); // Bump the generation number. - unsigned PreviousGeneration = CurrentGeneration++; + unsigned PreviousGeneration = incrementGeneration(Context); unsigned NumModules = ModuleMgr.size(); SmallVector<ImportedModule, 4> Loaded; @@ -3615,7 +3615,7 @@ ASTReader::ReadASTCore(StringRef FileName, std::string ErrorStr; ModuleManager::AddModuleResult AddResult = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy, - CurrentGeneration, ExpectedSize, ExpectedModTime, + getGeneration(), ExpectedSize, ExpectedModTime, M, ErrorStr); switch (AddResult) { @@ -5939,6 +5939,37 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) { return GetDecl(ID); } +void ASTReader::CompleteRedeclChain(const Decl *D) { + const DeclContext *DC = D->getDeclContext()->getRedeclContext(); + + // Recursively ensure that the decl context itself is complete + // (in particular, this matters if the decl context is a namespace). + // + // FIXME: This should be performed by lookup instead of here. + cast<Decl>(DC)->getMostRecentDecl(); + + // If this is a named declaration, complete it by looking it up + // within its context. + // + // FIXME: We don't currently handle the cases where we can't do this; + // merging a class definition that contains unnamed entities should merge + // those entities. Likewise, merging a function definition should merge + // all mergeable entities within it. + if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) || + isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) { + if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) { + auto *II = Name.getAsIdentifierInfo(); + if (isa<TranslationUnitDecl>(DC) && II) { + // Outside of C++, we don't have a lookup table for the TU, so update + // the identifier instead. In C++, either way should work fine. + if (II->isOutOfDate()) + updateOutOfDateIdentifier(*II); + } else + DC->lookup(Name); + } + } +} + uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, unsigned &Idx) { @@ -6926,7 +6957,7 @@ void ASTReader::ReadMethodPool(Selector Sel) { // Get the selector generation and update it to the current generation. unsigned &Generation = SelectorGeneration[Sel]; unsigned PriorGeneration = Generation; - Generation = CurrentGeneration; + Generation = getGeneration(); // Search for methods defined with this selector. ++NumMethodPoolLookups; @@ -8114,7 +8145,6 @@ void ASTReader::finishPendingActions() { if (auto RD = dyn_cast<CXXRecordDecl>(*D)) { for (auto R : RD->redecls()) cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData; - } continue; @@ -8250,7 +8280,7 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot, AllowConfigurationMismatch(AllowConfigurationMismatch), ValidateSystemInputs(ValidateSystemInputs), UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false), - CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts), + CurrSwitchCaseStmts(&SwitchCaseStmts), NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), TotalNumMacros(0), NumIdentifierLookups(0), NumIdentifierLookupHits(0), NumSelectorsRead(0), diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index d2219d49812..719d56edf2c 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1289,8 +1289,9 @@ void ASTDeclReader::ReadCXXDefinitionData( void ASTDeclReader::MergeDefinitionData( CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &MergeDD) { - assert(D->DefinitionData && "merging class definition into non-definition"); - auto &DD = *D->DefinitionData; + assert(D->DefinitionData.getNotUpdated() && + "merging class definition into non-definition"); + auto &DD = *D->DefinitionData.getNotUpdated(); // If the new definition has new special members, let the name lookup // code know that it needs to look in the new definition too. @@ -1390,7 +1391,7 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) { // If we're reading an update record, we might already have a definition for // this record. If so, just merge into it. - if (D->DefinitionData) { + if (D->DefinitionData.getNotUpdated()) { MergeDefinitionData(D, *DD); return; } @@ -1399,25 +1400,26 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) { // that all other deserialized declarations will see it. CXXRecordDecl *Canon = D->getCanonicalDecl(); if (Canon == D) { - D->DefinitionData = DD; + D->DefinitionData.setNotUpdated(DD); D->IsCompleteDefinition = true; - } else if (!Canon->DefinitionData) { - Canon->DefinitionData = D->DefinitionData = DD; - D->IsCompleteDefinition = true; - - // Note that we have deserialized a definition. Any declarations - // deserialized before this one will be be given the DefinitionData - // pointer at the end. - Reader.PendingDefinitions.insert(D); - } else { + } else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) { // We have already deserialized a definition of this record. This // definition is no longer really a definition. Note that the pre-existing // definition is the *real* definition. Reader.MergedDeclContexts.insert( - std::make_pair(D, Canon->DefinitionData->Definition)); - D->DefinitionData = D->getCanonicalDecl()->DefinitionData; + std::make_pair(D, CanonDD->Definition)); + D->DefinitionData = Canon->DefinitionData; D->IsCompleteDefinition = false; MergeDefinitionData(D, *DD); + } else { + Canon->DefinitionData.setNotUpdated(DD); + D->DefinitionData = Canon->DefinitionData; + D->IsCompleteDefinition = true; + + // Note that we have deserialized a definition. Any declarations + // deserialized before this one will be be given the DefinitionData + // pointer at the end. + Reader.PendingDefinitions.insert(D); } } @@ -1741,16 +1743,16 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( // This declaration might be a definition. Merge with any existing // definition. - if (D->DefinitionData) { - if (!CanonSpec->DefinitionData) { - CanonSpec->DefinitionData = D->DefinitionData; - } else { - MergeDefinitionData(CanonSpec, *D->DefinitionData); + if (auto *DDD = D->DefinitionData.getNotUpdated()) { + if (auto *CanonDD = CanonSpec->DefinitionData.getNotUpdated()) { + MergeDefinitionData(CanonSpec, *DDD); Reader.PendingDefinitions.erase(D); Reader.MergedDeclContexts.insert( - std::make_pair(D, CanonSpec->DefinitionData->Definition)); + std::make_pair(D, CanonDD->Definition)); D->IsCompleteDefinition = false; D->DefinitionData = CanonSpec->DefinitionData; + } else { + CanonSpec->DefinitionData = D->DefinitionData; } } } @@ -2459,7 +2461,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { template<typename DeclT> void ASTDeclReader::attachPreviousDeclImpl(Redeclarable<DeclT> *D, Decl *Previous) { - D->RedeclLink.setNext(cast<DeclT>(Previous)); + D->RedeclLink.setPrevious(cast<DeclT>(Previous)); } void ASTDeclReader::attachPreviousDeclImpl(...) { llvm_unreachable("attachPreviousDecl on non-redeclarable declaration"); @@ -2489,7 +2491,7 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *Previous) { template<typename DeclT> void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) { - D->RedeclLink = Redeclarable<DeclT>::LatestDeclLink(cast<DeclT>(Latest)); + D->RedeclLink.setLatest(cast<DeclT>(Latest)); } void ASTDeclReader::attachLatestDeclImpl(...) { llvm_unreachable("attachLatestDecl on non-redeclarable declaration"); @@ -2500,8 +2502,8 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) { switch (D->getKind()) { #define ABSTRACT_DECL(TYPE) -#define DECL(TYPE, BASE) \ - case Decl::TYPE: \ +#define DECL(TYPE, BASE) \ + case Decl::TYPE: \ attachLatestDeclImpl(cast<TYPE##Decl>(D), Latest); \ break; #include "clang/AST/DeclNodes.inc" diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index d9bef82130a..d88d1ca99f1 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5301,8 +5301,7 @@ void ASTWriter::AddCXXCtorInitializers( } void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) { - assert(D->DefinitionData); - struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; + auto &Data = D->data(); Record.push_back(Data.IsLambda); Record.push_back(Data.UserDeclaredConstructor); Record.push_back(Data.UserDeclaredSpecialMembers); @@ -5361,7 +5360,7 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec // Add lambda-specific data. if (Data.IsLambda) { - CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData(); + auto &Lambda = D->getLambdaData(); Record.push_back(Lambda.Dependent); Record.push_back(Lambda.IsGenericLambda); Record.push_back(Lambda.CaptureDefault); diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map index d6effcf0ad0..061abbd24d5 100644 --- a/clang/test/Modules/Inputs/module.map +++ b/clang/test/Modules/Inputs/module.map @@ -69,6 +69,8 @@ module redeclarations_left { header "redeclarations_left.h" } module redeclarations_right { header "redeclarations_right.h" } module redecl_namespaces_left { header "redecl_namespaces_left.h" } module redecl_namespaces_right { header "redecl_namespaces_right.h" } +module redecl_add_after_load_top { header "redecl-add-after-load-top.h" } +module redecl_add_after_load { header "redecl-add-after-load.h" } module load_failure { header "load_failure.h" } module decldef { diff --git a/clang/test/Modules/Inputs/redecl-add-after-load.h b/clang/test/Modules/Inputs/redecl-add-after-load.h new file mode 100644 index 00000000000..6951a76289f --- /dev/null +++ b/clang/test/Modules/Inputs/redecl-add-after-load.h @@ -0,0 +1,23 @@ +struct A {}; +extern const int variable = 0; +extern constexpr int function() { return 0; } + +namespace N { + struct A {}; + extern const int variable = 0; + extern constexpr int function() { return 0; } +} + +@import redecl_add_after_load_top; +struct C::A {}; +const int C::variable = 0; +constexpr int C::function() { return 0; } + +struct D { + struct A; + static const int variable; + static constexpr int function(); +}; +struct D::A {}; +const int D::variable = 0; +constexpr int D::function() { return 0; } diff --git a/clang/test/Modules/decldef.mm b/clang/test/Modules/decldef.mm index 35694935dfb..2e2bd8a75e2 100644 --- a/clang/test/Modules/decldef.mm +++ b/clang/test/Modules/decldef.mm @@ -1,14 +1,18 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY -// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify +// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_1 -DUSE_2 -DUSE_3 -DUSE_4 +// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_2 -DUSE_3 -DUSE_4 +// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_3 -DUSE_4 +// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_4 -// expected-note@Inputs/def.h:5 {{previous}} +// expected-note@Inputs/def.h:5 0-1{{previous}} +// expected-note@Inputs/def.h:16 0-1{{previous}} +// expected-note@Inputs/def-include.h:11 0-1{{previous}} @class Def; Def *def; -class Def2; // expected-note {{forward decl}} +class Def2; // expected-note 0-1{{forward decl}} Def2 *def2; -namespace Def3NS { class Def3; } // expected-note {{forward decl}} +namespace Def3NS { class Def3; } // expected-note 0-1{{forward decl}} Def3NS::Def3 *def3; @interface Unrelated @@ -16,9 +20,10 @@ Def3NS::Def3 *def3; @end @import decldef; -#ifdef USE_EARLY +#ifdef USE_1 A *a1; // expected-error{{declaration of 'A' must be imported from module 'decldef.Def'}} B *b1; +#define USED #endif @import decldef.Decl; @@ -26,14 +31,23 @@ A *a2; B *b; void testA(A *a) { +#ifdef USE_2 a->ivar = 17; -#ifndef USE_EARLY + #ifndef USED // expected-error@-2{{definition of 'A' must be imported from module 'decldef.Def' before it is required}} + #define USED + #endif #endif } void testB() { - B b; // Note: redundant error silenced +#ifdef USE_3 + B b; + #ifndef USED + // expected-error@-2{{definition of 'B' must be imported from module 'decldef.Def' before it is required}} + #define USED + #endif +#endif } void testDef() { @@ -41,9 +55,12 @@ void testDef() { } void testDef2() { - // FIXME: These should both work, since we've (implicitly) imported - // decldef.Def here, but they don't, because nothing has triggered the lazy - // loading of the definitions of these classes. - def2->func(); // expected-error {{incomplete}} - def3->func(); // expected-error {{incomplete}} +#ifdef USE_4 + def2->func(); + def3->func(); + #ifndef USED + // expected-error@-3 {{definition of 'Def2' must be imported}} + #define USED + #endif +#endif } diff --git a/clang/test/Modules/redecl-add-after-load.cpp b/clang/test/Modules/redecl-add-after-load.cpp new file mode 100644 index 00000000000..4ee63b5d815 --- /dev/null +++ b/clang/test/Modules/redecl-add-after-load.cpp @@ -0,0 +1,48 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 + +typedef struct A B; +extern const int variable; +extern constexpr int function(); +constexpr int test(bool b) { return b ? variable : function(); } + +namespace N { + typedef struct A B; + extern const int variable; + extern constexpr int function(); +} +typedef N::B NB; +constexpr int N_test(bool b) { return b ? N::variable : N::function(); } + +@import redecl_add_after_load_top; +typedef C::A CB; +constexpr int C_test(bool b) { return b ? C::variable : C::function(); } + +struct D { + struct A; // expected-note {{forward}} + static const int variable; + static constexpr int function(); // expected-note {{here}} +}; +typedef D::A DB; +constexpr int D_test(bool b) { return b ? D::variable : D::function(); } // expected-note {{subexpression}} expected-note {{undefined}} + +@import redecl_add_after_load; + +B tu_struct_test; +constexpr int tu_variable_test = test(true); +constexpr int tu_function_test = test(false); + +NB ns_struct_test; +constexpr int ns_variable_test = N_test(true); +constexpr int ns_function_test = N_test(false); + +CB struct_struct_test; +constexpr int struct_variable_test = C_test(true); +constexpr int struct_function_test = C_test(false); + +// FIXME: We should accept this, but we're currently too lazy when merging class +// definitions to determine that the definitions in redecl_add_after_load are +// definitions of these entities. +DB merged_struct_struct_test; // expected-error {{incomplete}} +constexpr int merged_struct_variable_test = D_test(true); // expected-error {{constant}} expected-note {{in call to}} +constexpr int merged_struct_function_test = D_test(false); // expected-error {{constant}} expected-note {{in call to}} |