Skip to content

Commit e4828aa

Browse files
authored
[clang-doc] Wrap per thread arenas in an accessor for BUILD_SHARED (#201388)
It seems like for BUILD_SHARED builds of the toolchain on Windows, specifically aarch64-windows-gnu hosts, the use of the `thread_local` variables in Representation.cpp causes an issue at link time due to non-explicit export. Instead, just wrap them in an accessor function, which should solve the issue in a cross platform way. Fixes #200915
1 parent cac3e79 commit e4828aa

7 files changed

Lines changed: 92 additions & 76 deletions

File tree

clang-tools-extra/clang-doc/BitcodeReader.cpp

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -569,13 +569,13 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, CommentInfo *I) {
569569
[&]() -> llvm::Error {
570570
if (!LocalChildren.empty())
571571
I->Children =
572-
allocateArray<CommentInfo>(LocalChildren, TransientArena);
572+
allocateArray<CommentInfo>(LocalChildren, getTransientArena());
573573
if (!AttrKeys.empty())
574-
I->AttrKeys = allocateArray(AttrKeys, TransientArena);
574+
I->AttrKeys = allocateArray(AttrKeys, getTransientArena());
575575
if (!AttrValues.empty())
576-
I->AttrValues = allocateArray(AttrValues, TransientArena);
576+
I->AttrValues = allocateArray(AttrValues, getTransientArena());
577577
if (!Args.empty())
578-
I->Args = allocateArray(Args, TransientArena);
578+
I->Args = allocateArray(Args, getTransientArena());
579579

580580
return llvm::Error::success();
581581
},
@@ -608,9 +608,9 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, FunctionInfo *I) {
608608
return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
609609
},
610610
[&]() -> llvm::Error {
611-
I->Params = allocateArray(LocalParams, TransientArena);
611+
I->Params = allocateArray(LocalParams, getTransientArena());
612612
if (!LocalNamespaces.empty())
613-
I->Namespace = allocateArray(LocalNamespaces, TransientArena);
613+
I->Namespace = allocateArray(LocalNamespaces, getTransientArena());
614614
return llvm::Error::success();
615615
});
616616
}
@@ -632,9 +632,9 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, EnumInfo *I) {
632632
return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
633633
},
634634
[&]() -> llvm::Error {
635-
I->Members = allocateArray(LocalMembers, TransientArena);
635+
I->Members = allocateArray(LocalMembers, getTransientArena());
636636
if (!LocalNamespaces.empty())
637-
I->Namespace = allocateArray(LocalNamespaces, TransientArena);
637+
I->Namespace = allocateArray(LocalNamespaces, getTransientArena());
638638
return llvm::Error::success();
639639
});
640640
}
@@ -679,14 +679,14 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, BaseRecordInfo *I) {
679679
},
680680
[&]() -> llvm::Error {
681681
if (!LocalMembers.empty())
682-
I->Members = allocateArray(LocalMembers, TransientArena);
682+
I->Members = allocateArray(LocalMembers, getTransientArena());
683683
if (!LocalParents.empty())
684-
I->Parents = allocateArray(LocalParents, TransientArena);
684+
I->Parents = allocateArray(LocalParents, getTransientArena());
685685
if (!LocalVirtualParents.empty())
686686
I->VirtualParents =
687-
allocateArray(LocalVirtualParents, TransientArena);
688-
I->Bases = allocateArray(LocalBases, TransientArena);
689-
I->Friends = allocateArray(LocalFriends, TransientArena);
687+
allocateArray(LocalVirtualParents, getTransientArena());
688+
I->Bases = allocateArray(LocalBases, getTransientArena());
689+
I->Friends = allocateArray(LocalFriends, getTransientArena());
690690
return llvm::Error::success();
691691
});
692692
}
@@ -730,16 +730,16 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, RecordInfo *I) {
730730
},
731731
[&]() -> llvm::Error {
732732
if (!LocalMembers.empty())
733-
I->Members = allocateArray(LocalMembers, TransientArena);
733+
I->Members = allocateArray(LocalMembers, getTransientArena());
734734
if (!LocalParents.empty())
735-
I->Parents = allocateArray(LocalParents, TransientArena);
735+
I->Parents = allocateArray(LocalParents, getTransientArena());
736736
if (!LocalVirtualParents.empty())
737737
I->VirtualParents =
738-
allocateArray(LocalVirtualParents, TransientArena);
738+
allocateArray(LocalVirtualParents, getTransientArena());
739739
if (!LocalNamespaces.empty())
740-
I->Namespace = allocateArray(LocalNamespaces, TransientArena);
741-
I->Bases = allocateArray(LocalBases, TransientArena);
742-
I->Friends = allocateArray(LocalFriends, TransientArena);
740+
I->Namespace = allocateArray(LocalNamespaces, getTransientArena());
741+
I->Bases = allocateArray(LocalBases, getTransientArena());
742+
I->Friends = allocateArray(LocalFriends, getTransientArena());
743743
return llvm::Error::success();
744744
});
745745
}
@@ -769,8 +769,8 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, TemplateInfo *I) {
769769
return false;
770770
},
771771
[&]() -> llvm::Error {
772-
I->Params = allocateArray(LocalParams, TransientArena);
773-
I->Constraints = allocateArray(LocalConstraints, TransientArena);
772+
I->Params = allocateArray(LocalParams, getTransientArena());
773+
I->Constraints = allocateArray(LocalConstraints, getTransientArena());
774774
return llvm::Error::success();
775775
},
776776
[&](unsigned BlockOrCode) -> llvm::Error {
@@ -796,7 +796,7 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID,
796796
return false;
797797
},
798798
[&]() -> llvm::Error {
799-
I->Params = allocateArray(LocalParams, TransientArena);
799+
I->Params = allocateArray(LocalParams, getTransientArena());
800800
return llvm::Error::success();
801801
},
802802
[&](unsigned BlockOrCode) -> llvm::Error {
@@ -1221,7 +1221,7 @@ llvm::Error ClangDocBitcodeReader::readBlockWithNamespace(unsigned ID, T I) {
12211221
},
12221222
[&]() -> llvm::Error {
12231223
if (!LocalNamespaces.empty())
1224-
I->Namespace = allocateArray(LocalNamespaces, TransientArena);
1224+
I->Namespace = allocateArray(LocalNamespaces, getTransientArena());
12251225
return llvm::Error::success();
12261226
});
12271227
}
@@ -1254,7 +1254,8 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, FriendInfo *I) {
12541254
},
12551255
[&]() -> llvm::Error {
12561256
if (!LocalParams.empty())
1257-
I->Params = allocateArray<FieldTypeInfo>(LocalParams, TransientArena);
1257+
I->Params =
1258+
allocateArray<FieldTypeInfo>(LocalParams, getTransientArena());
12581259
return llvm::Error::success();
12591260
},
12601261
[&](unsigned BlockOrCode) -> llvm::Error {

clang-tools-extra/clang-doc/Mapper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
4444
llvm::timeTraceProfilerInitialize(200, "clang-doc");
4545
TraverseDecl(Context.getTranslationUnitDecl());
4646

47-
TransientArena.Reset();
47+
getTransientArena().Reset();
4848

4949
if (CDCtx.FTimeTrace)
5050
llvm::timeTraceProfilerFinishThread();

clang-tools-extra/clang-doc/Representation.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,15 @@ namespace clang {
2929
namespace doc {
3030

3131
// Thread local arenas usable in each thread pool
32-
thread_local llvm::BumpPtrAllocator TransientArena;
33-
thread_local llvm::BumpPtrAllocator PersistentArena;
32+
llvm::BumpPtrAllocator &getTransientArena() {
33+
thread_local llvm::BumpPtrAllocator TransientArena;
34+
return TransientArena;
35+
}
36+
37+
llvm::BumpPtrAllocator &getPersistentArena() {
38+
thread_local llvm::BumpPtrAllocator PersistentArena;
39+
return PersistentArena;
40+
}
3441

3542
ConcurrentStringPool &getGlobalStringPool() {
3643
static ConcurrentStringPool GlobalPool;
@@ -168,7 +175,7 @@ void mergeUnkeyed<CommentInfo>(DocList<CommentInfo> &Target,
168175
if (llvm::none_of(Target,
169176
[Ptr](const auto &E) { return *E.Ptr == *Ptr; })) {
170177
Target.push_back(
171-
*allocateListNodePersistent<CommentInfo>(*Ptr, PersistentArena));
178+
*allocateListNodePersistent<CommentInfo>(*Ptr, getPersistentArena()));
172179
}
173180
}
174181
}
@@ -461,7 +468,7 @@ void Info::mergeBase(Info &&Other) {
461468
if (Path == "")
462469
Path = Other.Path;
463470
if (Namespace.empty() && !Other.Namespace.empty())
464-
Namespace = allocateArray(Other.Namespace, PersistentArena);
471+
Namespace = allocateArray(Other.Namespace, getPersistentArena());
465472
// Unconditionally extend the description, since each decl may have a comment.
466473
mergeUnkeyed(Description, std::move(Other.Description));
467474
if (ParentUSR == EmptySID)
@@ -549,22 +556,22 @@ void RecordInfo::merge(RecordInfo &&Other) {
549556
TagType = Other.TagType;
550557
IsTypeDef = IsTypeDef || Other.IsTypeDef;
551558
if (Members.empty() && !Other.Members.empty())
552-
Members = deepCopyArray(Other.Members, PersistentArena);
559+
Members = deepCopyArray(Other.Members, getPersistentArena());
553560
if (Bases.empty() && !Other.Bases.empty())
554-
Bases = deepCopyArray(Other.Bases, PersistentArena);
561+
Bases = deepCopyArray(Other.Bases, getPersistentArena());
555562
if (Parents.empty() && !Other.Parents.empty())
556-
Parents = allocateArray(Other.Parents, PersistentArena);
563+
Parents = allocateArray(Other.Parents, getPersistentArena());
557564
if (VirtualParents.empty() && !Other.VirtualParents.empty())
558-
VirtualParents = allocateArray(Other.VirtualParents, PersistentArena);
565+
VirtualParents = allocateArray(Other.VirtualParents, getPersistentArena());
559566
if (Friends.empty() && !Other.Friends.empty())
560-
Friends = deepCopyArray(Other.Friends, PersistentArena);
567+
Friends = deepCopyArray(Other.Friends, getPersistentArena());
561568
// Reduce children if necessary.
562569
reduceChildren(Children.Records, std::move(Other.Children.Records));
563570
reduceChildren(Children.Functions, std::move(Other.Children.Functions));
564571
reduceChildren(Children.Enums, std::move(Other.Children.Enums));
565572
reduceChildren(Children.Typedefs, std::move(Other.Children.Typedefs));
566573
if (!Template && Other.Template)
567-
Template = TemplateInfo(*Other.Template, PersistentArena);
574+
Template = TemplateInfo(*Other.Template, getPersistentArena());
568575
SymbolInfo::merge(std::move(Other));
569576
}
570577

@@ -586,7 +593,7 @@ void EnumInfo::merge(EnumInfo &&Other) {
586593
if (!BaseType && Other.BaseType)
587594
BaseType = std::move(Other.BaseType);
588595
if (Members.empty() && !Other.Members.empty())
589-
Members = deepCopyArray(Other.Members, PersistentArena);
596+
Members = deepCopyArray(Other.Members, getPersistentArena());
590597
SymbolInfo::merge(std::move(Other));
591598
}
592599

@@ -601,9 +608,9 @@ void FunctionInfo::merge(FunctionInfo &&Other) {
601608
if (Parent.USR == EmptySID && Parent.Name == "")
602609
Parent = std::move(Other.Parent);
603610
if (Params.empty() && !Other.Params.empty())
604-
Params = allocateArray(Other.Params, PersistentArena);
611+
Params = allocateArray(Other.Params, getPersistentArena());
605612
if (!Template && Other.Template)
606-
Template = TemplateInfo(*Other.Template, PersistentArena);
613+
Template = TemplateInfo(*Other.Template, getPersistentArena());
607614
SymbolInfo::merge(std::move(Other));
608615
}
609616

@@ -614,7 +621,7 @@ void TypedefInfo::merge(TypedefInfo &&Other) {
614621
if (Underlying.Type.Name == "")
615622
Underlying = Other.Underlying;
616623
if (!Template && Other.Template)
617-
Template = TemplateInfo(*Other.Template, PersistentArena);
624+
Template = TemplateInfo(*Other.Template, getPersistentArena());
618625
SymbolInfo::merge(std::move(Other));
619626
}
620627

@@ -626,9 +633,10 @@ void ConceptInfo::merge(ConceptInfo &&Other) {
626633
ConstraintExpression = std::move(Other.ConstraintExpression);
627634
if (Template.Constraints.empty() && !Other.Template.Constraints.empty())
628635
Template.Constraints =
629-
allocateArray(Other.Template.Constraints, PersistentArena);
636+
allocateArray(Other.Template.Constraints, getPersistentArena());
630637
if (Template.Params.empty() && !Other.Template.Params.empty())
631-
Template.Params = allocateArray(Other.Template.Params, PersistentArena);
638+
Template.Params =
639+
allocateArray(Other.Template.Params, getPersistentArena());
632640
SymbolInfo::merge(std::move(Other));
633641
}
634642

clang-tools-extra/clang-doc/Representation.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ class ConcurrentStringPool {
5151

5252
ConcurrentStringPool &getGlobalStringPool();
5353

54-
extern thread_local llvm::BumpPtrAllocator TransientArena;
55-
extern thread_local llvm::BumpPtrAllocator PersistentArena;
54+
llvm::BumpPtrAllocator &getTransientArena();
55+
llvm::BumpPtrAllocator &getPersistentArena();
5656

5757
inline StringRef internString(const Twine &T) {
5858
if (T.isTriviallyEmpty())
@@ -107,12 +107,13 @@ llvm::ArrayRef<T> deepCopyArray(llvm::ArrayRef<T> V,
107107
// A helper function to create an owned pointer, abstracting away the memory
108108
// allocation mechanism.
109109
template <typename T, typename... Args> T *allocateTransient(Args &&...args) {
110-
return new (TransientArena.Allocate<T>()) T(std::forward<Args>(args)...);
110+
return new (getTransientArena().Allocate<T>()) T(std::forward<Args>(args)...);
111111
}
112112

113113
// A helper function to create memory allocated in the TransientArena.
114114
template <typename T, typename... Args> T *allocatePersistent(Args &&...args) {
115-
return new (PersistentArena.Allocate<T>()) T(std::forward<Args>(args)...);
115+
return new (getPersistentArena().Allocate<T>())
116+
T(std::forward<Args>(args)...);
116117
}
117118

118119
// An overload to explicitly allocate on an arena, returning a bare pointer.
@@ -156,7 +157,7 @@ InfoNode<T> *allocateListNode(llvm::BumpPtrAllocator &Alloc, Args &&...args) {
156157

157158
template <typename T, typename... Args>
158159
InfoNode<T> *allocateListNodeTransient(Args &&...args) {
159-
return allocateListNode<T>(TransientArena, std::forward<Args>(args)...);
160+
return allocateListNode<T>(getTransientArena(), std::forward<Args>(args)...);
160161
}
161162

162163
template <typename T>
@@ -165,16 +166,16 @@ InfoNode<T> *allocateListNode(llvm::BumpPtrAllocator &Alloc, T *Item) {
165166
}
166167

167168
template <typename T> InfoNode<T> *allocateListNodeTransient(T *Item) {
168-
return allocateListNode<T>(TransientArena, Item);
169+
return allocateListNode<T>(getTransientArena(), Item);
169170
}
170171

171172
template <typename T, typename... Args>
172173
InfoNode<T> *allocateListNodePersistent(Args &&...args) {
173-
return allocateListNode<T>(PersistentArena, std::forward<Args>(args)...);
174+
return allocateListNode<T>(getPersistentArena(), std::forward<Args>(args)...);
174175
}
175176

176177
template <typename T> InfoNode<T> *allocateListNodePersistent(T *Item) {
177-
return allocateListNode<T>(PersistentArena, Item);
178+
return allocateListNode<T>(getPersistentArena(), Item);
178179
}
179180

180181
// An abstraction for lists that are dynamically managed (inserted/removed).

0 commit comments

Comments
 (0)