[llvm] 394a388 - [TableGen] Add a location for a class definition that was forward-declared

Nicolai Hähnle via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 20 06:56:47 PDT 2022


Author: Roman Rusyaev
Date: 2022-07-20T15:56:17+02:00
New Revision: 394a388d140dc9e74178532501cddb558a589398

URL: https://github.com/llvm/llvm-project/commit/394a388d140dc9e74178532501cddb558a589398
DIFF: https://github.com/llvm/llvm-project/commit/394a388d140dc9e74178532501cddb558a589398.diff

LOG: [TableGen] Add a location for a class definition that was forward-declared

This change improves ctags generation for tablegen files.

For the following example
```
class A;

class A {
  int a;
}
```
Previously, tags were generated only for a forward declaration of class 'A'.

This patch allows generating tags for the forward declarations
and further definition of class 'A'.

Reviewed By: barannikov88

Original patch by: rusyaev-roman (Roman Rusyaev)
Some adjustments by: nhaehnle (Nicolai Hähnle)

Differential Revision: https://reviews.llvm.org/D129935

Added: 
    llvm/test/TableGen/GenTags.td

Modified: 
    llvm/include/llvm/TableGen/Record.h
    llvm/lib/TableGen/Record.cpp
    llvm/lib/TableGen/TGParser.cpp
    llvm/utils/TableGen/CTagsEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 44daad976c128..bfcf44da04c0f 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1558,6 +1558,7 @@ class Record {
   // Location where record was instantiated, followed by the location of
   // multiclass prototypes used.
   SmallVector<SMLoc, 4> Locs;
+  SmallVector<SMLoc, 0> ForwardDeclarationLocs;
   SmallVector<Init *, 0> TemplateArgs;
   SmallVector<RecordVal, 0> Values;
   SmallVector<AssertionInfo, 0> Assertions;
@@ -1623,6 +1624,13 @@ class Record {
   ArrayRef<SMLoc> getLoc() const { return Locs; }
   void appendLoc(SMLoc Loc) { Locs.push_back(Loc); }
 
+  ArrayRef<SMLoc> getForwardDeclarationLocs() const {
+    return ForwardDeclarationLocs;
+  }
+
+  // Update a class location when encountering a (re-)definition.
+  void updateClassLoc(SMLoc Loc);
+
   // Make the type that this record should have based on its superclasses.
   RecordRecTy *getType();
 

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 75a99e95541a3..6b899a049e6b0 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2424,6 +2424,14 @@ void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
   if (PrintSem) OS << ";\n";
 }
 
+void Record::updateClassLoc(SMLoc Loc) {
+  assert(Locs.size() == 1);
+  ForwardDeclarationLocs.push_back(Locs.front());
+
+  Locs.clear();
+  Locs.push_back(Loc);
+}
+
 void Record::checkName() {
   // Ensure the record name has string type.
   const TypedInit *TypedName = cast<const TypedInit>(Name);

diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index acf93dc3d7925..aab1802c53480 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -3391,6 +3391,8 @@ bool TGParser::ParseClass() {
         !CurRec->getTemplateArgs().empty())
       return TokError("Class '" + CurRec->getNameInitAsString() +
                       "' already defined");
+
+    CurRec->updateClassLoc(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
index 0000000000000..74fe5afc27248
--- /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
index ccb7f3300dde4..fe62d6a9b67f2 100644
--- a/llvm/utils/TableGen/CTagsEmitter.cpp
+++ b/llvm/utils/TableGen/CTagsEmitter.cpp
@@ -27,18 +27,22 @@ namespace {
 
 class Tag {
 private:
-  const std::string *Id;
-  SMLoc Loc;
+  StringRef Id;
+  StringRef BufferIdentifier;
+  unsigned Line;
 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 {
+  Tag(StringRef Name, const SMLoc Location) : Id(Name) {
     const MemoryBuffer *CurMB =
-        SrcMgr.getMemoryBuffer(SrcMgr.FindBufferContainingLoc(Loc));
-    auto BufferName = CurMB->getBufferIdentifier();
-    std::pair<unsigned, unsigned> LineAndColumn = SrcMgr.getLineAndColumn(Loc);
-    OS << *Id << "\t" << BufferName << "\t" << LineAndColumn.first << "\n";
+        SrcMgr.getMemoryBuffer(SrcMgr.FindBufferContainingLoc(Location));
+    BufferIdentifier = CurMB->getBufferIdentifier();
+    auto LineAndColumn = SrcMgr.getLineAndColumn(Location);
+    Line = LineAndColumn.first;
+  }
+  int operator<(const Tag &B) const {
+    return std::make_tuple(Id, BufferIdentifier, Line) < std::make_tuple(B.Id, B.BufferIdentifier, B.Line);
+  }
+  void emit(raw_ostream &OS) const {
+    OS << Id << "\t" << BufferIdentifier << "\t" << Line << "\n";
   }
 };
 
@@ -67,8 +71,11 @@ void CTagsEmitter::run(raw_ostream &OS) {
   std::vector<Tag> Tags;
   // Collect tags.
   Tags.reserve(Classes.size() + Defs.size());
-  for (const auto &C : Classes)
+  for (const auto &C : Classes) {
     Tags.push_back(Tag(C.first, locate(C.second.get())));
+    for (SMLoc FwdLoc : C.second->getForwardDeclarationLocs())
+      Tags.push_back(Tag(C.first, FwdLoc));
+  }
   for (const auto &D : Defs)
     Tags.push_back(Tag(D.first, locate(D.second.get())));
   // Emit tags.


        


More information about the llvm-commits mailing list