diff options
Diffstat (limited to 'clang/include')
-rw-r--r-- | clang/include/clang/AST/ASTContext.h | 18 | ||||
-rw-r--r-- | clang/include/clang/AST/Decl.h | 77 | ||||
-rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 63 | ||||
-rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 12 | ||||
-rw-r--r-- | clang/include/clang/AST/DeclTemplate.h | 61 | ||||
-rw-r--r-- | clang/include/clang/AST/ExternalASTSource.h | 113 | ||||
-rw-r--r-- | clang/include/clang/AST/Redeclarable.h | 83 | ||||
-rw-r--r-- | clang/include/clang/Sema/MultiplexExternalSemaSource.h | 4 | ||||
-rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 9 |
9 files changed, 315 insertions, 125 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, |