blob: 40d2c112ec0f5fb270576fbf2fcbc5ea7afa78b2 [file] [log] [blame]
//===--- IndexUnitWriter.h - Index unit serialization ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_INDEX_INDEXUNITWRITER_H
#define LLVM_CLANG_INDEX_INDEXUNITWRITER_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallString.h"
#include <string>
#include <vector>
namespace llvm {
class BitstreamWriter;
}
namespace clang {
class FileEntry;
class FileManager;
namespace index {
namespace writer {
/// An opaque pointer to a module used by the IndexUnitWriter to associate
/// record and file dependencies with a module, and as a token for getting
/// information about the module from the caller.
typedef const void *OpaqueModule;
/// Module info suitable for serialization.
///
/// This is used for top-level modules and sub-modules.
struct ModuleInfo {
/// Full, dot-separate, module name.
StringRef Name;
};
typedef llvm::function_ref<ModuleInfo(OpaqueModule, SmallVectorImpl<char> &Scratch)>
ModuleInfoWriterCallback;
} // end namespace writer
class IndexUnitWriter {
FileManager &FileMgr;
SmallString<64> UnitsPath;
std::string ProviderIdentifier;
std::string ProviderVersion;
std::string OutputFile;
std::string ModuleName;
const FileEntry *MainFile;
bool IsSystemUnit;
bool IsModuleUnit;
bool IsDebugCompilation;
std::string TargetTriple;
std::string WorkDir;
std::string SysrootPath;
std::function<writer::ModuleInfo(writer::OpaqueModule,
SmallVectorImpl<char> &Scratch)> GetInfoForModuleFn;
struct FileInclude {
int Index;
unsigned Line;
};
struct FileEntryData {
const FileEntry *File;
bool IsSystem;
int ModuleIndex;
std::vector<FileInclude> Includes;
};
std::vector<FileEntryData> Files;
std::vector<writer::OpaqueModule> Modules;
llvm::DenseMap<const FileEntry *, int> IndexByFile;
llvm::DenseMap<writer::OpaqueModule, int> IndexByModule;
llvm::DenseSet<const FileEntry *> SeenASTFiles;
struct RecordOrUnitData {
std::string Name;
int FileIndex;
int ModuleIndex;
bool IsSystem;
};
std::vector<RecordOrUnitData> Records;
std::vector<RecordOrUnitData> ASTFileUnits;
public:
/// \param MainFile the main file for a compiled source file. This should be
/// null for PCH and module units.
/// \param IsSystem true for system module units, false otherwise.
IndexUnitWriter(FileManager &FileMgr,
StringRef StorePath,
StringRef ProviderIdentifier, StringRef ProviderVersion,
StringRef OutputFile,
StringRef ModuleName,
const FileEntry *MainFile,
bool IsSystem,
bool IsModuleUnit,
bool IsDebugCompilation,
StringRef TargetTriple,
StringRef SysrootPath,
writer::ModuleInfoWriterCallback GetInfoForModule);
~IndexUnitWriter();
int addFileDependency(const FileEntry *File, bool IsSystem,
writer::OpaqueModule Mod);
void addRecordFile(StringRef RecordFile, const FileEntry *File, bool IsSystem,
writer::OpaqueModule Mod);
void addASTFileDependency(const FileEntry *File, bool IsSystem,
writer::OpaqueModule Mod, bool withoutUnitName = false);
void addUnitDependency(StringRef UnitFile, const FileEntry *File, bool IsSystem,
writer::OpaqueModule Mod);
bool addInclude(const FileEntry *Source, unsigned Line, const FileEntry *Target);
bool write(std::string &Error);
void getUnitNameForOutputFile(StringRef FilePath, SmallVectorImpl<char> &Str);
void getUnitPathForOutputFile(StringRef FilePath, SmallVectorImpl<char> &Str);
/// If the unit file exists and \p timeCompareFilePath is provided, it will
/// return true if \p timeCompareFilePath is older than the unit file.
Optional<bool> isUnitUpToDateForOutputFile(StringRef FilePath,
Optional<StringRef> TimeCompareFilePath,
std::string &Error);
static void getUnitNameForAbsoluteOutputFile(StringRef FilePath, SmallVectorImpl<char> &Str);
static bool initIndexDirectory(StringRef StorePath, std::string &Error);
private:
class PathStorage;
int addModule(writer::OpaqueModule Mod);
void writeUnitInfo(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
void writeDependencies(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
void writeIncludes(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
void writePaths(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
void writeModules(llvm::BitstreamWriter &Stream);
};
} // end namespace index
} // end namespace clang
#endif