OptionalFileEntryRef ASTFile;
/// The top-level headers associated with this module.
- llvm::SmallSetVector<const FileEntry *, 2> TopHeaders;
+ llvm::SmallSetVector<FileEntryRef, 2> TopHeaders;
/// top-level header filenames that aren't resolved to FileEntries yet.
std::vector<std::string> TopHeaderNames;
OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const;
/// Add a top-level header associated with this module.
- void addTopHeader(const FileEntry *File);
+ void addTopHeader(FileEntryRef File);
/// Add a top-level header filename associated with this module.
void addTopHeaderFilename(StringRef Filename) {
}
/// The top-level headers associated with this module.
- ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr);
+ ArrayRef<FileEntryRef> getTopHeaders(FileManager &FileMgr);
/// Determine whether this module has declared its intention to
/// directly use another module.
bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn);
/// Get the PCH file if one was included.
- const FileEntry *getPCHFile();
+ OptionalFileEntryRef getPCHFile();
/// Returns true if the ASTUnit was constructed from a serialized
/// module file.
return std::nullopt;
}
-void Module::addTopHeader(const FileEntry *File) {
+void Module::addTopHeader(FileEntryRef File) {
assert(File);
TopHeaders.insert(File);
}
-ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
+ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
if (!TopHeaderNames.empty()) {
- for (std::vector<std::string>::iterator
- I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
- if (auto FE = FileMgr.getFile(*I))
+ for (StringRef TopHeaderName : TopHeaderNames)
+ if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))
TopHeaders.insert(*FE);
- }
TopHeaderNames.clear();
}
return true;
}
-const FileEntry *ASTUnit::getPCHFile() {
+OptionalFileEntryRef ASTUnit::getPCHFile() {
if (!Reader)
- return nullptr;
+ return std::nullopt;
serialization::ModuleFile *Mod = nullptr;
Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {
if (Mod)
return Mod->File;
- return nullptr;
+ return std::nullopt;
}
bool ASTUnit::isModuleFile() const {
llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
- SmallVector<
- std::pair<std::string, OptionalFileEntryRefDegradesToFileEntryPtr>, 8>
- Headers;
+ SmallVector<std::pair<std::string, FileEntryRef>, 8> Headers;
for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
Dir != End && !EC; Dir.increment(EC)) {
// Check whether this entry has an extension typically associated with
// Emit the top headers.
{
- auto TopHeaders = Mod->getTopHeaders(PP->getFileManager());
RecordData::value_type Record[] = {SUBMODULE_TOPHEADER};
- for (auto *H : TopHeaders) {
- SmallString<128> HeaderName(H->getName());
+ for (FileEntryRef H : Mod->getTopHeaders(PP->getFileManager())) {
+ SmallString<128> HeaderName(H.getName());
PreparePathForOutput(HeaderName);
Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, HeaderName);
}
#include "CIndexer.h"
#include "CLog.h"
#include "CXCursor.h"
+#include "CXFile.h"
#include "CXSourceLocation.h"
#include "CXString.h"
#include "CXTranslationUnit.h"
if (!SFile)
return cxstring::createNull();
- FileEntry *FEnt = static_cast<FileEntry *>(SFile);
- return cxstring::createRef(FEnt->getName());
+ FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);
+ return cxstring::createRef(FEnt.getName());
}
time_t clang_getFileTime(CXFile SFile) {
if (!SFile)
return 0;
- FileEntry *FEnt = static_cast<FileEntry *>(SFile);
- return FEnt->getModificationTime();
+ FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);
+ return FEnt.getModificationTime();
}
CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
FileManager &FMgr = CXXUnit->getFileManager();
- auto File = FMgr.getFile(file_name);
- if (!File)
- return nullptr;
- return const_cast<FileEntry *>(*File);
+ return cxfile::makeCXFile(FMgr.getOptionalFileRef(file_name));
}
const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
}
const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
- FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
+ FileID fid = SM.translateFile(*cxfile::getFileEntryRef(file));
std::optional<llvm::MemoryBufferRef> buf = SM.getBufferOrNone(fid);
if (!buf) {
if (size)
return 0;
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
- FileEntry *FEnt = static_cast<FileEntry *>(file);
+ FileEntryRef FEnt = *cxfile::getFileEntryRef(file);
return CXXUnit->getPreprocessor()
.getHeaderSearchInfo()
.isFileMultipleIncludeGuarded(FEnt);
if (!file || !outID)
return 1;
- FileEntry *FEnt = static_cast<FileEntry *>(file);
- const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
+ FileEntryRef FEnt = *cxfile::getFileEntryRef(file);
+ const llvm::sys::fs::UniqueID &ID = FEnt.getUniqueID();
outID->data[0] = ID.getDevice();
outID->data[1] = ID.getFile();
- outID->data[2] = FEnt->getModificationTime();
+ outID->data[2] = FEnt.getModificationTime();
return 0;
}
if (!file1 || !file2)
return false;
- FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
- FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
- return FEnt1->getUniqueID() == FEnt2->getUniqueID();
+ FileEntryRef FEnt1 = *cxfile::getFileEntryRef(file1);
+ FileEntryRef FEnt2 = *cxfile::getFileEntryRef(file2);
+ return FEnt1.getUniqueID() == FEnt2.getUniqueID();
}
CXString clang_File_tryGetRealPathName(CXFile SFile) {
if (!SFile)
return cxstring::createNull();
- FileEntry *FEnt = static_cast<FileEntry *>(SFile);
- return cxstring::createRef(FEnt->tryGetRealPathName());
+ FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);
+ return cxstring::createRef(FEnt.getFileEntry().tryGetRealPathName());
}
//===----------------------------------------------------------------------===//
return nullptr;
const InclusionDirective *ID = getCursorInclusionDirective(cursor);
- OptionalFileEntryRef File = ID->getFile();
- return const_cast<FileEntry *>(File ? &File->getFileEntry() : nullptr);
+ return cxfile::makeCXFile(ID->getFile());
}
unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
}
if (!File)
return nullptr;
- FileEntry *FE = static_cast<FileEntry *>(File);
+ FileEntryRef FE = *cxfile::getFileEntryRef(File);
ASTUnit &Unit = *cxtu::getASTUnit(TU);
HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
- // TODO: Make CXFile a FileEntryRef.
- ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE->getLastRef());
+ ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
return Header.getModule();
}
if (!CXMod)
return nullptr;
Module *Mod = static_cast<Module *>(CXMod);
- if (auto File = Mod->getASTFile())
- return const_cast<FileEntry *>(&File->getFileEntry());
- return nullptr;
+ return cxfile::makeCXFile(Mod->getASTFile());
}
CXModule clang_Module_getParent(CXModule CXMod) {
return 0;
Module *Mod = static_cast<Module *>(CXMod);
FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
- ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
+ ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);
return TopHeaders.size();
}
Module *Mod = static_cast<Module *>(CXMod);
FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
- ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
+ ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);
if (Index < TopHeaders.size())
- return const_cast<FileEntry *>(TopHeaders[Index]);
+ return cxfile::makeCXFile(TopHeaders[Index]);
return nullptr;
}
ASTContext &Ctx = astUnit->getASTContext();
SourceManager &sm = Ctx.getSourceManager();
- FileEntry *fileEntry = static_cast<FileEntry *>(file);
+ FileEntryRef fileEntry = *cxfile::getFileEntryRef(file);
FileID wantedFileID = sm.translateFile(fileEntry);
bool isMainFile = wantedFileID == sm.getMainFileID();
return *this;
}
-Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
- *this << FE->getName();
+Logger &cxindex::Logger::operator<<(FileEntryRef FE) {
+ *this << FE.getName();
return *this;
}
#include "CursorVisitor.h"
#include "CLog.h"
#include "CXCursor.h"
+#include "CXFile.h"
#include "CXSourceLocation.h"
#include "CXTranslationUnit.h"
#include "clang/AST/DeclObjC.h"
}
if (Log)
- *Log << cursor << " @" << static_cast<const FileEntry *>(file);
+ *Log << cursor << " @" << *cxfile::getFileEntryRef(file);
ASTUnit *CXXUnit = cxcursor::getCursorASTUnit(cursor);
if (!CXXUnit)
cursor.kind == CXCursor_MacroExpansion) {
if (findMacroRefsInFile(cxcursor::getCursorTU(cursor),
cursor,
- static_cast<const FileEntry *>(file),
+ *cxfile::getFileEntryRef(file),
visitor))
return CXResult_VisitBreak;
return CXResult_Success;
if (findIdRefsInFile(cxcursor::getCursorTU(cursor),
refCursor,
- static_cast<const FileEntry *>(file),
+ *cxfile::getFileEntryRef(file),
visitor))
return CXResult_VisitBreak;
return CXResult_Success;
}
if (Log)
- *Log << TU << " @" << static_cast<const FileEntry *>(file);
+ *Log << TU << " @" << *cxfile::getFileEntryRef(file);
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
- if (findIncludesInFile(TU, static_cast<const FileEntry *>(file), visitor))
+ if (findIncludesInFile(TU, *cxfile::getFileEntryRef(file), visitor))
return CXResult_VisitBreak;
return CXResult_Success;
}
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
+#include "CXFile.h"
#include "CXSourceLocation.h"
#include "CXTranslationUnit.h"
#include "clang/AST/DeclVisitor.h"
InclusionStack.pop_back();
// Callback to the client.
- // FIXME: We should have a function to construct CXFiles.
- CB(static_cast<CXFile>(const_cast<FileEntry *>(
- static_cast<const FileEntry *>(FI.getContentCache().OrigEntry))),
+ CB(cxfile::makeCXFile(*FI.getContentCache().OrigEntry),
InclusionStack.data(), InclusionStack.size(), clientData);
}
}
#define LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H
#include "clang-c/Index.h"
+#include "clang/Basic/FileEntry.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
}
namespace clang {
- class FileEntry;
-
namespace cxindex {
class Logger;
~Logger();
Logger &operator<<(CXTranslationUnit);
- Logger &operator<<(const FileEntry *FE);
+ Logger &operator<<(FileEntryRef FE);
Logger &operator<<(CXCursor cursor);
Logger &operator<<(CXSourceLocation);
Logger &operator<<(CXSourceRange);
--- /dev/null
+//===- CXFile.h - Routines for manipulating CXFile --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXFILE_H
+#define LLVM_CLANG_TOOLS_LIBCLANG_CXFILE_H
+
+#include "clang-c/CXFile.h"
+#include "clang/Basic/FileEntry.h"
+
+namespace clang {
+namespace cxfile {
+inline CXFile makeCXFile(OptionalFileEntryRef FE) {
+ return CXFile(FE ? &FE->getMapEntry() : nullptr);
+}
+
+inline OptionalFileEntryRef getFileEntryRef(CXFile File) {
+ if (!File)
+ return std::nullopt;
+ return FileEntryRef(*reinterpret_cast<const FileEntryRef::MapEntry *>(File));
+}
+} // namespace cxfile
+} // namespace clang
+
+#endif
#include "CXIndexDataConsumer.h"
#include "CIndexDiagnostic.h"
+#include "CXFile.h"
#include "CXTranslationUnit.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
return CB.abortQuery(ClientData, nullptr);
}
-void CXIndexDataConsumer::enteredMainFile(const FileEntry *File) {
+void CXIndexDataConsumer::enteredMainFile(OptionalFileEntryRef File) {
if (File && CB.enteredMainFile) {
CXIdxClientFile idxFile =
- CB.enteredMainFile(ClientData,
- static_cast<CXFile>(const_cast<FileEntry *>(File)),
- nullptr);
- FileMap[File] = idxFile;
+ CB.enteredMainFile(ClientData, cxfile::makeCXFile(*File), nullptr);
+ FileMap[*File] = idxFile;
}
}
ScratchAlloc SA(*this);
CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
SA.toCStr(filename),
- static_cast<CXFile>(
- const_cast<FileEntry *>(FE)),
+ cxfile::makeCXFile(File),
isImport, isAngled, isModuleImport };
CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
FileMap[FE] = idxFile;
if (SrcMod->getTopLevelModule() == Mod->getTopLevelModule())
return;
- FileEntry *FE = nullptr;
- if (auto File = Mod->getASTFile())
- FE = const_cast<FileEntry *>(&File->getFileEntry());
- CXIdxImportedASTFileInfo Info = {static_cast<CXFile>(FE), Mod,
+ OptionalFileEntryRef FE = Mod->getASTFile();
+ CXIdxImportedASTFileInfo Info = {cxfile::makeCXFile(FE), Mod,
getIndexLoc(ImportD->getLocation()),
ImportD->isImplicit()};
CXIdxClientASTFile astFile = CB.importedASTFile(ClientData, &Info);
(void)astFile;
}
-void CXIndexDataConsumer::importedPCH(const FileEntry *File) {
+void CXIndexDataConsumer::importedPCH(FileEntryRef File) {
if (!CB.importedASTFile)
return;
CXIdxImportedASTFileInfo Info = {
- static_cast<CXFile>(
- const_cast<FileEntry *>(File)),
+ cxfile::makeCXFile(File),
/*module=*/nullptr,
getIndexLoc(SourceLocation()),
/*isImplicit=*/false
if (FID.isInvalid())
return;
- const FileEntry *FE = SM.getFileEntryForID(FID);
+ OptionalFileEntryRefDegradesToFileEntryPtr FE = SM.getFileEntryRefForID(FID);
if (indexFile)
*indexFile = getIndexFile(FE);
if (file)
- *file = const_cast<FileEntry *>(FE);
+ *file = cxfile::makeCXFile(FE);
if (line)
*line = SM.getLineNumber(FID, FileOffset);
if (column)
bool hasDiagnosticCallback() const { return CB.diagnostic; }
- void enteredMainFile(const FileEntry *File);
+ void enteredMainFile(OptionalFileEntryRef File);
void ppIncludedFile(SourceLocation hashLoc, StringRef filename,
OptionalFileEntryRef File, bool isImport, bool isAngled,
bool isModuleImport);
void importedModule(const ImportDecl *ImportD);
- void importedPCH(const FileEntry *File);
+ void importedPCH(FileEntryRef File);
void startedTranslationUnit();
//===----------------------------------------------------------------------===//
#include "CXLoadedDiagnostic.h"
+#include "CXFile.h"
#include "CXString.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
FileSystemOptions FO;
FileManager FakeFiles;
- llvm::DenseMap<unsigned, const FileEntry *> Files;
+ llvm::DenseMap<unsigned, FileEntryRef> Files;
/// Copy the string into our own allocator.
const char *copyString(StringRef Blob) {
if (FileID == 0)
LoadedLoc.file = nullptr;
else {
- LoadedLoc.file = const_cast<FileEntry *>(TopDiags->Files[FileID]);
- if (!LoadedLoc.file)
+ auto It = TopDiags->Files.find(FileID);
+ if (It == TopDiags->Files.end())
return reportInvalidFile("Corrupted file entry in source location");
+ LoadedLoc.file = cxfile::makeCXFile(It->second);
}
LoadedLoc.line = SDLoc.Line;
LoadedLoc.column = SDLoc.Col;
if (Name.size() > 65536)
return reportInvalidFile("Out-of-bounds string in filename");
TopDiags->FileNames[ID] = TopDiags->copyString(Name);
- TopDiags->Files[ID] =
- TopDiags->FakeFiles.getVirtualFile(Name, Size, Timestamp);
+ TopDiags->Files.insert(
+ {ID, TopDiags->FakeFiles.getVirtualFileRef(Name, Size, Timestamp)});
return std::error_code();
}
#include "CXSourceLocation.h"
#include "CIndexer.h"
#include "CLog.h"
+#include "CXFile.h"
#include "CXLoadedDiagnostic.h"
#include "CXString.h"
#include "CXTranslationUnit.h"
LogRef Log = Logger::make(__func__);
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
- const FileEntry *File = static_cast<const FileEntry *>(file);
+ FileEntryRef File = *cxfile::getFileEntryRef(file);
SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
if (SLoc.isInvalid()) {
if (Log)
*Log << llvm::format("(\"%s\", %d, %d) = invalid",
- File->getName().str().c_str(), line, column);
+ File.getName().str().c_str(), line, column);
return clang_getNullLocation();
}
CXSourceLocation CXLoc =
cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
if (Log)
- *Log << llvm::format("(\"%s\", %d, %d) = ", File->getName().str().c_str(),
+ *Log << llvm::format("(\"%s\", %d, %d) = ", File.getName().str().c_str(),
line, column)
<< CXLoc;
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceLocation SLoc
- = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
+ = CXXUnit->getLocation(*cxfile::getFileEntryRef(file), offset);
if (SLoc.isInvalid())
return clang_getNullLocation();
}
if (file)
- *file = const_cast<FileEntry *>(SM.getFileEntryForSLocEntry(sloc));
+ *file = cxfile::makeCXFile(SM.getFileEntryRefForID(fileID));
if (line)
*line = SM.getExpansionLineNumber(ExpansionLoc);
if (column)
return createNullLocation(file, line, column, offset);
if (file)
- *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
+ *file = cxfile::makeCXFile(SM.getFileEntryRefForID(FID));
if (line)
*line = SM.getLineNumber(FID, FileOffset);
if (column)
return createNullLocation(file, line, column, offset);
if (file)
- *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
+ *file = cxfile::makeCXFile(SM.getFileEntryRefForID(FID));
if (line)
*line = SM.getLineNumber(FID, FileOffset);
if (column)
if (Loc == MainFileLoc && Reason == PPCallbacks::EnterFile) {
IsMainFileEntered = true;
- DataConsumer.enteredMainFile(SM.getFileEntryForID(SM.getMainFileID()));
+ DataConsumer.enteredMainFile(
+ *SM.getFileEntryRefForID(SM.getMainFileID()));
}
}
PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
if (!PPOpts.ImplicitPCHInclude.empty()) {
- auto File = CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude);
- if (File)
+ if (auto File =
+ CI.getFileManager().getOptionalFileRef(PPOpts.ImplicitPCHInclude))
DataConsumer->importedPCH(*File);
}
ASTUnit::ConcurrencyCheck Check(*Unit);
- if (const FileEntry *PCHFile = Unit->getPCHFile())
- DataConsumer.importedPCH(PCHFile);
+ if (OptionalFileEntryRef PCHFile = Unit->getPCHFile())
+ DataConsumer.importedPCH(*PCHFile);
FileManager &FileMgr = Unit->getFileManager();
if (Unit->getOriginalSourceFileName().empty())
- DataConsumer.enteredMainFile(nullptr);
- else if (auto MainFile = FileMgr.getFile(Unit->getOriginalSourceFileName()))
+ DataConsumer.enteredMainFile(std::nullopt);
+ else if (auto MainFile =
+ FileMgr.getFileRef(Unit->getOriginalSourceFileName()))
DataConsumer.enteredMainFile(*MainFile);
else
- DataConsumer.enteredMainFile(nullptr);
+ DataConsumer.enteredMainFile(std::nullopt);
DataConsumer.setASTContext(Unit->getASTContext());
DataConsumer.startedTranslationUnit();