https://github.com/joker-eph updated 
https://github.com/llvm/llvm-project/pull/223047

>From 0edeaebf6ac4e095599c6e10adacdc933b4de068 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <[email protected]>
Date: Wed, 16 Sep 2026 15:10:51 -0700
Subject: [PATCH] [Clang] Store AST context in declaration contexts

Store the owning ASTContext directly in each DeclContext and route declarations
through that direct path. This removes the nullable cache and translation-unit
walk from Decl::getASTContext().

Assisted-by: Codex
---
 clang/include/clang/AST/Decl.h         | 24 +++++------
 clang/include/clang/AST/DeclBase.h     | 17 ++++++--
 clang/include/clang/AST/DeclCXX.h      |  5 ++-
 clang/include/clang/AST/DeclObjC.h     | 20 +++++-----
 clang/include/clang/AST/DeclOpenMP.h   | 35 +++++++++++++---
 clang/include/clang/AST/DeclTemplate.h |  2 +-
 clang/lib/AST/Decl.cpp                 | 55 ++++++++++++++------------
 clang/lib/AST/DeclBase.cpp             |  6 +--
 clang/lib/AST/DeclCXX.cpp              | 12 +++---
 clang/lib/AST/DeclObjC.cpp             | 50 ++++++++++++-----------
 clang/lib/AST/DeclOpenMP.cpp           | 26 ++++++------
 clang/lib/AST/DeclTemplate.cpp         | 11 +++---
 clang/unittests/AST/DeclTest.cpp       | 18 +++++++++
 13 files changed, 169 insertions(+), 112 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index c64dc8c02d40e0..a5174d547d5bac 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -246,9 +246,9 @@ class PragmaDetectMismatchDecl final
 /// The declaration at #3 finds it is a redeclaration of \c N::f through
 /// lookup in the extern "C" context.
 class ExternCContextDecl : public Decl, public DeclContext {
-  explicit ExternCContextDecl(TranslationUnitDecl *TU)
-    : Decl(ExternCContext, TU, SourceLocation()),
-      DeclContext(ExternCContext) {}
+  ExternCContextDecl(ASTContext &C, TranslationUnitDecl *TU)
+      : Decl(ExternCContext, TU, SourceLocation()),
+        DeclContext(C, ExternCContext) {}
 
   virtual void anchor();
 
@@ -4776,8 +4776,8 @@ class TopLevelStmtDecl : public Decl, public DeclContext {
   /// Position among all top-level statements of the session, in parse order.
   unsigned Ordinal = 0;
 
-  TopLevelStmtDecl(DeclContext *DC, SourceLocation L, Stmt *S)
-      : Decl(TopLevelStmt, DC, L), DeclContext(TopLevelStmt), Statement(S) {}
+  TopLevelStmtDecl(ASTContext &C, DeclContext *DC, SourceLocation L, Stmt *S)
+      : Decl(TopLevelStmt, DC, L), DeclContext(C, TopLevelStmt), Statement(S) 
{}
 
   virtual void anchor();
 
@@ -4874,7 +4874,7 @@ class BlockDecl : public Decl, public DeclContext {
   Decl *ManglingContextDecl = nullptr;
 
 protected:
-  BlockDecl(DeclContext *DC, SourceLocation CaretLoc);
+  BlockDecl(ASTContext &C, DeclContext *DC, SourceLocation CaretLoc);
 
 public:
   static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -5022,7 +5022,7 @@ class OutlinedFunctionDecl final
   /// The body of the outlined function.
   llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
 
-  explicit OutlinedFunctionDecl(DeclContext *DC, unsigned NumParams);
+  OutlinedFunctionDecl(ASTContext &C, DeclContext *DC, unsigned NumParams);
 
   ImplicitParamDecl *const *getParams() const { return getTrailingObjects(); }
 
@@ -5095,7 +5095,7 @@ class CapturedDecl final
   /// The body of the outlined function.
   llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
 
-  explicit CapturedDecl(DeclContext *DC, unsigned NumParams);
+  CapturedDecl(ASTContext &C, DeclContext *DC, unsigned NumParams);
 
   ImplicitParamDecl *const *getParams() const { return getTrailingObjects(); }
 
@@ -5276,8 +5276,8 @@ class ExportDecl final : public Decl, public DeclContext {
   /// The source location for the right brace (if valid).
   SourceLocation RBraceLoc;
 
-  ExportDecl(DeclContext *DC, SourceLocation ExportLoc)
-      : Decl(Export, DC, ExportLoc), DeclContext(Export),
+  ExportDecl(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc)
+      : Decl(Export, DC, ExportLoc), DeclContext(C, Export),
         RBraceLoc(SourceLocation()) {}
 
 public:
@@ -5350,8 +5350,8 @@ class HLSLBufferDecl final : public NamedDecl, public 
DeclContext {
   // allocator in HLSLBufferDecl::CreateDefaultCBuffer.
   ArrayRef<Decl *> DefaultBufferDecls;
 
-  HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc,
-                 IdentifierInfo *ID, SourceLocation IDLoc,
+  HLSLBufferDecl(ASTContext &C, DeclContext *DC, bool CBuffer,
+                 SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation 
IDLoc,
                  SourceLocation LBrace);
 
   void setDefaultBufferDecls(ArrayRef<Decl *> Decls);
diff --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index 9d233be282dbb8..436d880d8022a6 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -2101,13 +2101,16 @@ class DeclContext {
   /// another pointer.
   mutable Decl *LastDecl = nullptr;
 
+  /// The owning AST context.
+  ASTContext &Ctx;
+
   /// Build up a chain of declarations.
   ///
   /// \returns the first/last pair of declarations.
   static std::pair<Decl *, Decl *>
   BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
 
-  DeclContext(Decl::Kind K);
+  DeclContext(ASTContext &Ctx, Decl::Kind K);
 
 public:
   ~DeclContext();
@@ -2152,9 +2155,7 @@ class DeclContext {
     return const_cast<DeclContext*>(this)->getLookupParent();
   }
 
-  ASTContext &getParentASTContext() const {
-    return cast<Decl>(this)->getASTContext();
-  }
+  ASTContext &getParentASTContext() const { return Ctx; }
 
   bool isClosure() const { return getDeclKind() == Decl::Block; }
 
@@ -2825,6 +2826,14 @@ inline bool Decl::isTemplateParameter() const {
          getKind() == TemplateTemplateParm;
 }
 
+inline ASTContext &Decl::getASTContext() const {
+  const DeclContext *DC = getDeclContext();
+  // The translation unit has no parent context and owns the AST context.
+  if (!DC)
+    DC = castToDeclContext(this);
+  return DC->getParentASTContext();
+}
+
 // Specialization selected when ToTy is not a known subclass of DeclContext.
 template <class ToTy,
           bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index afe46fae1bceb1..ac572e481c9e0f 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -2117,7 +2117,8 @@ class CXXDeductionGuideDecl : public FunctionDecl {
 /// template argument list imposed by the compound requirement.
 class RequiresExprBodyDecl : public Decl, public DeclContext {
   RequiresExprBodyDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
-      : Decl(RequiresExprBody, DC, StartLoc), DeclContext(RequiresExprBody) {}
+      : Decl(RequiresExprBody, DC, StartLoc), DeclContext(C, RequiresExprBody) 
{
+  }
 
 public:
   friend class ASTDeclReader;
@@ -3052,7 +3053,7 @@ class LinkageSpecDecl : public Decl, public DeclContext {
   /// The source location for the right brace (if valid).
   SourceLocation RBraceLoc;
 
-  LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
+  LinkageSpecDecl(ASTContext &C, DeclContext *DC, SourceLocation ExternLoc,
                   SourceLocation LangLoc, LinkageSpecLanguageIDs lang,
                   bool HasBraces);
 
diff --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 6b9aac57e6a500..92f227d890e6cf 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -2623,20 +2623,18 @@ class ObjCImplementationDecl : public ObjCImplDecl {
   LLVM_PREFERRED_TYPE(bool)
   bool HasDestructors : 1;
 
-  ObjCImplementationDecl(DeclContext *DC,
-                         ObjCInterfaceDecl *classInterface,
-                         ObjCInterfaceDecl *superDecl,
-                         SourceLocation nameLoc, SourceLocation atStartLoc,
+  ObjCImplementationDecl(DeclContext *DC, ObjCInterfaceDecl *classInterface,
+                         ObjCInterfaceDecl *superDecl, SourceLocation nameLoc,
+                         SourceLocation atStartLoc,
                          SourceLocation superLoc = SourceLocation(),
-                         SourceLocation IvarLBraceLoc=SourceLocation(),
-                         SourceLocation IvarRBraceLoc=SourceLocation())
+                         SourceLocation IvarLBraceLoc = SourceLocation(),
+                         SourceLocation IvarRBraceLoc = SourceLocation())
       : ObjCImplDecl(ObjCImplementation, DC, classInterface,
-                     classInterface ? classInterface->getIdentifier()
-                                    : nullptr,
+                     classInterface ? classInterface->getIdentifier() : 
nullptr,
                      nameLoc, atStartLoc),
-         SuperClass(superDecl), SuperLoc(superLoc),
-         IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc),
-         HasNonZeroConstructors(false), HasDestructors(false) {}
+        SuperClass(superDecl), SuperLoc(superLoc), 
IvarLBraceLoc(IvarLBraceLoc),
+        IvarRBraceLoc(IvarRBraceLoc), HasNonZeroConstructors(false),
+        HasDestructors(false) {}
 
   void anchor() override;
 
diff --git a/clang/include/clang/AST/DeclOpenMP.h 
b/clang/include/clang/AST/DeclOpenMP.h
index 06414cef6baf35..db46d116f1c558 100644
--- a/clang/include/clang/AST/DeclOpenMP.h
+++ b/clang/include/clang/AST/DeclOpenMP.h
@@ -69,6 +69,30 @@ template <typename U> class OMPDeclarativeDirective : public 
U {
     return Inst;
   }
 
+  template <typename T, typename... Params>
+  static T *createDirectiveWithContext(const ASTContext &C, DeclContext *DC,
+                                       ArrayRef<OMPClause *> Clauses,
+                                       unsigned NumChildren, Params &&...P) {
+    auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
+        T(const_cast<ASTContext &>(C), DC, std::forward<Params>(P)...);
+    Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
+                                     /*AssociatedStmt=*/nullptr, NumChildren);
+    Inst->Data->setClauses(Clauses);
+    return Inst;
+  }
+
+  template <typename T, typename... Params>
+  static T *
+  createEmptyDirectiveWithContext(const ASTContext &C, GlobalDeclID ID,
+                                  unsigned NumClauses, unsigned NumChildren,
+                                  Params &&...P) {
+    auto *Inst = new (C, ID, size(NumClauses, NumChildren))
+        T(const_cast<ASTContext &>(C), nullptr, std::forward<Params>(P)...);
+    Inst->Data = OMPChildren::CreateEmpty(
+        Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
+    return Inst;
+  }
+
   static size_t size(unsigned NumClauses, unsigned NumChildren) {
     return OMPChildren::size(NumClauses, /*HasAssociatedStmt=*/false,
                              NumChildren);
@@ -261,8 +285,8 @@ class OMPDeclareReductionDecl final : public ValueDecl, 
public DeclContext {
 
   void anchor() override;
 
-  OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
-                          DeclarationName Name, QualType Ty,
+  OMPDeclareReductionDecl(ASTContext &C, Kind DK, DeclContext *DC,
+                          SourceLocation L, DeclarationName Name, QualType Ty,
                           OMPDeclareReductionDecl *PrevDeclInScope);
 
   void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
@@ -361,11 +385,12 @@ class OMPDeclareMapperDecl final : public 
OMPDeclarativeDirective<ValueDecl>,
 
   void anchor() override;
 
-  OMPDeclareMapperDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                       QualType Ty, DeclarationName VarName,
+  OMPDeclareMapperDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                       DeclarationName Name, QualType Ty,
+                       DeclarationName VarName,
                        OMPDeclareMapperDecl *PrevDeclInScope)
       : OMPDeclarativeDirective<ValueDecl>(OMPDeclareMapper, DC, L, Name, Ty),
-        DeclContext(OMPDeclareMapper), VarName(VarName),
+        DeclContext(C, OMPDeclareMapper), VarName(VarName),
         PrevDeclInScope(PrevDeclInScope) {}
 
   void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {
diff --git a/clang/include/clang/AST/DeclTemplate.h 
b/clang/include/clang/AST/DeclTemplate.h
index 0d110bc3e63063..fbae88825f50a0 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -3433,7 +3433,7 @@ class CXXExpansionStmtDecl : public Decl, public 
DeclContext {
   NonTypeTemplateParmDecl *IndexNTTP = nullptr;
   CXXExpansionStmtInstantiation *Instantiations = nullptr;
 
-  CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
+  CXXExpansionStmtDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
                        NonTypeTemplateParmDecl *NTTP);
 
 public:
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 8c1418625bf339..a2ad37bf3629e8 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -103,7 +103,7 @@ bool Decl::isOutOfLine() const {
 
 TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx)
     : Decl(TranslationUnit, nullptr, SourceLocation()),
-      DeclContext(TranslationUnit), redeclarable_base(ctx), Ctx(ctx) {}
+      DeclContext(ctx, TranslationUnit), redeclarable_base(ctx), Ctx(ctx) {}
 
 
//===----------------------------------------------------------------------===//
 // NamedDecl Implementation
@@ -3073,7 +3073,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, 
DeclContext *DC,
                            const AssociatedConstraint &TrailingRequiresClause)
     : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
                      StartLoc),
-      DeclContext(DK), redeclarable_base(C), Body(), ODRHash(0),
+      DeclContext(C, DK), redeclarable_base(C), Body(), ODRHash(0),
       EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {
   assert(T.isNull() || T->isFunctionType());
   FunctionDeclBits.SClass = S;
@@ -4939,7 +4939,8 @@ const FieldDecl *FieldDecl::findCountedByField() const {
 TagDecl::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),
+    : TypeDecl(DK, DC, L, Id, StartL),
+      DeclContext(const_cast<ASTContext &>(C), DK), redeclarable_base(C),
       TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) {
   assert((DK != Enum || TK == TagTypeKind::Enum) &&
          "EnumDecl not matched with TagTypeKind::Enum");
@@ -5500,8 +5501,8 @@ unsigned RecordDecl::getODRHash() {
 // BlockDecl Implementation
 
//===----------------------------------------------------------------------===//
 
-BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
-    : Decl(Block, DC, CaretLoc), DeclContext(Block) {
+BlockDecl::BlockDecl(ASTContext &C, DeclContext *DC, SourceLocation CaretLoc)
+    : Decl(Block, DC, CaretLoc), DeclContext(C, Block) {
   setIsVariadic(false);
   setCapturesCXXThis(false);
   setBlockMissingReturnType(true);
@@ -5614,7 +5615,7 @@ void ExternCContextDecl::anchor() {}
 
 ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C,
                                                TranslationUnitDecl *DC) {
-  return new (C, DC) ExternCContextDecl(DC);
+  return new (C, DC) ExternCContextDecl(const_cast<ASTContext &>(C), DC);
 }
 
 void LabelDecl::anchor() {}
@@ -5715,30 +5716,31 @@ bool FunctionDecl::isReferenceableKernel() const {
 }
 
 BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) 
{
-  return new (C, DC) BlockDecl(DC, L);
+  return new (C, DC) BlockDecl(C, DC, L);
 }
 
 BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) BlockDecl(nullptr, SourceLocation());
+  return new (C, ID) BlockDecl(C, nullptr, SourceLocation());
 }
 
-OutlinedFunctionDecl::OutlinedFunctionDecl(DeclContext *DC, unsigned NumParams)
+OutlinedFunctionDecl::OutlinedFunctionDecl(ASTContext &C, DeclContext *DC,
+                                           unsigned NumParams)
     : Decl(OutlinedFunction, DC, SourceLocation()),
-      DeclContext(OutlinedFunction), NumParams(NumParams),
+      DeclContext(C, OutlinedFunction), NumParams(NumParams),
       BodyAndNothrow(nullptr, false) {}
 
 OutlinedFunctionDecl *OutlinedFunctionDecl::Create(ASTContext &C,
                                                    DeclContext *DC,
                                                    unsigned NumParams) {
   return new (C, DC, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams))
-      OutlinedFunctionDecl(DC, NumParams);
+      OutlinedFunctionDecl(C, DC, NumParams);
 }
 
 OutlinedFunctionDecl *
 OutlinedFunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
                                          unsigned NumParams) {
   return new (C, ID, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams))
-      OutlinedFunctionDecl(nullptr, NumParams);
+      OutlinedFunctionDecl(C, nullptr, NumParams);
 }
 
 Stmt *OutlinedFunctionDecl::getBody() const {
@@ -5751,20 +5753,20 @@ void OutlinedFunctionDecl::setNothrow(bool Nothrow) {
   BodyAndNothrow.setInt(Nothrow);
 }
 
-CapturedDecl::CapturedDecl(DeclContext *DC, unsigned NumParams)
-    : Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
+CapturedDecl::CapturedDecl(ASTContext &C, DeclContext *DC, unsigned NumParams)
+    : Decl(Captured, DC, SourceLocation()), DeclContext(C, Captured),
       NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) {}
 
 CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC,
                                    unsigned NumParams) {
   return new (C, DC, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams))
-      CapturedDecl(DC, NumParams);
+      CapturedDecl(C, DC, NumParams);
 }
 
 CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
                                                unsigned NumParams) {
   return new (C, ID, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams))
-      CapturedDecl(nullptr, NumParams);
+      CapturedDecl(C, nullptr, NumParams);
 }
 
 Stmt *CapturedDecl::getBody() const { return BodyAndNothrow.getPointer(); }
@@ -5938,7 +5940,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, 
Stmt *Statement) {
   SourceLocation Loc = Statement ? Statement->getBeginLoc() : SourceLocation();
   DeclContext *DC = C.getTranslationUnitDecl();
 
-  auto *D = new (C, DC) TopLevelStmtDecl(DC, Loc, Statement);
+  auto *D = new (C, DC) TopLevelStmtDecl(C, DC, Loc, Statement);
   D->Ordinal = C.NumTopLevelStmtDecls++;
   return D;
 }
@@ -5946,7 +5948,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, 
Stmt *Statement) {
 TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C,
                                                        GlobalDeclID ID) {
   return new (C, ID)
-      TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr);
+      TopLevelStmtDecl(C, /*DC=*/nullptr, SourceLocation(), /*S=*/nullptr);
 }
 
 SourceRange TopLevelStmtDecl::getSourceRange() const {
@@ -5969,11 +5971,11 @@ EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, 
GlobalDeclID ID) {
   return new (C, ID) EmptyDecl(nullptr, SourceLocation());
 }
 
