[clang-tools-extra] [clang-doc] Add Start and End Line Numbers (PR #135081)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 9 14:27:00 PDT 2025
https://github.com/PeterChou1 updated https://github.com/llvm/llvm-project/pull/135081
>From 8fb896f16396c2e01427ac7baa8791461ff500a3 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Thu, 3 Apr 2025 17:07:01 -0400
Subject: [PATCH 1/5] [clang-doc] add start and end line number
---
clang-tools-extra/clang-doc/BitcodeReader.cpp | 2 +-
clang-tools-extra/clang-doc/BitcodeWriter.cpp | 9 +-
clang-tools-extra/clang-doc/Mapper.cpp | 17 +++-
clang-tools-extra/clang-doc/Mapper.h | 3 +
clang-tools-extra/clang-doc/Representation.h | 22 ++---
clang-tools-extra/clang-doc/Serialize.cpp | 85 ++++++++++---------
6 files changed, 82 insertions(+), 56 deletions(-)
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 1f2fb0a8b2b85..c9f588303fd08 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -85,7 +85,7 @@ llvm::Error decodeRecord(const Record &R, std::optional<Location> &Field,
if (R[0] > INT_MAX)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"integer too large to parse");
- Field.emplace((int)R[0], Blob, (bool)R[1]);
+ Field.emplace((int)R[0], (int) R[1], Blob, (bool)R[2]);
return llvm::Error::success();
}
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index 06f30f76e33d8..8230097c0726d 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -77,13 +77,16 @@ static void LocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
{// 0. Fixed-size integer (line number)
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
BitCodeConstants::LineNumberSize),
- // 1. Boolean (IsFileInRootDir)
+ // 1. Fixed-size integer (start line number)
+ llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
+ BitCodeConstants::LineNumberSize),
+ // 2. Boolean (IsFileInRootDir)
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
BitCodeConstants::BoolSize),
- // 2. Fixed-size integer (length of the following string (filename))
+ // 3. Fixed-size integer (length of the following string (filename))
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
BitCodeConstants::StringLengthSize),
- // 3. The string blob
+ // 4. The string blob
llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
}
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index 6c90db03424c6..bdcf0c842b98f 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -28,6 +28,21 @@ template <typename T> bool isTypedefAnonRecord(const T *D) {
return false;
}
+Location MapASTVisitor::getDeclLocation(const NamedDecl *D) const {
+ bool IsFileInRootDir;
+ llvm::SmallString<128> File =
+ getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
+ ASTContext &Context = D->getASTContext();
+ int Start = Context.getSourceManager()
+ .getPresumedLoc(D->getBeginLoc())
+ .getLine();
+ int End = Context.getSourceManager()
+ .getPresumedLoc(D->getEndLoc())
+ .getLine();
+
+ return Location(Start, End, File, IsFileInRootDir);
+}
+
void MapASTVisitor::HandleTranslationUnit(ASTContext &Context) {
TraverseDecl(Context.getTranslationUnitDecl());
}
@@ -60,7 +75,7 @@ bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) {
llvm::SmallString<128> File =
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
auto I = serialize::emitInfo(D, getComment(D, D->getASTContext()),
- getLine(D, D->getASTContext()), File,
+ getDeclLocation(D), File,
IsFileInRootDir, CDCtx.PublicOnly);
// A null in place of I indicates that the serializer is skipping this decl
diff --git a/clang-tools-extra/clang-doc/Mapper.h b/clang-tools-extra/clang-doc/Mapper.h
index 75c8e947c8f90..3c3ebdb683911 100644
--- a/clang-tools-extra/clang-doc/Mapper.h
+++ b/clang-tools-extra/clang-doc/Mapper.h
@@ -46,6 +46,9 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
template <typename T> bool mapDecl(const T *D, bool IsDefinition);
int getLine(const NamedDecl *D, const ASTContext &Context) const;
+
+ Location getDeclLocation(const NamedDecl *D) const;
+
llvm::SmallString<128> getFile(const NamedDecl *D, const ASTContext &Context,
StringRef RootDir,
bool &IsFileInRootDir) const;
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 2153b62864ee3..53a62edf3dbcf 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -238,19 +238,20 @@ struct MemberTypeInfo : public FieldTypeInfo {
};
struct Location {
- Location(int LineNumber = 0, StringRef Filename = StringRef(),
+ Location(int StartLineNumber = 0,
+ int EndLineNumber = 0, StringRef Filename = StringRef(),
bool IsFileInRootDir = false)
- : LineNumber(LineNumber), Filename(Filename),
- IsFileInRootDir(IsFileInRootDir) {}
+ : StartLineNumber(StartLineNumber), EndLineNumber(EndLineNumber),
+ Filename(Filename), IsFileInRootDir(IsFileInRootDir) {}
bool operator==(const Location &Other) const {
- return std::tie(LineNumber, Filename) ==
- std::tie(Other.LineNumber, Other.Filename);
+ return std::tie(StartLineNumber, EndLineNumber, Filename) ==
+ std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
}
bool operator!=(const Location &Other) const {
- return std::tie(LineNumber, Filename) !=
- std::tie(Other.LineNumber, Other.Filename);
+ return std::tie(StartLineNumber, Filename) !=
+ std::tie(Other.StartLineNumber, Other.Filename);
}
// This operator is used to sort a vector of Locations.
@@ -258,11 +259,12 @@ struct Location {
// sort is enough, the order is only needed to call std::unique after sorting
// the vector.
bool operator<(const Location &Other) const {
- return std::tie(LineNumber, Filename) <
- std::tie(Other.LineNumber, Other.Filename);
+ return std::tie(StartLineNumber, Filename) <
+ std::tie(Other.StartLineNumber, Other.Filename);
}
- int LineNumber = 0; // Line number of this Location.
+ int StartLineNumber = 0; // Line number of this Location.
+ int EndLineNumber = 0;
SmallString<32> Filename; // File for this Location.
bool IsFileInRootDir = false; // Indicates if file is inside root directory
};
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index f737fc75135a1..aa3dff1d210b5 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -527,22 +527,20 @@ static void populateInfo(Info &I, const T *D, const FullComment *C,
template <typename T>
static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
- int LineNumber, StringRef Filename,
- bool IsFileInRootDir,
+ Location Loc,
bool &IsInAnonymousNamespace) {
populateInfo(I, D, C, IsInAnonymousNamespace);
if (D->isThisDeclarationADefinition())
- I.DefLoc.emplace(LineNumber, Filename, IsFileInRootDir);
+ I.DefLoc = Loc;
else
- I.Loc.emplace_back(LineNumber, Filename, IsFileInRootDir);
+ I.Loc.emplace_back(Loc);
}
static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
- const FullComment *FC, int LineNumber,
- StringRef Filename, bool IsFileInRootDir,
+ const FullComment *FC,
+ Location Loc,
bool &IsInAnonymousNamespace) {
- populateSymbolInfo(I, D, FC, LineNumber, Filename, IsFileInRootDir,
- IsInAnonymousNamespace);
+ populateSymbolInfo(I, D, FC, Loc, IsInAnonymousNamespace);
auto &LO = D->getLangOpts();
I.ReturnType = getTypeInfoForType(D->getReturnType(), LO);
parseParameters(I, D);
@@ -623,8 +621,7 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
// reference, its value is not relevant in here so it's not used
// anywhere besides the function call.
bool IsInAnonymousNamespace;
- populateFunctionInfo(FI, MD, /*FullComment=*/{}, /*LineNumber=*/{},
- /*FileName=*/{}, IsFileInRootDir,
+ populateFunctionInfo(FI, MD, /*FullComment=*/{}, /*Location=*/{},
IsInAnonymousNamespace);
FI.Access =
getFinalAccessSpecifier(BI.Access, MD->getAccessUnsafe());
@@ -642,8 +639,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
- llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
auto I = std::make_unique<NamespaceInfo>();
bool IsInAnonymousNamespace = false;
populateInfo(*I, D, FC, IsInAnonymousNamespace);
@@ -663,12 +660,11 @@ emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
- llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+emitInfo(const RecordDecl *D, const FullComment *FC,
+ Location Loc, bool PublicOnly) {
auto I = std::make_unique<RecordInfo>();
bool IsInAnonymousNamespace = false;
- populateSymbolInfo(*I, D, FC, LineNumber, File, IsFileInRootDir,
- IsInAnonymousNamespace);
+ populateSymbolInfo(*I, D, FC, Loc, IsInAnonymousNamespace);
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
@@ -681,7 +677,7 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
}
// TODO: remove first call to parseBases, that function should be deleted
parseBases(*I, C);
- parseBases(*I, C, IsFileInRootDir, PublicOnly, true);
+ parseBases(*I, C, true, PublicOnly, true);
}
I->Path = getInfoRelativePath(I->Namespace);
@@ -730,30 +726,28 @@ emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
- llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+emitInfo(const FunctionDecl *D, const FullComment *FC,
+ Location Loc, bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
- populateFunctionInfo(Func, D, FC, LineNumber, File, IsFileInRootDir,
- IsInAnonymousNamespace);
+ populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
Func.Access = clang::AccessSpecifier::AS_none;
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
// Info is wrapped in its parent scope so is returned in the second position.
return {nullptr, MakeAndInsertIntoParent<FunctionInfo &&>(std::move(Func))};
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
- llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+emitInfo(const CXXMethodDecl *D, const FullComment *FC,
+ Location Loc, bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
- populateFunctionInfo(Func, D, FC, LineNumber, File, IsFileInRootDir,
- IsInAnonymousNamespace);
+ populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
Func.IsMethod = true;
const NamedDecl *Parent = nullptr;
@@ -774,18 +768,21 @@ emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
+
TypedefInfo Info;
-
+ ASTContext& Context = D->getASTContext();
bool IsInAnonymousNamespace = false;
populateInfo(Info, D, FC, IsInAnonymousNamespace);
+
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
- Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
+
+ Info.DefLoc = Loc;
auto &LO = D->getLangOpts();
Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
+
if (Info.Underlying.Type.Name.empty()) {
// Typedef for an unnamed type. This is like "typedef struct { } Foo;"
// The record serializer explicitly checks for this syntax and constructs
@@ -793,7 +790,13 @@ emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
return {};
}
Info.IsUsing = false;
-
+ if (RawComment *Comment = D->getASTContext().getRawCommentForDeclNoCache(D)) {
+ Comment->setAttached();
+ if (comments::FullComment *Fc = Comment->parse(Context, nullptr, D)) {
+ Info.Description.emplace_back();
+ parseFullComment(Fc, Info.Description.back());
+ }
+ }
// Info is wrapped in its parent scope so is returned in the second position.
return {nullptr, MakeAndInsertIntoParent<TypedefInfo &&>(std::move(Info))};
}
@@ -801,8 +804,8 @@ emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
// A type alias is a C++ "using" declaration for a type. It gets mapped to a
// TypedefInfo with the IsUsing flag set.
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+emitInfo(const TypeAliasDecl *D, const FullComment *FC,
+ Location Loc, bool PublicOnly) {
TypedefInfo Info;
bool IsInAnonymousNamespace = false;
@@ -810,7 +813,7 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
- Info.DefLoc.emplace(LineNumber, File, IsFileInRootDir);
+ Info.DefLoc = Loc;
auto &LO = D->getLangOpts();
Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
Info.IsUsing = true;
@@ -820,15 +823,15 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const EnumDecl *D, const FullComment *FC, int LineNumber,
- llvm::StringRef File, bool IsFileInRootDir, bool PublicOnly) {
+emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
EnumInfo Enum;
bool IsInAnonymousNamespace = false;
- populateSymbolInfo(Enum, D, FC, LineNumber, File, IsFileInRootDir,
- IsInAnonymousNamespace);
+ populateSymbolInfo(Enum, D, FC, Loc, IsInAnonymousNamespace);
+
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
Enum.Scoped = D->isScoped();
if (D->isFixed()) {
auto Name = D->getIntegerType().getAsString();
>From 7dd8ebe47b2a7669fdb9dbd2a5369b487831389f Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Mon, 7 Apr 2025 15:41:29 -0400
Subject: [PATCH 2/5] add number
---
clang-tools-extra/clang-doc/Mapper.cpp | 3 +-
clang-tools-extra/clang-doc/Serialize.h | 28 +++++++++----------
clang-tools-extra/clang-doc/YAMLGenerator.cpp | 2 +-
3 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index bdcf0c842b98f..4dadff41e96e8 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -75,8 +75,7 @@ bool MapASTVisitor::mapDecl(const T *D, bool IsDefinition) {
llvm::SmallString<128> File =
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
auto I = serialize::emitInfo(D, getComment(D, D->getASTContext()),
- getDeclLocation(D), File,
- IsFileInRootDir, CDCtx.PublicOnly);
+ getDeclLocation(D), CDCtx.PublicOnly);
// A null in place of I indicates that the serializer is skipping this decl
// for some reason (e.g. we're only reporting public decls).
diff --git a/clang-tools-extra/clang-doc/Serialize.h b/clang-tools-extra/clang-doc/Serialize.h
index 4e203ca7891ac..8874299e9af9e 100644
--- a/clang-tools-extra/clang-doc/Serialize.h
+++ b/clang-tools-extra/clang-doc/Serialize.h
@@ -37,32 +37,32 @@ namespace serialize {
// its parent scope. For NamespaceDecl and RecordDecl both elements are not
// nullptr.
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const NamespaceDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly);
+emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const RecordDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly);
+emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const EnumDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly);
+emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly);
+emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const CXXMethodDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly);
+emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypedefDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly);
+emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypeAliasDecl *D, const FullComment *FC, int LineNumber,
- StringRef File, bool IsFileInRootDir, bool PublicOnly);
+emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly);
// Function to hash a given USR value for storage.
// As USRs (Unified Symbol Resolution) could be large, especially for functions
diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
index ffabd2fd82229..d990dd4b647e8 100644
--- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
@@ -169,7 +169,7 @@ static void CommentInfoMapping(IO &IO, CommentInfo &I) {
template <> struct MappingTraits<Location> {
static void mapping(IO &IO, Location &Loc) {
- IO.mapOptional("LineNumber", Loc.LineNumber, 0);
+ IO.mapOptional("LineNumber", Loc.StartLineNumber, 0);
IO.mapOptional("Filename", Loc.Filename, SmallString<32>());
}
};
>From af43032429cef3ae328af88f5893bbc0f46eadee Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Wed, 9 Apr 2025 17:01:43 -0400
Subject: [PATCH 3/5] fix compilation error
---
clang-tools-extra/clang-doc/BitcodeReader.cpp | 2 +-
clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 ++-
clang-tools-extra/clang-doc/HTMLGenerator.cpp | 8 +++++---
clang-tools-extra/clang-doc/MDGenerator.cpp | 5 +++--
4 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index c9f588303fd08..2334521db2860 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -135,7 +135,7 @@ llvm::Error decodeRecord(const Record &R,
if (R[0] > INT_MAX)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"integer too large to parse");
- Field.emplace_back((int)R[0], Blob, (bool)R[1]);
+ Field.emplace_back((int)R[0], (int)R[1], Blob, (bool)R[2]);
return llvm::Error::success();
}
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index 8230097c0726d..402386443dbc0 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -355,7 +355,8 @@ void ClangDocBitcodeWriter::emitRecord(const Location &Loc, RecordId ID) {
if (!prepRecordData(ID, true))
return;
// FIXME: Assert that the line number is of the appropriate size.
- Record.push_back(Loc.LineNumber);
+ Record.push_back(Loc.StartLineNumber);
+ Record.push_back(Loc.EndLineNumber);
assert(Loc.Filename.size() < (1U << BitCodeConstants::StringLengthSize));
Record.push_back(Loc.IsFileInRootDir);
Record.push_back(Loc.Filename.size());
diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index f559933fc2283..cf998a4948369 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -495,7 +495,7 @@ static std::unique_ptr<TagNode> writeSourceFileRef(const ClangDocContext &CDCtx,
if (!L.IsFileInRootDir && !CDCtx.RepositoryUrl)
return std::make_unique<TagNode>(
- HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) +
+ HTMLTag::TAG_P, "Defined at line " + std::to_string(L.StartLineNumber) +
" of file " + L.Filename);
SmallString<128> FileURL(CDCtx.RepositoryUrl.value_or(""));
@@ -513,12 +513,14 @@ static std::unique_ptr<TagNode> writeSourceFileRef(const ClangDocContext &CDCtx,
auto Node = std::make_unique<TagNode>(HTMLTag::TAG_P);
Node->Children.emplace_back(std::make_unique<TextNode>("Defined at line "));
auto LocNumberNode =
- std::make_unique<TagNode>(HTMLTag::TAG_A, std::to_string(L.LineNumber));
+ std::make_unique<TagNode>(HTMLTag::TAG_A,
+ std::to_string(L.StartLineNumber));
// The links to a specific line in the source code use the github /
// googlesource notation so it won't work for all hosting pages.
LocNumberNode->Attributes.emplace_back(
"href", formatv("{0}#{1}{2}", FileURL,
- CDCtx.RepositoryLinePrefix.value_or(""), L.LineNumber));
+ CDCtx.RepositoryLinePrefix.value_or(""),
+ L.StartLineNumber));
Node->Children.emplace_back(std::move(LocNumberNode));
Node->Children.emplace_back(std::make_unique<TextNode>(" of file "));
auto LocFileNode = std::make_unique<TagNode>(
diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp
index 5c782fcc10da5..ac7e20b27db23 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -56,12 +56,13 @@ static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L,
raw_ostream &OS) {
if (!CDCtx.RepositoryUrl) {
- OS << "*Defined at " << L.Filename << "#" << std::to_string(L.LineNumber)
+ OS << "*Defined at " << L.Filename << "#"
+ << std::to_string(L.StartLineNumber)
<< "*";
} else {
OS << formatv("*Defined at [#{0}{1}{2}](#{0}{1}{3})*",
- CDCtx.RepositoryLinePrefix.value_or(""), L.LineNumber,
+ CDCtx.RepositoryLinePrefix.value_or(""), L.StartLineNumber,
L.Filename, *CDCtx.RepositoryUrl);
}
OS << "\n\n";
>From 7563ec536d9698ebec57e070cc1a363f2b8d05e5 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Wed, 9 Apr 2025 17:19:32 -0400
Subject: [PATCH 4/5] clang-format
---
clang-tools-extra/clang-doc/BitcodeReader.cpp | 2 +-
clang-tools-extra/clang-doc/Mapper.cpp | 11 ++---
clang-tools-extra/clang-doc/Mapper.h | 4 +-
clang-tools-extra/clang-doc/Representation.h | 7 ++-
clang-tools-extra/clang-doc/Serialize.cpp | 48 +++++++++----------
clang-tools-extra/clang-doc/Serialize.h | 14 +++---
6 files changed, 40 insertions(+), 46 deletions(-)
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 2334521db2860..d7233459bdd61 100644
--- a/clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -85,7 +85,7 @@ llvm::Error decodeRecord(const Record &R, std::optional<Location> &Field,
if (R[0] > INT_MAX)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"integer too large to parse");
- Field.emplace((int)R[0], (int) R[1], Blob, (bool)R[2]);
+ Field.emplace((int)R[0], (int)R[1], Blob, (bool)R[2]);
return llvm::Error::success();
}
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index 4dadff41e96e8..c210338f7863f 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -33,13 +33,10 @@ Location MapASTVisitor::getDeclLocation(const NamedDecl *D) const {
llvm::SmallString<128> File =
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir);
ASTContext &Context = D->getASTContext();
- int Start = Context.getSourceManager()
- .getPresumedLoc(D->getBeginLoc())
- .getLine();
- int End = Context.getSourceManager()
- .getPresumedLoc(D->getEndLoc())
- .getLine();
-
+ int Start =
+ Context.getSourceManager().getPresumedLoc(D->getBeginLoc()).getLine();
+ int End = Context.getSourceManager().getPresumedLoc(D->getEndLoc()).getLine();
+
return Location(Start, End, File, IsFileInRootDir);
}
diff --git a/clang-tools-extra/clang-doc/Mapper.h b/clang-tools-extra/clang-doc/Mapper.h
index 3c3ebdb683911..36322ea2bfb77 100644
--- a/clang-tools-extra/clang-doc/Mapper.h
+++ b/clang-tools-extra/clang-doc/Mapper.h
@@ -46,9 +46,9 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
template <typename T> bool mapDecl(const T *D, bool IsDefinition);
int getLine(const NamedDecl *D, const ASTContext &Context) const;
-
+
Location getDeclLocation(const NamedDecl *D) const;
-
+
llvm::SmallString<128> getFile(const NamedDecl *D, const ASTContext &Context,
StringRef RootDir,
bool &IsFileInRootDir) const;
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 53a62edf3dbcf..eebf0c799c1f0 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -238,9 +238,8 @@ struct MemberTypeInfo : public FieldTypeInfo {
};
struct Location {
- Location(int StartLineNumber = 0,
- int EndLineNumber = 0, StringRef Filename = StringRef(),
- bool IsFileInRootDir = false)
+ Location(int StartLineNumber = 0, int EndLineNumber = 0,
+ StringRef Filename = StringRef(), bool IsFileInRootDir = false)
: StartLineNumber(StartLineNumber), EndLineNumber(EndLineNumber),
Filename(Filename), IsFileInRootDir(IsFileInRootDir) {}
@@ -263,7 +262,7 @@ struct Location {
std::tie(Other.StartLineNumber, Other.Filename);
}
- int StartLineNumber = 0; // Line number of this Location.
+ int StartLineNumber = 0; // Line number of this Location.
int EndLineNumber = 0;
SmallString<32> Filename; // File for this Location.
bool IsFileInRootDir = false; // Indicates if file is inside root directory
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index aa3dff1d210b5..ce21a9bc8c109 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -527,8 +527,7 @@ static void populateInfo(Info &I, const T *D, const FullComment *C,
template <typename T>
static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
- Location Loc,
- bool &IsInAnonymousNamespace) {
+ Location Loc, bool &IsInAnonymousNamespace) {
populateInfo(I, D, C, IsInAnonymousNamespace);
if (D->isThisDeclarationADefinition())
I.DefLoc = Loc;
@@ -537,8 +536,7 @@ static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
}
static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
- const FullComment *FC,
- Location Loc,
+ const FullComment *FC, Location Loc,
bool &IsInAnonymousNamespace) {
populateSymbolInfo(I, D, FC, Loc, IsInAnonymousNamespace);
auto &LO = D->getLangOpts();
@@ -569,7 +567,7 @@ static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D) {
assert(D && "Expect non-null FieldDecl in populateMemberTypeInfo");
- ASTContext& Context = D->getASTContext();
+ ASTContext &Context = D->getASTContext();
// TODO investigate whether we can use ASTContext::getCommentForDecl instead
// of this logic. See also similar code in Mapper.cpp.
RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
@@ -639,7 +637,7 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly) {
auto I = std::make_unique<NamespaceInfo>();
bool IsInAnonymousNamespace = false;
@@ -660,8 +658,8 @@ emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const RecordDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
auto I = std::make_unique<RecordInfo>();
bool IsInAnonymousNamespace = false;
populateSymbolInfo(*I, D, FC, Loc, IsInAnonymousNamespace);
@@ -726,28 +724,28 @@ emitInfo(const RecordDecl *D, const FullComment *FC,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const FunctionDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
Func.Access = clang::AccessSpecifier::AS_none;
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
// Info is wrapped in its parent scope so is returned in the second position.
return {nullptr, MakeAndInsertIntoParent<FunctionInfo &&>(std::move(Func))};
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const CXXMethodDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
Func.IsMethod = true;
const NamedDecl *Parent = nullptr;
@@ -768,21 +766,21 @@ emitInfo(const CXXMethodDecl *D, const FullComment *FC,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly) {
-
+
TypedefInfo Info;
- ASTContext& Context = D->getASTContext();
+ ASTContext &Context = D->getASTContext();
bool IsInAnonymousNamespace = false;
populateInfo(Info, D, FC, IsInAnonymousNamespace);
-
+
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
Info.DefLoc = Loc;
auto &LO = D->getLangOpts();
Info.Underlying = getTypeInfoForType(D->getUnderlyingType(), LO);
-
+
if (Info.Underlying.Type.Name.empty()) {
// Typedef for an unnamed type. This is like "typedef struct { } Foo;"
// The record serializer explicitly checks for this syntax and constructs
@@ -804,8 +802,8 @@ emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
// A type alias is a C++ "using" declaration for a type. It gets mapped to a
// TypedefInfo with the IsUsing flag set.
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypeAliasDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
TypedefInfo Info;
bool IsInAnonymousNamespace = false;
@@ -823,15 +821,15 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly) {
EnumInfo Enum;
bool IsInAnonymousNamespace = false;
populateSymbolInfo(Enum, D, FC, Loc, IsInAnonymousNamespace);
-
+
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
Enum.Scoped = D->isScoped();
if (D->isFixed()) {
auto Name = D->getIntegerType().getAsString();
diff --git a/clang-tools-extra/clang-doc/Serialize.h b/clang-tools-extra/clang-doc/Serialize.h
index 8874299e9af9e..bdf969aa56b97 100644
--- a/clang-tools-extra/clang-doc/Serialize.h
+++ b/clang-tools-extra/clang-doc/Serialize.h
@@ -37,31 +37,31 @@ namespace serialize {
// its parent scope. For NamespaceDecl and RecordDecl both elements are not
// nullptr.
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
// Function to hash a given USR value for storage.
>From 93f30bca2b5902f128824ee3a8ba9e1e78c0be09 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Wed, 9 Apr 2025 17:26:37 -0400
Subject: [PATCH 5/5] clang-format
---
clang-tools-extra/clang-doc/HTMLGenerator.cpp | 11 +++++------
clang-tools-extra/clang-doc/MDGenerator.cpp | 5 ++---
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index cf998a4948369..b9be8ceb3f66c 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -512,15 +512,14 @@ static std::unique_ptr<TagNode> writeSourceFileRef(const ClangDocContext &CDCtx,
llvm::sys::path::Style::windows));
auto Node = std::make_unique<TagNode>(HTMLTag::TAG_P);
Node->Children.emplace_back(std::make_unique<TextNode>("Defined at line "));
- auto LocNumberNode =
- std::make_unique<TagNode>(HTMLTag::TAG_A,
- std::to_string(L.StartLineNumber));
+ auto LocNumberNode = std::make_unique<TagNode>(
+ HTMLTag::TAG_A, std::to_string(L.StartLineNumber));
// The links to a specific line in the source code use the github /
// googlesource notation so it won't work for all hosting pages.
LocNumberNode->Attributes.emplace_back(
- "href", formatv("{0}#{1}{2}", FileURL,
- CDCtx.RepositoryLinePrefix.value_or(""),
- L.StartLineNumber));
+ "href",
+ formatv("{0}#{1}{2}", FileURL, CDCtx.RepositoryLinePrefix.value_or(""),
+ L.StartLineNumber));
Node->Children.emplace_back(std::move(LocNumberNode));
Node->Children.emplace_back(std::make_unique<TextNode>(" of file "));
auto LocFileNode = std::make_unique<TagNode>(
diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp
index ac7e20b27db23..ce147de5e54d8 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -56,9 +56,8 @@ static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L,
raw_ostream &OS) {
if (!CDCtx.RepositoryUrl) {
- OS << "*Defined at " << L.Filename << "#"
- << std::to_string(L.StartLineNumber)
- << "*";
+ OS << "*Defined at " << L.Filename << "#"
+ << std::to_string(L.StartLineNumber) << "*";
} else {
OS << formatv("*Defined at [#{0}{1}{2}](#{0}{1}{3})*",
More information about the cfe-commits
mailing list