[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
This commit is contained in:
parent
643dfd97d5
commit
394a388d14
|
@ -1558,6 +1558,7 @@ private:
|
|||
// 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 @@ public:
|
|||
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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 =
|
||||
|
|
9
llvm/test/TableGen/GenTags.td
Normal file
9
llvm/test/TableGen/GenTags.td
Normal file
|
@ -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";
|
||||
}
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue
Block a user