-HLSLBufferDecl::HLSLBufferDecl(DeclContext *DC, bool CBuffer,
+HLSLBufferDecl::HLSLBufferDecl(ASTContext &C, DeclContext *DC, bool CBuffer,
                                SourceLocation KwLoc, IdentifierInfo *ID,
                                SourceLocation IDLoc, SourceLocation LBrace)
     : NamedDecl(Decl::Kind::HLSLBuffer, DC, IDLoc, DeclarationName(ID)),
-      DeclContext(Decl::Kind::HLSLBuffer), LBraceLoc(LBrace), KwLoc(KwLoc),
+      DeclContext(C, Decl::Kind::HLSLBuffer), LBraceLoc(LBrace), KwLoc(KwLoc),
       IsCBuffer(CBuffer), HasValidPackoffset(false), LayoutStruct(nullptr) {}
 
 HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C,
@@ -5994,7 +5996,7 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C,
   // FIXME: support nested buffers if required for back-compat.
   DeclContext *DC = LexicalParent;
   HLSLBufferDecl *Result =
-      new (C, DC) HLSLBufferDecl(DC, CBuffer, KwLoc, ID, IDLoc, LBrace);
+      new (C, DC) HLSLBufferDecl(C, DC, CBuffer, KwLoc, ID, IDLoc, LBrace);
   return Result;
 }
 
