#ifndef CANGJIE_INCREMENTALGEN2_H
#define CANGJIE_INCREMENTALGEN2_H
#include <map>
#include <unordered_set>
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "cangjie/IncrementalCompilation/CachedMangleMap.h"
namespace Cangjie::CodeGen {
class IncrementalGen {
public:
explicit IncrementalGen(bool cgParallelEnabled);
~IncrementalGen() = default;
bool Init(const std::string& cachedIRPath, llvm::LLVMContext& llvmContext);
llvm::Module* LinkModules(llvm::Module* incremental, const CachedMangleMap& cachedMangles = {});
std::vector<std::string> GetIncrLLVMUsedNames();
std::vector<std::string> GetIncrCachedStaticGINames();
private:
void InitCodeGenAddedCachedMap();
void UpdateCachedDeclsFromInjectedModule(const CachedMangleMap& cachedMangles);
void CopyDeclarationsToInjectedModule();
void FillValueMap(llvm::ValueToValueMapTy& valueMap);
void UpdateInitializationsOfGlobalVariables(llvm::ValueToValueMapTy& valueMap);
void UpdateDefinitionsOfFunction(llvm::ValueToValueMapTy& valueMap);
void UpdateBodyOfKeepTypesFunction(llvm::ValueToValueMapTy& valueMap);
void CollectUselessFunctions();
void EraseUselessFunctions();
void CollectUselessDefinitions(llvm::GlobalObject* uselessDefinition);
void UpdateReflectionMetadata();
void UpdateCodeGenAddedMetadata();
void UpdateIncrLLVMUsedNames();
const bool cgParallelEnabled;
std::unique_ptr<llvm::Module> incrementalModule;
std::unique_ptr<llvm::Module> injectedModule;
std::unordered_map<std::string, std::unordered_set<std::string>> codegenAddedCachedMap;
std::unordered_set<llvm::GlobalObject*> uselessDefinitions;
std::unordered_set<llvm::GlobalObject*> deferErase;
std::vector<std::string> llvmUsedGVNames;
std::vector<std::string> staticGINames;
};
}
#endif