[clang] [Clang] Cache AST context lookup for declarations (NFC) (PR #223047)
Mehdi Amini via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 22 03:50:32 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/223047
>From e1abcb2a2c5655902274faa80abf6e5f77390b6a Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
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 | 19 +++++++--
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 | 49 ++++++++++++-----------
clang/lib/AST/DeclOpenMP.cpp | 26 ++++++------
clang/lib/AST/DeclTemplate.cpp | 11 +++---
clang/unittests/AST/DeclTest.cpp | 18 +++++++++
13 files changed, 170 insertions(+), 112 deletions(-)
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index c64dc8c02d40e..a5174d547d5ba 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 9d233be282dbb..86dc9325b5e5c 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -2101,13 +2101,18 @@ 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);
+ DeclContext(DeclContext *Parent, Decl::Kind K)
+ : DeclContext(Parent->getParentASTContext(), K) {}
public:
~DeclContext();
@@ -2152,9 +2157,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 +2828,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 afe46fae1bceb..ac572e481c9e0 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 6b9aac57e6a50..92f227d890e6c 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 06414cef6baf3..db46d116f1c55 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 0d110bc3e6306..fbae88825f50a 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 8c1418625bf33..a2ad37bf3629e 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 70f61fa57a682..71d28579cfd6c 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 f0da56542ae7e..6a2bfa997ce2a 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 1adf6c9e048a9..210703d841613 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -66,7 +66,7 @@ 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, DK) {
setAtStartLoc(atStartLoc);
}
@@ -823,8 +823,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, ObjCMethod), MethodDeclType(T),
+ ReturnTInfo(ReturnTInfo), DeclEndLoc(endLoc) {
// Initialized the bits stored in DeclContext.
ObjCMethodDeclBits.Family =
@@ -861,8 +861,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 +1574,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 +1972,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 +2151,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 +2169,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 +2210,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 +2310,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 ef08a1c30042f..fc4568fe8a25d 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 64cb49b0aa53e..d92e7450dfb32 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 195b8ab4c4e66..bee8cdb3d1ac6 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(
More information about the cfe-commits
mailing list