@@ -6004,7 +6006,7 @@ HLSLBufferDecl::CreateDefaultCBuffer(ASTContext &C, 
DeclContext *LexicalParent,
   DeclContext *DC = LexicalParent;
   IdentifierInfo *II = &C.Idents.get("$Globals", tok::TokenKind::identifier);
   HLSLBufferDecl *Result = new (C, DC) HLSLBufferDecl(
-      DC, true, SourceLocation(), II, SourceLocation(), SourceLocation());
+      C, DC, true, SourceLocation(), II, SourceLocation(), SourceLocation());
   Result->setImplicit(true);
   Result->setDefaultBufferDecls(DefaultCBufferDecls);
   return Result;
@@ -6012,8 +6014,9 @@ HLSLBufferDecl::CreateDefaultCBuffer(ASTContext &C, 
DeclContext *LexicalParent,
 
 HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C,
                                                    GlobalDeclID ID) {
-  return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr,
-                                    SourceLocation(), SourceLocation());
+  return new (C, ID)
+      HLSLBufferDecl(C, nullptr, false, SourceLocation(), nullptr,
+                     SourceLocation(), SourceLocation());
 }
 
 void HLSLBufferDecl::addLayoutStruct(CXXRecordDecl *LS) {
@@ -6163,11 +6166,11 @@ void ExportDecl::anchor() {}
 
 ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC,
                                SourceLocation ExportLoc) {
-  return new (C, DC) ExportDecl(DC, ExportLoc);
+  return new (C, DC) ExportDecl(C, DC, ExportLoc);
 }
 
 ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) ExportDecl(nullptr, SourceLocation());
