[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