diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -3391,6 +3391,9 @@ !CurRec->getTemplateArgs().empty()) return TokError("Class '" + CurRec->getNameInitAsString() + "' already defined"); + + // Add a location for the class definition. + CurRec->appendLoc(Lex.getLoc()); } else { // If this is the first reference to this class, create and add it. auto NewRec = diff --git a/llvm/test/TableGen/GenTags.td b/llvm/test/TableGen/GenTags.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/GenTags.td @@ -0,0 +1,9 @@ +// RUN: llvm-tblgen --gen-ctags %s | FileCheck %s -DFILE=%s + +// CHECK: A [[FILE]] [[@LINE+1]] +class A; + +// CHECK: A [[FILE]] [[@LINE+1]] +class A { + string name = "A"; +} diff --git a/llvm/utils/TableGen/CTagsEmitter.cpp b/llvm/utils/TableGen/CTagsEmitter.cpp --- a/llvm/utils/TableGen/CTagsEmitter.cpp +++ b/llvm/utils/TableGen/CTagsEmitter.cpp @@ -28,17 +28,20 @@ class Tag { private: const std::string *Id; - SMLoc Loc; + ArrayRef Locs; + public: - Tag(const std::string &Name, const SMLoc Location) - : Id(&Name), Loc(Location) {} + Tag(const std::string &Name, ArrayRef Locs) : Id(&Name), Locs(Locs) {} int operator<(const Tag &B) const { return *Id < *B.Id; } void emit(raw_ostream &OS) const { - const MemoryBuffer *CurMB = - SrcMgr.getMemoryBuffer(SrcMgr.FindBufferContainingLoc(Loc)); - auto BufferName = CurMB->getBufferIdentifier(); - std::pair LineAndColumn = SrcMgr.getLineAndColumn(Loc); - OS << *Id << "\t" << BufferName << "\t" << LineAndColumn.first << "\n"; + for (auto Loc : Locs) { + const MemoryBuffer *CurMB = + SrcMgr.getMemoryBuffer(SrcMgr.FindBufferContainingLoc(Loc)); + auto BufferName = CurMB->getBufferIdentifier(); + std::pair LineAndColumn = + SrcMgr.getLineAndColumn(Loc); + OS << *Id << "\t" << BufferName << "\t" << LineAndColumn.first << "\n"; + } } }; @@ -49,18 +52,10 @@ 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(); - return !Locs.empty() ? Locs.front() : SMLoc(); -} - void CTagsEmitter::run(raw_ostream &OS) { const auto &Classes = Records.getClasses(); const auto &Defs = Records.getDefs(); @@ -68,9 +63,9 @@ // Collect tags. Tags.reserve(Classes.size() + Defs.size()); for (const auto &C : Classes) - Tags.push_back(Tag(C.first, locate(C.second.get()))); + Tags.push_back(Tag(C.first, C.second->getLoc())); for (const auto &D : Defs) - Tags.push_back(Tag(D.first, locate(D.second.get()))); + Tags.push_back(Tag(D.first, D.second->getLoc())); // Emit tags. llvm::sort(Tags); OS << "!_TAG_FILE_FORMAT\t1\t/original ctags format/\n";