+  return new (C, ID) ExportDecl(C, nullptr, SourceLocation());
 }
 
 bool clang::IsArmStreamingFunction(const FunctionDecl *FD,
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 70f61fa57a682a..71d28579cfd6c2 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -547,10 +547,6 @@ TranslationUnitDecl *Decl::getTranslationUnitDecl() {
   return cast<TranslationUnitDecl>(DC);
 }
 
-ASTContext &Decl::getASTContext() const {
-  return getTranslationUnitDecl()->getASTContext();
-}
-
 /// Helper to get the language options from the ASTContext.
 /// Defined out of line to avoid depending on ASTContext.h.
 const LangOptions &Decl::getLangOpts() const {
@@ -1308,7 +1304,7 @@ Decl *DeclContext::getNonClosureAncestor() {
 // DeclContext Implementation
 
//===----------------------------------------------------------------------===//
 
-DeclContext::DeclContext(Decl::Kind K) {
+DeclContext::DeclContext(ASTContext &Ctx, Decl::Kind K) : Ctx(Ctx) {
   DeclContextBits.DeclKind = K;
   setHasExternalLexicalStorage(false);
   setHasExternalVisibleStorage(false);
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index f0da56542ae7ea..6a2bfa997ce2a9 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -3299,10 +3299,11 @@ bool 
CXXConversionDecl::isLambdaToBlockPointerConversion() const {
          getConversionType()->isBlockPointerType();
 }
 
-LinkageSpecDecl::LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
+LinkageSpecDecl::LinkageSpecDecl(ASTContext &C, DeclContext *DC,
+                                 SourceLocation ExternLoc,
                                  SourceLocation LangLoc,
                                  LinkageSpecLanguageIDs lang, bool HasBraces)
-    : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
+    : Decl(LinkageSpec, DC, LangLoc), DeclContext(C, LinkageSpec),
       ExternLoc(ExternLoc), RBraceLoc(SourceLocation()) {
   setLanguage(lang);
   LinkageSpecDeclBits.HasBraces = HasBraces;
@@ -3315,13 +3316,14 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, 
DeclContext *DC,
                                          SourceLocation LangLoc,
                                          LinkageSpecLanguageIDs Lang,
                                          bool HasBraces) {
-  return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
+  return new (C, DC)
+      LinkageSpecDecl(C, DC, ExternLoc, LangLoc, Lang, HasBraces);
 }
 
 LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C,
                                                      GlobalDeclID ID) {
   return new (C, ID)
-      LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(),
+      LinkageSpecDecl(C, nullptr, SourceLocation(), SourceLocation(),
                       LinkageSpecLanguageIDs::C, false);
 }
 
@@ -3364,7 +3366,7 @@ NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext 
*DC, bool Inline,
                              SourceLocation StartLoc, SourceLocation IdLoc,
                              IdentifierInfo *Id, NamespaceDecl *PrevDecl,
                              bool Nested)
-    : NamespaceBaseDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+    : NamespaceBaseDecl(Namespace, DC, IdLoc, Id), DeclContext(C, Namespace),
       redeclarable_base(C), LocStart(StartLoc) {
   setInline(Inline);
   setNested(Nested);
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 1adf6c9e048a97..ddddbf5fccfd1f 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -66,7 +66,8 @@ ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,
                                      const IdentifierInfo *Id,
                                      SourceLocation nameLoc,
                                      SourceLocation atStartLoc)
-    : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
+    : NamedDecl(DK, DC, nameLoc, Id),
+      DeclContext(DC->getParentASTContext(), DK) {
   setAtStartLoc(atStartLoc);
 }
 
@@ -823,8 +824,8 @@ ObjCMethodDecl::ObjCMethodDecl(
     bool isSynthesizedAccessorStub, bool isImplicitlyDeclared, bool isDefined,
     ObjCImplementationControl impControl, bool HasRelatedResultType)
     : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
-      DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),
-      DeclEndLoc(endLoc) {
+      DeclContext(contextDecl->getParentASTContext(), ObjCMethod),
+      MethodDeclType(T), ReturnTInfo(ReturnTInfo), DeclEndLoc(endLoc) {
 
   // Initialized the bits stored in DeclContext.
   ObjCMethodDeclBits.Family =
@@ -861,8 +862,9 @@ ObjCMethodDecl *ObjCMethodDecl::Create(
 
 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C,
                                                    GlobalDeclID ID) {
-  return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
-                                    Selector(), QualType(), nullptr, nullptr);
+  return new (C, ID)
+      ObjCMethodDecl(SourceLocation(), SourceLocation(), Selector(), 
QualType(),
+                     nullptr, C.getTranslationUnitDecl());
 }
 
 void ObjCMethodDecl::getNameForDiagnostic(raw_ostream &OS,
@@ -1573,8 +1575,8 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(
 ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
                                                          GlobalDeclID ID) {
   auto *Result = new (C, ID)
-      ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr,
-                        SourceLocation(), nullptr, false);
+      ObjCInterfaceDecl(C, C.getTranslationUnitDecl(), SourceLocation(),
+                        nullptr, nullptr, SourceLocation(), nullptr, false);
   Result->Data.setInt(!C.getLangOpts().Modules);
   return Result;
 }
@@ -1971,8 +1973,8 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, 
DeclContext *DC,
 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
                                                        GlobalDeclID ID) {
   ObjCProtocolDecl *Result =
-      new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
-                                   SourceLocation(), nullptr);
+      new (C, ID) ObjCProtocolDecl(C, C.getTranslationUnitDecl(), nullptr,
+                                   SourceLocation(), SourceLocation(), 
nullptr);
   Result->Data.setInt(!C.getLangOpts().Modules);
   return Result;
 }
@@ -2150,10 +2152,9 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create(
     const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
     ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc,
     SourceLocation IvarRBraceLoc) {
-  auto *CatDecl =
-      new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, 
Id,
-                                   IDecl, typeParamList, IvarLBraceLoc,
-                                   IvarRBraceLoc);
+  auto *CatDecl = new (C, DC)
+      ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id, IDecl,
+                       typeParamList, IvarLBraceLoc, IvarRBraceLoc);
   if (IDecl) {
     // Link this category into its class's category list.
     CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
@@ -2169,9 +2170,9 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create(
 
 ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
                                                        GlobalDeclID ID) {
-  return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
-                                      SourceLocation(), SourceLocation(),
-                                      nullptr, nullptr, nullptr);
+  return new (C, ID) ObjCCategoryDecl(
+      C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
+      SourceLocation(), nullptr, nullptr, nullptr);
 }
 
 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
