-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[llvm] annotate interfaces in llvm/Analysis for DLL export #136623
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
d192f16
to
ccf4b8d
Compare
da2bc32
to
cf1cca7
Compare
3025889
to
89db249
Compare
89db249
to
7cadbca
Compare
@llvm/pr-subscribers-mlgo @llvm/pr-subscribers-llvm-analysis Author: Andrew Rogers (andrurogerz) ChangesPurposeThis patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the BackgroundThis effort is tracked in #109483. Additional context is provided in this discourse, and documentation for The bulk of these changes were generated automatically using the Interface Definition Scanner (IDS) tool, followed formatting with The following manual adjustments were also applied after running IDS on Linux:
ValidationLocal builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations:
Patch is 602.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136623.diff 97 Files Affected:
diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h
index 16f54c394788d..d8d88639b85a1 100644
--- a/llvm/include/llvm/Analysis/AliasAnalysis.h
+++ b/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -43,6 +43,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ModRef.h"
#include <cstdint>
#include <functional>
@@ -142,10 +143,10 @@ static_assert(sizeof(AliasResult) == 4,
"AliasResult size is intended to be 4 bytes!");
/// << operator for AliasResult.
-raw_ostream &operator<<(raw_ostream &OS, AliasResult AR);
+LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, AliasResult AR);
/// Virtual base class for providers of capture analysis.
-struct CaptureAnalysis {
+struct LLVM_ABI CaptureAnalysis {
virtual ~CaptureAnalysis() = 0;
/// Check whether Object is not captured before instruction I. If OrAt is
@@ -159,7 +160,7 @@ struct CaptureAnalysis {
/// Context-free CaptureAnalysis provider, which computes and caches whether an
/// object is captured in the function at all, but does not distinguish whether
/// it was captured before or after the context instruction.
-class SimpleCaptureAnalysis final : public CaptureAnalysis {
+class LLVM_ABI SimpleCaptureAnalysis final : public CaptureAnalysis {
SmallDenseMap<const Value *, bool, 8> IsCapturedCache;
public:
@@ -170,7 +171,7 @@ class SimpleCaptureAnalysis final : public CaptureAnalysis {
/// Context-sensitive CaptureAnalysis provider, which computes and caches the
/// earliest common dominator closure of all captures. It provides a good
/// approximation to a precise "captures before" analysis.
-class EarliestEscapeAnalysis final : public CaptureAnalysis {
+class LLVM_ABI EarliestEscapeAnalysis final : public CaptureAnalysis {
DominatorTree &DT;
const LoopInfo *LI;
@@ -315,9 +316,9 @@ class AAResults {
public:
// Make these results default constructable and movable. We have to spell
// these out because MSVC won't synthesize them.
- AAResults(const TargetLibraryInfo &TLI);
- AAResults(AAResults &&Arg);
- ~AAResults();
+ LLVM_ABI AAResults(const TargetLibraryInfo &TLI);
+ LLVM_ABI AAResults(AAResults &&Arg);
+ LLVM_ABI ~AAResults();
/// Register a specific AA result.
template <typename AAResultT> void addAAResult(AAResultT &AAResult) {
@@ -338,8 +339,8 @@ class AAResults {
///
/// The aggregation is invalidated if any of the underlying analyses is
/// invalidated.
- bool invalidate(Function &F, const PreservedAnalyses &PA,
- FunctionAnalysisManager::Invalidator &Inv);
+ LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
//===--------------------------------------------------------------------===//
/// \name Alias Queries
@@ -349,7 +350,8 @@ class AAResults {
/// Returns an AliasResult indicating whether the two pointers are aliased to
/// each other. This is the interface that must be implemented by specific
/// alias analysis implementations.
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB);
+ LLVM_ABI AliasResult alias(const MemoryLocation &LocA,
+ const MemoryLocation &LocB);
/// A convenience wrapper around the primary \c alias interface.
AliasResult alias(const Value *V1, LocationSize V1Size, const Value *V2,
@@ -417,8 +419,8 @@ class AAResults {
///
/// If IgnoreLocals is true, then this method returns NoModRef for memory
/// that points to a local alloca.
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
- bool IgnoreLocals = false);
+ LLVM_ABI ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
+ bool IgnoreLocals = false);
/// A convenience wrapper around the primary \c getModRefInfoMask
/// interface.
@@ -431,13 +433,13 @@ class AAResults {
/// that these bits do not necessarily account for the overall behavior of
/// the function, but rather only provide additional per-argument
/// information.
- ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
+ LLVM_ABI ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
/// Return the behavior of the given call site.
- MemoryEffects getMemoryEffects(const CallBase *Call);
+ LLVM_ABI MemoryEffects getMemoryEffects(const CallBase *Call);
/// Return the behavior when calling the given function.
- MemoryEffects getMemoryEffects(const Function *F);
+ LLVM_ABI MemoryEffects getMemoryEffects(const Function *F);
/// Checks if the specified call is known to never read or write memory.
///
@@ -519,11 +521,12 @@ class AAResults {
/// Return information about whether a call and an instruction may refer to
/// the same memory locations.
- ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call);
+ LLVM_ABI ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call);
/// Return information about whether two instructions may refer to the same
/// memory locations.
- ModRefInfo getModRefInfo(const Instruction *I1, const Instruction *I2);
+ LLVM_ABI ModRefInfo getModRefInfo(const Instruction *I1,
+ const Instruction *I2);
/// Return information about whether a particular call site modifies
/// or reads the specified memory location \p MemLoc before instruction \p I
@@ -548,7 +551,8 @@ class AAResults {
/// Check if it is possible for execution of the specified basic block to
/// modify the location Loc.
- bool canBasicBlockModify(const BasicBlock &BB, const MemoryLocation &Loc);
+ LLVM_ABI bool canBasicBlockModify(const BasicBlock &BB,
+ const MemoryLocation &Loc);
/// A convenience wrapper synthesizing a memory location.
bool canBasicBlockModify(const BasicBlock &BB, const Value *P,
@@ -561,9 +565,10 @@ class AAResults {
///
/// The instructions to consider are all of the instructions in the range of
/// [I1,I2] INCLUSIVE. I1 and I2 must be in the same basic block.
- bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
- const MemoryLocation &Loc,
- const ModRefInfo Mode);
+ LLVM_ABI bool canInstructionRangeModRef(const Instruction &I1,
+ const Instruction &I2,
+ const MemoryLocation &Loc,
+ const ModRefInfo Mode);
/// A convenience wrapper synthesizing a memory location.
bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2,
@@ -574,42 +579,54 @@ class AAResults {
// CtxI can be nullptr, in which case the query is whether or not the aliasing
// relationship holds through the entire function.
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
- AAQueryInfo &AAQI, const Instruction *CtxI = nullptr);
-
- ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI,
- bool IgnoreLocals = false);
- ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call2,
- AAQueryInfo &AAQIP);
- ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const LoadInst *L, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const StoreInst *S, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX,
- const MemoryLocation &Loc, AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const CatchPadInst *I, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const CatchReturnInst *I, const MemoryLocation &Loc,
- AAQueryInfo &AAQI);
- ModRefInfo getModRefInfo(const Instruction *I,
- const std::optional<MemoryLocation> &OptLoc,
- AAQueryInfo &AAQIP);
- ModRefInfo getModRefInfo(const Instruction *I1, const Instruction *I2,
- AAQueryInfo &AAQI);
- ModRefInfo callCapturesBefore(const Instruction *I,
- const MemoryLocation &MemLoc, DominatorTree *DT,
- AAQueryInfo &AAQIP);
- MemoryEffects getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI);
+ LLVM_ABI AliasResult alias(const MemoryLocation &LocA,
+ const MemoryLocation &LocB, AAQueryInfo &AAQI,
+ const Instruction *CtxI = nullptr);
+
+ LLVM_ABI ModRefInfo getModRefInfoMask(const MemoryLocation &Loc,
+ AAQueryInfo &AAQI,
+ bool IgnoreLocals = false);
+ LLVM_ABI ModRefInfo getModRefInfo(const Instruction *I, const CallBase *Call2,
+ AAQueryInfo &AAQIP);
+ LLVM_ABI ModRefInfo getModRefInfo(const CallBase *Call,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const CallBase *Call1,
+ const CallBase *Call2, AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const VAArgInst *V,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const LoadInst *L,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const StoreInst *S,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const FenceInst *S,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const AtomicRMWInst *RMW,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const CatchPadInst *I,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const CatchReturnInst *I,
+ const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo getModRefInfo(const Instruction *I,
+ const std::optional<MemoryLocation> &OptLoc,
+ AAQueryInfo &AAQIP);
+ LLVM_ABI ModRefInfo getModRefInfo(const Instruction *I1,
+ const Instruction *I2, AAQueryInfo &AAQI);
+ LLVM_ABI ModRefInfo callCapturesBefore(const Instruction *I,
+ const MemoryLocation &MemLoc,
+ DominatorTree *DT, AAQueryInfo &AAQIP);
+ LLVM_ABI MemoryEffects getMemoryEffects(const CallBase *Call,
+ AAQueryInfo &AAQI);
private:
class Concept;
@@ -708,7 +725,7 @@ using AliasAnalysis = AAResults;
/// All of these methods model methods by the same name in the \c
/// AAResults class. Only differences and specifics to how the
/// implementations are called are documented here.
-class AAResults::Concept {
+class LLVM_ABI AAResults::Concept {
public:
virtual ~Concept() = 0;
@@ -869,7 +886,7 @@ class AAResultBase {
};
/// Return true if this pointer is returned by a noalias function.
-bool isNoAliasCall(const Value *V);
+LLVM_ABI bool isNoAliasCall(const Value *V);
/// Return true if this pointer refers to a distinct and identifiable object.
/// This returns true for:
@@ -878,33 +895,33 @@ bool isNoAliasCall(const Value *V);
/// ByVal and NoAlias Arguments
/// NoAlias returns (e.g. calls to malloc)
///
-bool isIdentifiedObject(const Value *V);
+LLVM_ABI bool isIdentifiedObject(const Value *V);
/// Return true if V is umabigously identified at the function-level.
/// Different IdentifiedFunctionLocals can't alias.
/// Further, an IdentifiedFunctionLocal can not alias with any function
/// arguments other than itself, which is not necessarily true for
/// IdentifiedObjects.
-bool isIdentifiedFunctionLocal(const Value *V);
+LLVM_ABI bool isIdentifiedFunctionLocal(const Value *V);
/// Return true if we know V to the base address of the corresponding memory
/// object. This implies that any address less than V must be out of bounds
/// for the underlying object. Note that just being isIdentifiedObject() is
/// not enough - For example, a negative offset from a noalias argument or call
/// can be inbounds w.r.t the actual underlying object.
-bool isBaseOfObject(const Value *V);
+LLVM_ABI bool isBaseOfObject(const Value *V);
/// Returns true if the pointer is one which would have been considered an
/// escape by isNonEscapingLocalObject.
-bool isEscapeSource(const Value *V);
+LLVM_ABI bool isEscapeSource(const Value *V);
/// Return true if Object memory is not visible after an unwind, in the sense
/// that program semantics cannot depend on Object containing any particular
/// value on unwind. If the RequiresNoCaptureBeforeUnwind out parameter is set
/// to true, then the memory is only not visible if the object has not been
/// captured prior to the unwind. Otherwise it is not visible even if captured.
-bool isNotVisibleOnUnwind(const Value *Object,
- bool &RequiresNoCaptureBeforeUnwind);
+LLVM_ABI bool isNotVisibleOnUnwind(const Value *Object,
+ bool &RequiresNoCaptureBeforeUnwind);
/// Return true if the Object is writable, in the sense that any location based
/// on this pointer that can be loaded can also be stored to without trapping.
@@ -917,7 +934,8 @@ bool isNotVisibleOnUnwind(const Value *Object,
/// using the dereferenceable(N) attribute. It does not necessarily hold for
/// parts that are only known to be dereferenceable due to the presence of
/// loads.
-bool isWritableObject(const Value *Object, bool &ExplicitlyDereferenceableOnly);
+LLVM_ABI bool isWritableObject(const Value *Object,
+ bool &ExplicitlyDereferenceableOnly);
/// A manager for alias analyses.
///
@@ -950,12 +968,12 @@ class AAManager : public AnalysisInfoMixin<AAManager> {
ResultGetters.push_back(&getModuleAAResultImpl<AnalysisT>);
}
- Result run(Function &F, FunctionAnalysisManager &AM);
+ LLVM_ABI Result run(Function &F, FunctionAnalysisManager &AM);
private:
friend AnalysisInfoMixin<AAManager>;
- static AnalysisKey Key;
+ LLVM_ABI static AnalysisKey Key;
SmallVector<void (*)(Function &F, FunctionAnalysisManager &AM,
AAResults &AAResults),
@@ -984,7 +1002,7 @@ class AAManager : public AnalysisInfoMixin<AAManager> {
/// A wrapper pass to provide the legacy pass manager access to a suitably
/// prepared AAResults object.
-class AAResultsWrapperPass : public FunctionPass {
+class LLVM_ABI AAResultsWrapperPass : public FunctionPass {
std::unique_ptr<AAResults> AAR;
public:
@@ -1007,11 +1025,11 @@ struct ExternalAAWrapperPass : ImmutablePass {
CallbackT CB;
- static char ID;
+ LLVM_ABI static char ID;
- ExternalAAWrapperPass();
+ LLVM_ABI ExternalAAWrapperPass();
- explicit ExternalAAWrapperPass(CallbackT CB, bool RunEarly = false);
+ LLVM_ABI explicit ExternalAAWrapperPass(CallbackT CB, bool RunEarly = false);
/// Flag indicating whether this external AA should run before Basic AA.
///
@@ -1042,7 +1060,7 @@ struct ExternalAAWrapperPass : ImmutablePass {
/// object, and will receive a reference to the function wrapper pass, the
/// function, and the AAResults object to populate. This should be used when
/// setting up a custom pass pipeline to inject a hook into the AA results.
-ImmutablePass *createExternalAAWrapperPass(
+LLVM_ABI ImmutablePass *createExternalAAWrapperPass(
std::function<void(Pass &, Function &, AAResults &)> Callback);
} // end namespace llvm
diff --git a/llvm/include/llvm/Analysis/AliasAnalysisEvaluator.h b/llvm/include/llvm/Analysis/AliasAnalysisEvaluator.h
index e4f152c232aa6..d8b02bd42e7d8 100644
--- a/llvm/include/llvm/Analysis/AliasAnalysisEvaluator.h
+++ b/llvm/include/llvm/Analysis/AliasAnalysisEvaluator.h
@@ -25,6 +25,7 @@
#define LLVM_ANALYSIS_ALIASANALYSISEVALUATOR_H
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
class AAResults;
@@ -47,10 +48,10 @@ class AAEvaluator : public PassInfoMixin<AAEvaluator> {
ModRefCount(Arg.ModRefCount) {
Arg.FunctionCount = 0;
}
- ~AAEvaluator();
+ LLVM_ABI ~AAEvaluator();
/// Run the pass over the function.
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+ LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
private:
void runInternal(Function &F, AAResults &AA);
diff --git a/llvm/include/llvm/Analysis/AliasSetTracker.h b/llvm/include/llvm/Analysis/AliasSetTracker.h
index e5817d2409bc6..7d461b230478b 100644
--- a/llvm/include/llvm/Analysis/AliasSetTracker.h
+++ b/llvm/include/llvm/Analysis/AliasSetTracker.h
@@ -25,6 +25,7 @@
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <vector>
@@ -113,7 +114,8 @@ class AliasSet : public ilist_node<AliasSet> {
bool isForwardingAliasSet() const { return Forward; }
/// Merge the specified alias set into this alias set.
- void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
+ LLVM_ABI void mergeSetIn(AliasSet &AS, AliasSetTracker &AST,
+ BatchAAResults &BatchAA);
// Alias Set iteration - Allow access to all of the memory locations which are
// part of this alias set.
@@ -127,17 +129,17 @@ class AliasSet : public ilist_node<AliasSet> {
/// The order matches that of the memory locations, but duplicate pointer
/// values are omitted.
using PointerVector = SmallVector<const Value *, 8>;
- PointerVector getPointers() const;
+ LLVM_ABI PointerVector getPointers() const;
- void print(raw_ostream &OS) const;
- void dump() const;
+ LLVM_ABI void print(raw_ostream &OS) const;
+ LLVM_ABI void dump() const;
private:
// Can only be created by AliasSetTracker.
AliasSet()
: RefCount(0), AliasAny(false), Access(NoAccess), Alias(SetMustAlias) {}
- void removeFromTracker(AliasSetTracker &AST);
+ LLVM_ABI void removeFromTracker(AliasSetTracker &AST);
void addMemoryLocation(AliasSetTracker &AST, const MemoryLocation &MemLoc,
bool KnownMustAlias = false);
@@ -146,11 +148,11 @@ class AliasSet : public ilist_node<AliasSet> {
public:
/// If the specified memory location "may" (or must) alias one of the members
/// in the set return the appropriate AliasResult. Otherwise return NoAlias.
- AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc,
- BatchAAResults &AA) const;
+ LLVM_ABI AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc,
...
[truncated]
|
@compnerd, @vgvassilev this one is ready to go now, if you don't mind having a look. The middle commit is the most interesting since it contains the manual fixups. The rest of the changes were automated with ids and clang-format. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@@ -956,7 +956,7 @@ class AAManager : public AnalysisInfoMixin<AAManager> { | |||
private: | |||
friend AnalysisInfoMixin<AAManager>; | |||
|
|||
static AnalysisKey Key; | |||
LLVM_ABI static AnalysisKey Key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we automate such changes in future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we automate such changes in future?
I've thought about this case a bit since these private AnalysisKey
fields show up a lot. The proper generic solution is to teach IDS to export private fields that are referenced in friend classes and functions, which is what's going on here. I suspect that's is achievable, but I haven't looked into it.
The simple, inelegant solution is to introduce an --always-export=
argument to IDS to tell it to always export symbols of the specified type. We'd then always have to add --always-export="llvm::AnalysisKey"
whenever we run the tool on LLVM. This solution would catch the majority of cases but is more fragile and will miss new patterns in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent some time trying to make IDS recognize this pattern, which I think boils down to:
struct KeyType {};
template <typename T> struct KeyMixin {
static KeyType* getKey() { return &T::Key; }
};
class ExampleClass : public KeyMixin<ExampleClass> {
friend KeyMixin<ExampleClass>;
static KeyType Key; // <-- private field should be exported
};
However, unless the template is explicitly instantiated in the translation unit, the reference to ExampleClass::Key
isn't present in the AST so we don't observe it in IDS's clang::RecursiveASTVisitor
. I don't have any ideas for solving this one generically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A potentially very simple approach is to just always export all private members for any class that has at least one friend
declaration. That would address this issue, but would also over-export.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, yes, updating IDS to always export private static fields when there are friend classes works properly. It finds and exports every AnalysisKey
field and doesn't over-export. In fact, no other fields get exported. IDS PR to address this: compnerd/ids#55.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The visitor does not visit the implicit template instantiation by default iirc.
Purpose
This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the
llvm/Analysis
library. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build.Background
This effort is tracked in #109483. Additional context is provided in this discourse, and documentation for
LLVM_ABI
and related annotations is found in the LLVM repo here.The bulk of these changes were generated automatically using the Interface Definition Scanner (IDS) tool, followed formatting with
git clang-format
.The following manual adjustments were also applied after running IDS on Linux:
#include "llvm/Support/Compiler.h"
to files where it was not auto-added by IDS due to no pre-existing block of include statements.LLVM_TEMPLATE_ABI
andLLVM_EXPORT_TEMPLATE
to exported instantiated templatesLLVM_ABI
to a subset of private class methods and fields that require exportLLVM_ABI
to a small number of symbols that require export but are not declared in headersValidation
Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: