[clang] [llvm] [clang][AST] Un-template `LazyGenerationalUpdatePtr` (PR #219187)
Jonas Hahnfeld via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 07:53:43 PDT 2026
https://github.com/hahnjo updated https://github.com/llvm/llvm-project/pull/219187
>From 6116ec90c60f4664d3d266db3ffe8ebd61c1e533 Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <jonas.hahnfeld at cern.ch>
Date: Mon, 24 Aug 2026 14:02:12 +0200
Subject: [PATCH 1/4] [clang][AST] Un-template LazyGenerationalUpdatePtr
It is only used in Redeclarable with a single set of template
arguments. Rename to LazyGenerationalDeclPtr and simplify the code.
---
clang/include/clang/AST/ASTContext.h | 13 -----
clang/include/clang/AST/ExternalASTSource.h | 54 ++++++++++-----------
clang/include/clang/AST/Redeclarable.h | 4 +-
clang/lib/AST/ASTContext.cpp | 15 +++---
llvm/unittests/ADT/PointerUnionTest.cpp | 2 +-
5 files changed, 34 insertions(+), 54 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index dd67c5d0410f8..4e43b650285a4 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -4063,19 +4063,6 @@ inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) {
C.Deallocate(Ptr);
}
-/// 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;
-}
template <> struct llvm::DenseMapInfo<llvm::FoldingSetNodeID> {
static unsigned getHashValue(const FoldingSetNodeID &Val) {
return Val.ComputeHash();
diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h
index be88309969715..769ac0caf5605 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -439,46 +439,45 @@ struct LazyOffsetPtr {
}
};
-/// 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 lazy Decl value where the value might change in later generations of the
+/// external AST source.
+struct LazyGenerationalDeclPtr {
/// A cache of the value of this pointer, in the most recent generation in
/// which we queried it.
struct LazyData {
ExternalASTSource *ExternalSource;
uint32_t LastGeneration = 0;
- T LastValue;
+ Decl *LastValue;
- LazyData(ExternalASTSource *Source, T Value)
+ LazyData(ExternalASTSource *Source, Decl *Value)
: ExternalSource(Source), LastValue(Value) {}
};
- // Our value is represented as simply T if there is no external AST source.
- using ValueType = llvm::PointerUnion<T, LazyData*>;
+ // Our value is represented as simply a Decl pointer if there is no external
+ // AST source.
+ using ValueType = llvm::PointerUnion<Decl *, LazyData *>;
ValueType Value;
- LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
+ LazyGenerationalDeclPtr(ValueType V) : Value(V) {}
- // Defined in ASTContext.h
- static ValueType makeValue(const ASTContext &Ctx, T Value);
+ // Defined in ASTContext.cpp
+ static ValueType makeValue(const ASTContext &Ctx, Decl *Value);
public:
- explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
+ explicit LazyGenerationalDeclPtr(const ASTContext &Ctx, Decl *Value = nullptr)
: 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())
+ LazyGenerationalDeclPtr(NotUpdatedTag, Decl *Value = nullptr)
: Value(Value) {}
/// Forcibly set this pointer (which must be lazy) as needing updates.
void markIncomplete() { cast<LazyData *>(Value)->LastGeneration = 0; }
/// Set the value of this pointer, in the current generation.
- void set(T NewValue) {
+ void set(Decl *NewValue) {
if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) {
LazyVal->LastValue = NewValue;
return;
@@ -487,30 +486,30 @@ struct LazyGenerationalUpdatePtr {
}
/// Set the value of this pointer, for this and all future generations.
- void setNotUpdated(T NewValue) { Value = NewValue; }
+ void setNotUpdated(Decl *NewValue) { Value = NewValue; }
/// Get the value of this pointer, updating its owner if necessary.
- T get(Owner O) {
+ Decl *get(const Decl *O) {
if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) {
if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
- (LazyVal->ExternalSource->*Update)(O);
+ LazyVal->ExternalSource->CompleteRedeclChain(O);
}
return LazyVal->LastValue;
}
- return cast<T>(Value);
+ return cast<Decl *>(Value);
}
/// Get the most recently computed value of this pointer without updating it.
- T getNotUpdated() const {
+ Decl *getNotUpdated() const {
if (auto *LazyVal = Value.template dyn_cast<LazyData *>())
return LazyVal->LastValue;
- return cast<T>(Value);
+ return cast<Decl *>(Value);
}
void *getOpaqueValue() { return Value.getOpaqueValue(); }
- static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
- return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
+ static LazyGenerationalDeclPtr getFromOpaqueValue(void *Ptr) {
+ return LazyGenerationalDeclPtr(ValueType::getFromOpaqueValue(Ptr));
}
};
@@ -518,13 +517,10 @@ struct LazyGenerationalUpdatePtr {
namespace llvm {
-/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
+/// Specialize PointerLikeTypeTraits to allow LazyGenerationalDeclPtr to be
/// placed into a PointerUnion.
-template<typename Owner, typename T,
- void (clang::ExternalASTSource::*Update)(Owner)>
-struct PointerLikeTypeTraits<
- clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
- using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>;
+template <> struct PointerLikeTypeTraits<clang::LazyGenerationalDeclPtr> {
+ using Ptr = clang::LazyGenerationalDeclPtr;
static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h
index 28fff4f43823c..35911ee2f7d16 100644
--- a/clang/include/clang/AST/Redeclarable.h
+++ b/clang/include/clang/AST/Redeclarable.h
@@ -86,9 +86,7 @@ class Redeclarable {
class DeclLink {
/// A pointer to a known latest declaration, either statically known or
/// generationally updated as decls are added by an external source.
- using KnownLatest =
- LazyGenerationalUpdatePtr<const Decl *, Decl *,
- &ExternalASTSource::CompleteRedeclChain>;
+ using KnownLatest = LazyGenerationalDeclPtr;
/// We store a pointer to the ASTContext in the UninitializedLatest
/// pointer, but to avoid circular type dependencies when we steal the low
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b502c4436de49..73173b3f41bf5 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -15171,14 +15171,13 @@ LangAS ASTContext::getLangASForBuiltinAddressSpace(unsigned AS) const {
return getLangASFromTargetAS(AS);
}
-// 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);
+typename clang::LazyGenerationalDeclPtr::ValueType
+clang::LazyGenerationalDeclPtr::makeValue(const clang::ASTContext &Ctx,
+ Decl *Value) {
+ if (auto *Source = Ctx.getExternalSource())
+ return new (Ctx) LazyData(Source, Value);
+ return Value;
+}
unsigned char ASTContext::getFixedPointScale(QualType Ty) const {
assert(Ty->isFixedPointType());
diff --git a/llvm/unittests/ADT/PointerUnionTest.cpp b/llvm/unittests/ADT/PointerUnionTest.cpp
index 258e4050984e8..2c85c24526320 100644
--- a/llvm/unittests/ADT/PointerUnionTest.cpp
+++ b/llvm/unittests/ADT/PointerUnionTest.cpp
@@ -310,7 +310,7 @@ struct alignas(4) LowAlign {
};
// Wrapper around a PointerUnion that over-claims NumLowBitsAvailable,
-// mimicking LazyGenerationalUpdatePtr's PLTT on 32-bit.
+// mimicking LazyGenerationalDeclPtr's PLTT on 32-bit.
struct OverClaimWrapper {
PointerUnion<HighAlign *, LowAlign *> Value;
>From 795a8d5f804447f8b0ebe44c57b6fc246b6c2c5b Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <jonas.hahnfeld at cern.ch>
Date: Mon, 24 Aug 2026 14:16:37 +0200
Subject: [PATCH 2/4] [clang][AST] Remove unused LazyGenerationalDeclPtr
methods
---
clang/include/clang/AST/ExternalASTSource.h | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h
index 769ac0caf5605..1afe57aafe38e 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -467,12 +467,6 @@ struct LazyGenerationalDeclPtr {
explicit LazyGenerationalDeclPtr(const ASTContext &Ctx, Decl *Value = nullptr)
: Value(makeValue(Ctx, Value)) {}
- /// Create a pointer that is not potentially updated by later generations of
- /// the external AST source.
- enum NotUpdatedTag { NotUpdated };
- LazyGenerationalDeclPtr(NotUpdatedTag, Decl *Value = nullptr)
- : Value(Value) {}
-
/// Forcibly set this pointer (which must be lazy) as needing updates.
void markIncomplete() { cast<LazyData *>(Value)->LastGeneration = 0; }
@@ -485,9 +479,6 @@ struct LazyGenerationalDeclPtr {
Value = NewValue;
}
- /// Set the value of this pointer, for this and all future generations.
- void setNotUpdated(Decl *NewValue) { Value = NewValue; }
-
/// Get the value of this pointer, updating its owner if necessary.
Decl *get(const Decl *O) {
if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) {
>From 1e70c54d05a64287c72619e15c5f3895c228606d Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <jonas.hahnfeld at cern.ch>
Date: Thu, 27 Aug 2026 16:45:59 +0200
Subject: [PATCH 3/4] Remove redundant typename
---
clang/lib/AST/ASTContext.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 73173b3f41bf5..1d99196923cb0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -15171,7 +15171,7 @@ LangAS ASTContext::getLangASForBuiltinAddressSpace(unsigned AS) const {
return getLangASFromTargetAS(AS);
}
-typename clang::LazyGenerationalDeclPtr::ValueType
+clang::LazyGenerationalDeclPtr::ValueType
clang::LazyGenerationalDeclPtr::makeValue(const clang::ASTContext &Ctx,
Decl *Value) {
if (auto *Source = Ctx.getExternalSource())
>From b4c6f17f947affb55fba8bf37479b3c13f2782c4 Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <jonas.hahnfeld at cern.ch>
Date: Thu, 27 Aug 2026 16:48:14 +0200
Subject: [PATCH 4/4] Move LazyGenerationalDeclPtr::makeValue to
ExternalASTSource.cpp
---
clang/include/clang/AST/ExternalASTSource.h | 1 -
clang/lib/AST/ASTContext.cpp | 8 --------
clang/lib/AST/ExternalASTSource.cpp | 7 +++++++
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h
index 1afe57aafe38e..b277ce5812cdc 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -460,7 +460,6 @@ struct LazyGenerationalDeclPtr {
LazyGenerationalDeclPtr(ValueType V) : Value(V) {}
- // Defined in ASTContext.cpp
static ValueType makeValue(const ASTContext &Ctx, Decl *Value);
public:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 1d99196923cb0..4123c2d204920 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -15171,14 +15171,6 @@ LangAS ASTContext::getLangASForBuiltinAddressSpace(unsigned AS) const {
return getLangASFromTargetAS(AS);
}
-clang::LazyGenerationalDeclPtr::ValueType
-clang::LazyGenerationalDeclPtr::makeValue(const clang::ASTContext &Ctx,
- Decl *Value) {
- if (auto *Source = Ctx.getExternalSource())
- return new (Ctx) LazyData(Source, Value);
- return Value;
-}
-
unsigned char ASTContext::getFixedPointScale(QualType Ty) const {
assert(Ty->isFixedPointType());
diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp
index e8c1004089713..118f6fd67d3a4 100644
--- a/clang/lib/AST/ExternalASTSource.cpp
+++ b/clang/lib/AST/ExternalASTSource.cpp
@@ -134,3 +134,10 @@ uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
return OldGeneration;
}
+
+LazyGenerationalDeclPtr::ValueType
+LazyGenerationalDeclPtr::makeValue(const ASTContext &Ctx, Decl *Value) {
+ if (auto *Source = Ctx.getExternalSource())
+ return new (Ctx) LazyData(Source, Value);
+ return Value;
+}
More information about the llvm-commits
mailing list