@@ -2210,9 +2211,9 @@ ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create(
 
 ObjCCategoryImplDecl *
 ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
-                                          SourceLocation(), SourceLocation(),
-                                          SourceLocation());
+  return new (C, ID) ObjCCategoryImplDecl(C.getTranslationUnitDecl(), nullptr,
+                                          nullptr, SourceLocation(),
+                                          SourceLocation(), SourceLocation());
 }
 
 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
@@ -2310,15 +2311,16 @@ ObjCImplementationDecl::Create(ASTContext &C, 
DeclContext *DC,
                                SourceLocation IvarRBraceLoc) {
   if (ClassInterface && ClassInterface->hasDefinition())
     ClassInterface = ClassInterface->getDefinition();
-  return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
-                                            nameLoc, atStartLoc, superLoc,
-                                            IvarLBraceLoc, IvarRBraceLoc);
+  return new (C, DC)
+      ObjCImplementationDecl(DC, ClassInterface, SuperDecl, nameLoc, 
atStartLoc,
+                             superLoc, IvarLBraceLoc, IvarRBraceLoc);
 }
 
 ObjCImplementationDecl *
 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
-                                            SourceLocation(), 
SourceLocation());
+  return new (C, ID)
+      ObjCImplementationDecl(C.getTranslationUnitDecl(), nullptr, nullptr,
+                             SourceLocation(), SourceLocation());
 }
 
 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp
