-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang-doc] Add Start and End Line Numbers #135081
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang-tools-extra Author: None (PeterChou1) ChangesSplit from #133161 This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This is will be used by the mustache backend to generate line ranges Full diff: https://github.com/llvm/llvm-project/pull/135081.diff 8 Files Affected:
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..4dadff41e96e8 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,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()),
- getLine(D, D->getASTContext()), 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/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();
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>());
}
};
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly good, modulo a few small issues.
@@ -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]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're touching these, lets use static_cast<T>
. If C style casts are prevalent in the rest of the file, we should address those separately.
@@ -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]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
@@ -681,7 +675,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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this always true? also /*param_name=*/
} | ||
|
||
int LineNumber = 0; // Line number of this Location. | ||
int StartLineNumber = 0; // Line number of this Location. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stale comments?
seems like some tests need to be updated w/ the new interface. |
getFile(D, D->getASTContext(), CDCtx.SourceRoot, IsFileInRootDir); | ||
ASTContext &Context = D->getASTContext(); | ||
int Start = | ||
Context.getSourceManager().getPresumedLoc(D->getBeginLoc()).getLine(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Extracting out a source manager reference would make the difference between these two lines clearer.
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. | ||
// No specific order (attributes more important than others) is required. Any | ||
// sort is enough, the order is only needed to call std::unique after sorting | ||
// the vector. | ||
bool operator<(const Location &Other) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, from the comment, it appears that this need to be a strict weak order that respects the equality constraint given above. Accordingly, this should also include EndLineNumber.
} | ||
|
||
bool operator!=(const Location &Other) const { | ||
return std::tie(LineNumber, Filename) != | ||
std::tie(Other.LineNumber, Other.Filename); | ||
return std::tie(StartLineNumber, Filename) != |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has gone out of sync with ==. Maybe it would be better to implement this as return !(*this == Other)
?
any progress here? |
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges. Based on the orginal patch in #135081. Co-author: Paul Kirth <[email protected]> Co-authored-by: PeterChou1 <[email protected]>
closing, since we landed #137732 |
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges. Based on the orginal patch in llvm#135081. Co-author: Paul Kirth <[email protected]> Co-authored-by: PeterChou1 <[email protected]>
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges. Based on the orginal patch in llvm#135081. Co-author: Paul Kirth <[email protected]> Co-authored-by: PeterChou1 <[email protected]>
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges. Based on the orginal patch in llvm#135081. Co-author: Paul Kirth <[email protected]> Co-authored-by: PeterChou1 <[email protected]>
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges. Based on the orginal patch in llvm#135081. Co-author: Paul Kirth <[email protected]> Co-authored-by: PeterChou1 <[email protected]>
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges. Based on the orginal patch in llvm#135081. Co-author: Paul Kirth <[email protected]> Co-authored-by: PeterChou1 <[email protected]>
Split from #133161
This patch adds start and end line numbers to clang-doc. Currently clang-doc only encodes the start line numbers of records, struct, etc. This patch adds start and end line number to clang-doc bitcode which is passed to the generator. This will be used by the mustache backend to generate line ranges