summaryrefslogtreecommitdiffstats
path: root/clang/include
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/AST/ASTContext.h18
-rw-r--r--clang/include/clang/AST/Decl.h77
-rw-r--r--clang/include/clang/AST/DeclCXX.h63
-rw-r--r--clang/include/clang/AST/DeclObjC.h12
-rw-r--r--clang/include/clang/AST/DeclTemplate.h61
-rw-r--r--clang/include/clang/AST/ExternalASTSource.h113
-rw-r--r--clang/include/clang/AST/Redeclarable.h83
-rw-r--r--clang/include/clang/Sema/MultiplexExternalSemaSource.h4
-rw-r--r--clang/include/clang/Serialization/ASTReader.h9
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,
OpenPOWER on IntegriCloud