index ef08a1c30042f4..fc4568fe8a25db 100644
--- a/clang/lib/AST/DeclOpenMP.cpp
+++ b/clang/lib/AST/DeclOpenMP.cpp
@@ -130,9 +130,9 @@ OMPRequiresDecl 
*OMPRequiresDecl::CreateDeserialized(ASTContext &C,
 
//===----------------------------------------------------------------------===//
 
 OMPDeclareReductionDecl::OMPDeclareReductionDecl(
-    Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
-    QualType Ty, OMPDeclareReductionDecl *PrevDeclInScope)
-    : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
+    ASTContext &C, Kind DK, DeclContext *DC, SourceLocation L,
+    DeclarationName Name, QualType Ty, OMPDeclareReductionDecl 
*PrevDeclInScope)
+    : ValueDecl(DK, DC, L, Name, Ty), DeclContext(C, DK), Combiner(nullptr),
       PrevDeclInScope(PrevDeclInScope) {
   setInitializer(nullptr, OMPDeclareReductionInitKind::Call);
 }
@@ -142,15 +142,15 @@ void OMPDeclareReductionDecl::anchor() {}
 OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create(
     ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
     QualType T, OMPDeclareReductionDecl *PrevDeclInScope) {
-  return new (C, DC) OMPDeclareReductionDecl(OMPDeclareReduction, DC, L, Name,
-                                             T, PrevDeclInScope);
+  return new (C, DC) OMPDeclareReductionDecl(C, OMPDeclareReduction, DC, L,
+                                             Name, T, PrevDeclInScope);
 }
 
 OMPDeclareReductionDecl *
 OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
   return new (C, ID) OMPDeclareReductionDecl(
-      OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(),
-      QualType(), /*PrevDeclInScope=*/nullptr);
+      C, OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(),
+      DeclarationName(), QualType(), /*PrevDeclInScope=*/nullptr);
 }
 
 OMPDeclareReductionDecl *OMPDeclareReductionDecl::getPrevDeclInScope() {
@@ -173,16 +173,18 @@ OMPDeclareMapperDecl *OMPDeclareMapperDecl::Create(
     ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
     QualType T, DeclarationName VarName, ArrayRef<OMPClause *> Clauses,
     OMPDeclareMapperDecl *PrevDeclInScope) {
-  return OMPDeclarativeDirective::createDirective<OMPDeclareMapperDecl>(
-      C, DC, Clauses, 1, L, Name, T, VarName, PrevDeclInScope);
+  return OMPDeclarativeDirective::createDirectiveWithContext<
+      OMPDeclareMapperDecl>(C, DC, Clauses, 1, L, Name, T, VarName,
+                            PrevDeclInScope);
 }
 
 OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C,
                                                                GlobalDeclID ID,
                                                                unsigned N) {
-  return OMPDeclarativeDirective::createEmptyDirective<OMPDeclareMapperDecl>(
-      C, ID, N, 1, SourceLocation(), DeclarationName(), QualType(),
-      DeclarationName(), /*PrevDeclInScope=*/nullptr);
+  return OMPDeclarativeDirective::createEmptyDirectiveWithContext<
+      OMPDeclareMapperDecl>(C, ID, N, 1, SourceLocation(), DeclarationName(),
+                            QualType(), DeclarationName(),
+                            /*PrevDeclInScope=*/nullptr);
 }
 
 OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() {
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 64cb49b0aa53e4..d92e7450dfb325 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -1953,20 +1953,21 @@ SourceRange ExplicitInstantiationDecl::getSourceRange() 
const {
   return SourceRange(Begin, getEndLoc());
 }
 
-CXXExpansionStmtDecl::CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
+CXXExpansionStmtDecl::CXXExpansionStmtDecl(ASTContext &C, DeclContext *DC,
+                                           SourceLocation Loc,
                                            NonTypeTemplateParmDecl *NTTP)
-    : Decl(CXXExpansionStmt, DC, Loc), DeclContext(CXXExpansionStmt),
+    : Decl(CXXExpansionStmt, DC, Loc), DeclContext(C, CXXExpansionStmt),
       IndexNTTP(NTTP) {}
 
 CXXExpansionStmtDecl *
 CXXExpansionStmtDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation 
Loc,
                              NonTypeTemplateParmDecl *NTTP) {
-  return new (C, DC) CXXExpansionStmtDecl(DC, Loc, NTTP);
+  return new (C, DC) CXXExpansionStmtDecl(C, DC, Loc, NTTP);
 }
 CXXExpansionStmtDecl *
 CXXExpansionStmtDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID)
