summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-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
-rw-r--r--clang/lib/AST/ASTContext.cpp9
-rw-r--r--clang/lib/AST/Decl.cpp76
-rw-r--r--clang/lib/AST/DeclCXX.cpp85
-rw-r--r--clang/lib/AST/DeclObjC.cpp34
-rw-r--r--clang/lib/AST/DeclTemplate.cpp59
-rw-r--r--clang/lib/AST/ExternalASTSource.cpp20
-rw-r--r--clang/lib/CodeGen/CGBlocks.cpp21
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp3
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp8
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp15
-rw-r--r--clang/lib/Sema/MultiplexExternalSemaSource.cpp5
-rw-r--r--clang/lib/Serialization/ASTReader.cpp42
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp52
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp5
-rw-r--r--clang/test/Modules/Inputs/module.map2
-rw-r--r--clang/test/Modules/Inputs/redecl-add-after-load.h23
-rw-r--r--clang/test/Modules/decldef.mm43
-rw-r--r--clang/test/Modules/redecl-add-after-load.cpp48
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}}
OpenPOWER on IntegriCloud