void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, StringRef desc) { Checkers.push_back(CheckerInfo(fn, name, desc)); // Record the presence of the checker in its packages. StringRef packageName, leafName; llvm::tie(packageName, leafName) = name.rsplit(PackageSeparator); while (!leafName.empty()) { Packages[packageName] += 1; llvm::tie(packageName, leafName) = packageName.rsplit(PackageSeparator); } }
/// GetDwarfFile - takes a file name an number to place in the dwarf file and /// directory tables. If the file number has already been allocated it is an /// error and zero is returned and the client reports the error, else the /// allocated file number is returned. The file numbers may be in any order. unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) { // TODO: a FileNumber of zero says to use the next available file number. // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked // to not be less than one. This needs to be change to be not less than zero. // Make space for this FileNumber in the MCDwarfFiles vector if needed. if (FileNumber >= MCDwarfFiles.size()) { MCDwarfFiles.resize(FileNumber + 1); } else { MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber]; if (ExistingFile) // It is an error to use see the same number more than once. return 0; } // Get the new MCDwarfFile slot for this FileNumber. MCDwarfFile *&File = MCDwarfFiles[FileNumber]; // Separate the directory part from the basename of the FileName. std::pair<StringRef, StringRef> Slash = FileName.rsplit('/'); // Find or make a entry in the MCDwarfDirs vector for this Directory. StringRef Name; unsigned DirIndex; // Capture directory name. if (Slash.second.empty()) { Name = Slash.first; DirIndex = 0; // For FileNames with no directories a DirIndex of 0 is used. } else { StringRef Directory = Slash.first; Name = Slash.second; for (DirIndex = 1; DirIndex < MCDwarfDirs.size(); DirIndex++) { if (Directory == MCDwarfDirs[DirIndex]) break; } if (DirIndex >= MCDwarfDirs.size()) { char *Buf = static_cast<char *>(Allocate(Directory.size())); memcpy(Buf, Directory.data(), Directory.size()); MCDwarfDirs.push_back(StringRef(Buf, Directory.size())); } } // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles // vector. char *Buf = static_cast<char *>(Allocate(Name.size())); memcpy(Buf, Name.data(), Name.size()); File = new (*this) MCDwarfFile(StringRef(Buf, Name.size()), DirIndex); // return the allocated FileNumber. return FileNumber; }
bool MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes, const DefinedAtom *atom, unsigned &ordinal) { const File *objFile = &atom->file(); assert(objFile); StringRef objName = objFile->path(); std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/'); if (!dirAndLeaf.second.empty()) objName = dirAndLeaf.second; for (const OrderFileNode &info : nodes) { if (info.fileFilter.empty()) { // Have unprefixed symbol name in order file that matches this atom. ordinal = info.order; return true; } if (info.fileFilter.equals(objName)) { // Have prefixed symbol name in order file that matches atom's path. ordinal = info.order; return true; } } return false; }
void ModuleFile::getImportDecls(SmallVectorImpl<Decl *> &Results) { if (!Bits.ComputedImportDecls) { ASTContext &Ctx = getContext(); for (auto &Dep : Dependencies) { // FIXME: We need a better way to show headers, since they usually /are/ // re-exported. This isn't likely to come up much, though. if (Dep.isHeader()) continue; StringRef ModulePathStr = Dep.RawPath; StringRef ScopePath; if (Dep.isScoped()) std::tie(ModulePathStr, ScopePath) = ModulePathStr.rsplit('\0'); SmallVector<std::pair<swift::Identifier, swift::SourceLoc>, 1> AccessPath; while (!ModulePathStr.empty()) { StringRef NextComponent; std::tie(NextComponent, ModulePathStr) = ModulePathStr.split('\0'); AccessPath.push_back({Ctx.getIdentifier(NextComponent), SourceLoc()}); } if (AccessPath.size() == 1 && AccessPath[0].first == Ctx.StdlibModuleName) continue; Module *M = Ctx.getModule(AccessPath); auto Kind = ImportKind::Module; if (!ScopePath.empty()) { auto ScopeID = Ctx.getIdentifier(ScopePath); assert(!ScopeID.empty() && "invalid decl name (non-top-level decls not supported)"); if (!M) { // The dependency module could not be loaded. Just make a guess // about the import kind, we cannot do better. Kind = ImportKind::Func; } else { // Lookup the decl in the top-level module. Module *TopLevelModule = M; if (AccessPath.size() > 1) TopLevelModule = Ctx.getLoadedModule(AccessPath.front().first); SmallVector<ValueDecl *, 8> Decls; TopLevelModule->lookupQualified( ModuleType::get(TopLevelModule), ScopeID, NL_QualifiedDefault | NL_KnownNoDependency, nullptr, Decls); Optional<ImportKind> FoundKind = ImportDecl::findBestImportKind(Decls); assert(FoundKind.hasValue() && "deserialized imports should not be ambiguous"); Kind = *FoundKind; } AccessPath.push_back({ ScopeID, SourceLoc() }); } auto *ID = ImportDecl::create(Ctx, FileContext, SourceLoc(), Kind, SourceLoc(), AccessPath); ID->setModule(M); if (Dep.isExported()) ID->getAttrs().add( new (Ctx) ExportedAttr(/*IsImplicit=*/false)); ImportDecls.push_back(ID); } Bits.ComputedImportDecls = true; } Results.append(ImportDecls.begin(), ImportDecls.end()); }
GlobalModuleIndex::GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer, llvm::BitstreamCursor Cursor) : Buffer(std::move(Buffer)), IdentifierIndex(), NumIdentifierLookups(), NumIdentifierLookupHits() { // Read the global index. bool InGlobalIndexBlock = false; bool Done = false; while (!Done) { llvm::BitstreamEntry Entry = Cursor.advance(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: return; case llvm::BitstreamEntry::EndBlock: if (InGlobalIndexBlock) { InGlobalIndexBlock = false; Done = true; continue; } return; case llvm::BitstreamEntry::Record: // Entries in the global index block are handled below. if (InGlobalIndexBlock) break; return; case llvm::BitstreamEntry::SubBlock: if (!InGlobalIndexBlock && Entry.ID == GLOBAL_INDEX_BLOCK_ID) { if (Cursor.EnterSubBlock(GLOBAL_INDEX_BLOCK_ID)) return; InGlobalIndexBlock = true; } else if (Cursor.SkipBlock()) { return; } continue; } SmallVector<uint64_t, 64> Record; StringRef Blob; switch ((IndexRecordTypes)Cursor.readRecord(Entry.ID, Record, &Blob)) { case INDEX_METADATA: // Make sure that the version matches. if (Record.size() < 1 || Record[0] != CurrentVersion) return; break; case MODULE: { unsigned Idx = 0; unsigned ID = Record[Idx++]; // Make room for this module's information. if (ID == Modules.size()) Modules.push_back(ModuleInfo()); else Modules.resize(ID + 1); // Size/modification time for this module file at the time the // global index was built. Modules[ID].Size = Record[Idx++]; Modules[ID].ModTime = Record[Idx++]; // File name. unsigned NameLen = Record[Idx++]; Modules[ID].FileName.assign(Record.begin() + Idx, Record.begin() + Idx + NameLen); Idx += NameLen; // Dependencies unsigned NumDeps = Record[Idx++]; Modules[ID].Dependencies.insert(Modules[ID].Dependencies.end(), Record.begin() + Idx, Record.begin() + Idx + NumDeps); Idx += NumDeps; // Make sure we're at the end of the record. assert(Idx == Record.size() && "More module info?"); // Record this module as an unresolved module. // FIXME: this doesn't work correctly for module names containing path // separators. StringRef ModuleName = llvm::sys::path::stem(Modules[ID].FileName); // Remove the -<hash of ModuleMapPath> ModuleName = ModuleName.rsplit('-').first; UnresolvedModules[ModuleName] = ID; break; } case IDENTIFIER_INDEX: // Wire up the identifier index. if (Record[0]) { IdentifierIndex = IdentifierIndexTable::Create( (const unsigned char *)Blob.data() + Record[0], (const unsigned char *)Blob.data() + sizeof(uint32_t), (const unsigned char *)Blob.data(), IdentifierIndexReaderTrait()); } break; } } }