-      CXXExpansionStmtDecl(/*DC=*/nullptr, SourceLocation(), /*NTTP=*/nullptr);
+  return new (C, ID) CXXExpansionStmtDecl(C, /*DC=*/nullptr, SourceLocation(),
+                                          /*NTTP=*/nullptr);
 }
 
 SourceRange CXXExpansionStmtDecl::getSourceRange() const {
diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp
index 195b8ab4c4e661..bee8cdb3d1ac63 100644
--- a/clang/unittests/AST/DeclTest.cpp
+++ b/clang/unittests/AST/DeclTest.cpp
@@ -37,6 +37,24 @@ using namespace clang::ast_matchers;
 using namespace clang::tooling;
 using namespace clang;
 
+TEST(Decl, ParentASTContext) {
+  auto AST = tooling::buildASTFromCode("namespace N { struct S {}; }");
+  ASSERT_NE(nullptr, AST);
+  ASTContext &Ctx = AST->getASTContext();
+  const auto *Record = selectFirst<CXXRecordDecl>(
+      "s",
+      match(cxxRecordDecl(hasName("S"), unless(isImplicit())).bind("s"), Ctx));
+  ASSERT_NE(nullptr, Record);
+  // Check repeated queries through nested contexts and the translation unit,
+  // which has no parent.
+  const DeclContext *Contexts[] = {Record, Record->getParent(),
+                                   Ctx.getTranslationUnitDecl()};
+  for (const DeclContext *DC : Contexts) {
+    EXPECT_EQ(&Ctx, &DC->getParentASTContext());
+    EXPECT_EQ(&Ctx, &DC->getParentASTContext());
+  }
+}
+
 TEST(Decl, CleansUpAPValues) {
   MatchFinder Finder;
   std::unique_ptr<FrontendActionFactory> Factory(

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to