Index: utils/TableGen/CMakeLists.txt =================================================================== --- utils/TableGen/CMakeLists.txt +++ utils/TableGen/CMakeLists.txt @@ -33,4 +33,5 @@ X86DisassemblerTables.cpp X86ModRMFilters.cpp X86RecognizableInstr.cpp + CTagsEmitter.cpp ) Index: utils/TableGen/CTagsEmitter.cpp =================================================================== --- /dev/null +++ utils/TableGen/CTagsEmitter.cpp @@ -0,0 +1,104 @@ +//===- CTagsEmitter.cpp - Generate ctags-compatible index ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend emits an index of definitions in ctags(1) format. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "ctags-emitter" + +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" +#include +#include +#include +using namespace llvm; + +namespace llvm { +extern SourceMgr SrcMgr; +} + +namespace { + +class Tag { +private: + const std::string *Id; + SMLoc Loc; +public: + Tag(const std::string &Name, const SMLoc Location): + Id(&Name), Loc(Location) + {} + int operator<(const Tag &B) const { + return *Id < *B.Id; + } + void emit(raw_ostream &OS) const { + int BufferID = SrcMgr.FindBufferContainingLoc(Loc); + MemoryBuffer *CurMB = SrcMgr.getBufferInfo(BufferID).Buffer; + const char *BufferName = CurMB->getBufferIdentifier(); + std::pair LineAndColumn = SrcMgr.getLineAndColumn(Loc); + OS << *Id << "\t" << BufferName << "\t" << LineAndColumn.first << "\n"; + } +}; + +class CTagsEmitter { +private: + RecordKeeper &Records; +public: + CTagsEmitter(RecordKeeper &R): + Records(R) + {} + + void run(raw_ostream &OS); + +private: + static SMLoc locate(const Record *R); +}; + +} // End anonymous namespace. + +SMLoc CTagsEmitter::locate(const Record *R) { + ArrayRef Locs = R->getLoc(); + if (Locs.empty()) { + SMLoc NullLoc; + return NullLoc; + } + return Locs.front(); +} + +void CTagsEmitter::run(raw_ostream &OS) { + const std::map &Classes = Records.getClasses(); + const std::map &Defs = Records.getDefs(); + std::vector Tags; + // Collect tags. + Tags.reserve(Classes.size() + Defs.size()); + for (std::map::const_iterator I = Classes.begin(), + E = Classes.end(); I != E; ++I) + Tags.push_back(Tag(I->first, locate(I->second))); + for (std::map::const_iterator I = Defs.begin(), + E = Defs.end(); I != E; ++I) + Tags.push_back(Tag(I->first, locate(I->second))); + // Emit tags. + std::sort(Tags.begin(), Tags.end()); + OS << "!_TAG_FILE_FORMAT\t1\t/original ctags format/\n"; + OS << "!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n"; + for (std::vector::const_iterator I = Tags.begin(), E = Tags.end(); + I != E; ++I) + I->emit(OS); +} + +namespace llvm { + +void EmitCTags(RecordKeeper &RK, raw_ostream &OS) { + CTagsEmitter(RK).run(OS); +} + +} // End llvm namespace. Index: utils/TableGen/TableGen.cpp =================================================================== --- utils/TableGen/TableGen.cpp +++ utils/TableGen/TableGen.cpp @@ -40,7 +40,8 @@ GenTgtIntrinsic, PrintEnums, PrintSets, - GenOptParserDefs + GenOptParserDefs, + GenCTags }; namespace { @@ -82,6 +83,8 @@ "Print expanded sets for testing DAG exprs"), clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", "Generate option definitions"), + clEnumValN(GenCTags, "gen-ctags", + "Generate ctags-compatible index"), clEnumValEnd)); cl::opt @@ -161,6 +164,9 @@ } break; } + case GenCTags: + EmitCTags(Records, OS); + break; } return false; Index: utils/TableGen/TableGenBackends.h =================================================================== --- utils/TableGen/TableGenBackends.h +++ utils/TableGen/TableGenBackends.h @@ -75,5 +75,6 @@ void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS); void EmitMapTable(RecordKeeper &RK, raw_ostream &OS); void EmitOptParser(RecordKeeper &RK, raw_ostream &OS); +void EmitCTags(RecordKeeper &RK, raw_ostream &OS); } // End llvm namespace