418 changes: 418 additions & 0 deletions .github/workflows/commit-access-review.py

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions .github/workflows/commit-access-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Commit Access Review

on:
workflow_dispatch:
schedule:
# * is a special character in YAML so you have to quote this string
- cron: '0 7 1 * *'

permissions:
contents: read

jobs:
commit-access-review:
if: github.repository_owner == 'llvm'
runs-on: ubuntu-22.04
steps:
- name: Fetch LLVM sources
uses: actions/checkout@v4

- name: Install dependencies
run: |
pip install --require-hashes -r ./llvm/utils/git/requirements.txt
- name: Run Script
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TASKS_USER_TOKEN }}
run: |
python3 .github/workflows/commit-access-review.py $GITHUB_TOKEN
- name: Upload Triage List
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0
with:
name: triagers
path: triagers.log
1 change: 1 addition & 0 deletions .github/workflows/libcxx-build-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ jobs:
'generic-no-experimental',
'generic-no-filesystem',
'generic-no-localization',
'generic-no-terminal',
'generic-no-random_device',
'generic-no-threads',
'generic-no-tzdb',
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2502,7 +2502,7 @@ void BinaryFunction::annotateCFIState() {
}
}

if (!StateStack.empty()) {
if (opts::Verbosity >= 1 && !StateStack.empty()) {
BC.errs() << "BOLT-WARNING: non-empty CFI stack at the end of " << *this
<< '\n';
}
Expand Down
3 changes: 2 additions & 1 deletion bolt/lib/Core/BinaryFunctionProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ void BinaryFunction::inferFallThroughCounts() {
if (SuccBI.Count == 0) {
SuccBI.Count = Inferred;
SuccBI.MispredictedCount = BinaryBasicBlock::COUNT_INFERRED;
Succ->ExecutionCount += Inferred;
Succ->ExecutionCount =
std::max(Succ->getKnownExecutionCount(), Inferred);
}
}
}
Expand Down
45 changes: 45 additions & 0 deletions bolt/test/X86/infer-fall-throughs.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## Test that infer-fall-throughs would correctly infer the wrong fall-through
## edge count in the example

# RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.o
# RUN: link_fdata %s %t.o %t.fdata
# RUN: llvm-strip --strip-unneeded %t.o
# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q
# RUN: llvm-bolt %t.exe -o %t.bolt \
# RUN: --print-estimate-edge-counts --data=%t.fdata \
# RUN: 2>&1 | FileCheck --check-prefix=WITHOUTINFERENCE %s
# RUN: llvm-bolt %t.exe -o %t.bolt --infer-fall-throughs \
# RUN: --print-estimate-edge-counts --data=%t.fdata \
# RUN: 2>&1 | FileCheck --check-prefix=CORRECTINFERENCE %s


# WITHOUTINFERENCE: Binary Function "main" after estimate-edge-counts
# WITHOUTINFERENCE: {{^\.Ltmp0}}
# WITHOUTINFERENCE: Successors: .Ltmp1 (mispreds: 0, count: 10), .LFT0 (mispreds: 0, count: 0)
# WITHOUTINFERENCE: {{^\.LFT0}}
# WITHOUTINFERENCE: Exec Count : 490

# CORRECTINFERENCE: Binary Function "main" after estimate-edge-counts
# CORRECTINFERENCE: {{^\.Ltmp0}}
# CORRECTINFERENCE: Successors: .Ltmp1 (mispreds: 0, count: 10), .LFT0 (inferred count: 490)
# CORRECTINFERENCE: {{^\.LFT0}}
# CORRECTINFERENCE: Exec Count : 490


.globl main
.type main, @function
main:
LLmain_LLstart:
jmp LLstart
# FDATA: 1 main #LLmain_LLstart# 1 main #LLstart# 0 500
LLstart:
jge LLexit
# FDATA: 1 main #LLstart# 1 main #LLexit# 0 10
# FDATA: 1 main #LLstart# 1 main #LLmore# 0 0
LLmore:
movl $5, %eax
# FDATA: 1 main #LLmore# 1 main #LLexit# 0 490
LLexit:
ret
.LLmain_end:
.size main, .LLmain_end-main
4 changes: 4 additions & 0 deletions clang-tools-extra/clang-doc/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,10 @@ template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
return &I->Description.emplace_back();
}

template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumValueInfo *I) {
return &I->Description.emplace_back();
}

template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
I->Children.emplace_back(std::make_unique<CommentInfo>());
return I->Children.back().get();
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clang-doc/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ void ClangDocBitcodeWriter::emitBlock(const EnumValueInfo &I) {
emitRecord(I.Name, ENUM_VALUE_NAME);
emitRecord(I.Value, ENUM_VALUE_VALUE);
emitRecord(I.ValueExpr, ENUM_VALUE_EXPR);
for (const auto &CI : I.Description)
emitBlock(CI);
}

void ClangDocBitcodeWriter::emitBlock(const RecordInfo &I) {
Expand Down
100 changes: 84 additions & 16 deletions clang-tools-extra/clang-doc/HTMLGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ class HTMLTag {
TAG_SPAN,
TAG_TITLE,
TAG_UL,
TAG_TABLE,
TAG_THEAD,
TAG_TBODY,
TAG_TR,
TAG_TD,
TAG_TH
};

HTMLTag() = default;
Expand Down Expand Up @@ -133,6 +139,12 @@ bool HTMLTag::isSelfClosing() const {
case HTMLTag::TAG_SPAN:
case HTMLTag::TAG_TITLE:
case HTMLTag::TAG_UL:
case HTMLTag::TAG_TABLE:
case HTMLTag::TAG_THEAD:
case HTMLTag::TAG_TBODY:
case HTMLTag::TAG_TR:
case HTMLTag::TAG_TD:
case HTMLTag::TAG_TH:
return false;
}
llvm_unreachable("Unhandled HTMLTag::TagType");
Expand Down Expand Up @@ -174,6 +186,18 @@ StringRef HTMLTag::toString() const {
return "title";
case HTMLTag::TAG_UL:
return "ul";
case HTMLTag::TAG_TABLE:
return "table";
case HTMLTag::TAG_THEAD:
return "thead";
case HTMLTag::TAG_TBODY:
return "tbody";
case HTMLTag::TAG_TR:
return "tr";
case HTMLTag::TAG_TD:
return "td";
case HTMLTag::TAG_TH:
return "th";
}
llvm_unreachable("Unhandled HTMLTag::TagType");
}
Expand Down Expand Up @@ -377,10 +401,27 @@ genEnumMembersBlock(const llvm::SmallVector<EnumValueInfo, 4> &Members) {
if (Members.empty())
return nullptr;

auto List = std::make_unique<TagNode>(HTMLTag::TAG_UL);
for (const auto &M : Members)
List->Children.emplace_back(
std::make_unique<TagNode>(HTMLTag::TAG_LI, M.Name));
auto List = std::make_unique<TagNode>(HTMLTag::TAG_TBODY);

for (const auto &M : Members) {
auto TRNode = std::make_unique<TagNode>(HTMLTag::TAG_TR);
TRNode->Children.emplace_back(
std::make_unique<TagNode>(HTMLTag::TAG_TD, M.Name));
// Use user supplied value if it exists, otherwise use the value
if (!M.ValueExpr.empty()) {
TRNode->Children.emplace_back(
std::make_unique<TagNode>(HTMLTag::TAG_TD, M.ValueExpr));
} else {
TRNode->Children.emplace_back(
std::make_unique<TagNode>(HTMLTag::TAG_TD, M.Value));
}
if (!M.Description.empty()) {
auto TD = std::make_unique<TagNode>(HTMLTag::TAG_TD);
TD->Children.emplace_back(genHTML(M.Description));
TRNode->Children.emplace_back(std::move(TD));
}
List->Children.emplace_back(std::move(TRNode));
}
return List;
}

Expand Down Expand Up @@ -624,7 +665,7 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) {
}
return std::move(FullComment);
}

if (I.Kind == "ParagraphComment") {
auto ParagraphComment = std::make_unique<TagNode>(HTMLTag::TAG_P);
for (const auto &Child : I.Children) {
Expand All @@ -637,6 +678,19 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) {
return std::move(ParagraphComment);
}

if (I.Kind == "BlockCommandComment") {
auto BlockComment = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
BlockComment->Children.emplace_back(
std::make_unique<TagNode>(HTMLTag::TAG_DIV, I.Name));
for (const auto &Child : I.Children) {
std::unique_ptr<HTMLNode> Node = genHTML(*Child);
if (Node)
BlockComment->Children.emplace_back(std::move(Node));
}
if (BlockComment->Children.empty())
return nullptr;
return std::move(BlockComment);
}
if (I.Kind == "TextComment") {
if (I.Text == "")
return nullptr;
Expand All @@ -658,22 +712,36 @@ static std::vector<std::unique_ptr<TagNode>>
genHTML(const EnumInfo &I, const ClangDocContext &CDCtx) {
std::vector<std::unique_ptr<TagNode>> Out;
std::string EnumType = I.Scoped ? "enum class " : "enum ";

Out.emplace_back(
std::make_unique<TagNode>(HTMLTag::TAG_H3, EnumType + I.Name));
Out.back()->Attributes.emplace_back("id",
llvm::toHex(llvm::toStringRef(I.USR)));

std::unique_ptr<TagNode> Node = genEnumMembersBlock(I.Members);
if (Node)
Out.emplace_back(std::move(Node));
// Determine if enum members have comments attached
bool HasComments = std::any_of(
I.Members.begin(), I.Members.end(),
[](const EnumValueInfo &M) { return !M.Description.empty(); });
std::unique_ptr<TagNode> Table =
std::make_unique<TagNode>(HTMLTag::TAG_TABLE);
std::unique_ptr<TagNode> THead =
std::make_unique<TagNode>(HTMLTag::TAG_THEAD);
std::unique_ptr<TagNode> TRow = std::make_unique<TagNode>(HTMLTag::TAG_TR);
std::unique_ptr<TagNode> TD =
std::make_unique<TagNode>(HTMLTag::TAG_TH, EnumType + I.Name);
// Span 3 columns if enum has comments
TD->Attributes.emplace_back("colspan", HasComments ? "3" : "2");

Table->Attributes.emplace_back("id", llvm::toHex(llvm::toStringRef(I.USR)));
TRow->Children.emplace_back(std::move(TD));
THead->Children.emplace_back(std::move(TRow));
Table->Children.emplace_back(std::move(THead));

if (std::unique_ptr<TagNode> Node = genEnumMembersBlock(I.Members))
Table->Children.emplace_back(std::move(Node));

Out.emplace_back(std::move(Table));

if (I.DefLoc) {
if (!CDCtx.RepositoryUrl)
Out.emplace_back(writeFileDefinition(*I.DefLoc));
else
Out.emplace_back(writeFileDefinition(
*I.DefLoc, StringRef{*CDCtx.RepositoryUrl}));
Out.emplace_back(
writeFileDefinition(*I.DefLoc, StringRef{*CDCtx.RepositoryUrl}));
}

std::string Description;
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-doc/Representation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ void SymbolInfo::merge(SymbolInfo &&Other) {
}

NamespaceInfo::NamespaceInfo(SymbolID USR, StringRef Name, StringRef Path)
: Info(InfoType::IT_namespace, USR, Name, Path) {}
: Info(InfoType::IT_namespace, USR, Name, Path) {}

void NamespaceInfo::merge(NamespaceInfo &&Other) {
assert(mergeable(Other));
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clang-doc/Representation.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ struct EnumValueInfo {
// Stores the user-supplied initialization expression for this enumeration
// constant. This will be empty for implicit enumeration values.
SmallString<16> ValueExpr;

std::vector<CommentInfo> Description; /// Comment description of this field.
};

// TODO: Expand to allow for documenting templating.
Expand Down
16 changes: 13 additions & 3 deletions clang-tools-extra/clang-doc/Serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,20 @@ static void parseEnumerators(EnumInfo &I, const EnumDecl *D) {
std::string ValueExpr;
if (const Expr *InitExpr = E->getInitExpr())
ValueExpr = getSourceCode(D, InitExpr->getSourceRange());

SmallString<16> ValueStr;
E->getInitVal().toString(ValueStr);
I.Members.emplace_back(E->getNameAsString(), ValueStr, ValueExpr);
I.Members.emplace_back(E->getNameAsString(), ValueStr.str(), ValueExpr);
ASTContext &Context = E->getASTContext();
if (RawComment *Comment =
E->getASTContext().getRawCommentForDeclNoCache(E)) {
CommentInfo CInfo;
Comment->setAttached();
if (comments::FullComment *Fc = Comment->parse(Context, nullptr, E)) {
EnumValueInfo &Member = I.Members.back();
Member.Description.emplace_back();
parseFullComment(Fc, Member.Description.back());
}
}
}
}

Expand Down Expand Up @@ -566,7 +576,7 @@ static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D) {
return;

Comment->setAttached();
if (comments::FullComment* fc = Comment->parse(Context, nullptr, D)) {
if (comments::FullComment *fc = Comment->parse(Context, nullptr, D)) {
I.Description.emplace_back();
parseFullComment(fc, I.Description.back());
}
Expand Down
6 changes: 3 additions & 3 deletions clang-tools-extra/clang-tidy/modernize/UseStdFormatCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ void UseStdFormatCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
callExpr(argumentCountAtLeast(1),
hasArgument(0, stringLiteral(isOrdinary())),
callee(functionDecl(unless(cxxMethodDecl()),
matchers::matchesAnyListedName(
callee(functionDecl(matchers::matchesAnyListedName(
StrFormatLikeFunctions))
.bind("func_decl")))
.bind("strformat"),
Expand Down Expand Up @@ -93,7 +92,8 @@ void UseStdFormatCheck::check(const MatchFinder::MatchResult &Result) {
diag(StrFormatCall->getBeginLoc(), "use '%0' instead of %1")
<< ReplacementFormatFunction << OldFunction->getIdentifier();
Diag << FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(StrFormatCall->getSourceRange()),
CharSourceRange::getTokenRange(StrFormatCall->getExprLoc(),
StrFormatCall->getEndLoc()),
ReplacementFormatFunction);
Converter.applyFixes(Diag, *Result.SourceManager);

Expand Down
8 changes: 3 additions & 5 deletions clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
unusedReturnValue(
callExpr(argumentCountAtLeast(1),
hasArgument(0, stringLiteral(isOrdinary())),
callee(functionDecl(unless(cxxMethodDecl()),
matchers::matchesAnyListedName(
callee(functionDecl(matchers::matchesAnyListedName(
PrintfLikeFunctions))
.bind("func_decl")))
.bind("printf")),
Expand All @@ -112,8 +111,7 @@ void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
unusedReturnValue(
callExpr(argumentCountAtLeast(2),
hasArgument(1, stringLiteral(isOrdinary())),
callee(functionDecl(unless(cxxMethodDecl()),
matchers::matchesAnyListedName(
callee(functionDecl(matchers::matchesAnyListedName(
FprintfLikeFunctions))
.bind("func_decl")))
.bind("fprintf")),
Expand Down Expand Up @@ -152,7 +150,7 @@ void UseStdPrintCheck::check(const MatchFinder::MatchResult &Result) {
<< ReplacementFunction << OldFunction->getIdentifier();

Diag << FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(PrintfCall->getBeginLoc(),
CharSourceRange::getTokenRange(PrintfCall->getExprLoc(),
PrintfCall->getEndLoc()),
ReplacementFunction);
Converter.applyFixes(Diag, *Result.SourceManager);
Expand Down
4 changes: 2 additions & 2 deletions clang-tools-extra/clangd/ParsedAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
auto Action = std::make_unique<ClangdFrontendAction>();
const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
if (!Action->BeginSourceFile(*Clang, MainInput)) {
log("BeginSourceFile() failed when building AST for {0}",
MainInput.getFile());
elog("BeginSourceFile() failed when building AST for {0}",
MainInput.getFile());
return std::nullopt;
}
// If we saw an include guard in the preamble section of the main file,
Expand Down
10 changes: 9 additions & 1 deletion clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,17 @@ New check aliases
Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^

- Improved :doc:`modernize-use-std-format
<clang-tidy/checks/modernize/use-std-format>` check to support replacing
member function calls too.

- Improved :doc:`modernize-use-std-print
<clang-tidy/checks/modernize/use-std-print>` check to support replacing
member function calls too.

- Improved :doc:`readability-redundant-smartptr-get
<clang-tidy/checks/readability/redundant-smartptr-get>` check to
remove `->`, when reduntant `get()` is removed.
remove `->`, when redundant `get()` is removed.

Removed checks
^^^^^^^^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ Options
A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter contains the
printf-style format string and the arguments to be formatted follow
immediately afterwards. The default value for this option is
`absl::StrFormat`.
immediately afterwards. Qualified member function names are supported,
but the replacement function name must be unqualified. The default value
for this option is `absl::StrFormat`.

.. option:: ReplacementFormatFunction

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,22 @@ Options
A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter contains the
printf-style format string and the arguments to be formatted follow
immediately afterwards. If neither this option nor
`FprintfLikeFunctions` are set then the default value for this option
is `printf; absl::PrintF`, otherwise it is empty.
immediately afterwards. Qualified member function names are supported,
but the replacement function name must be unqualified. If neither this
option nor `FprintfLikeFunctions` are set then the default value for
this option is `printf; absl::PrintF`, otherwise it is empty.


.. option:: FprintfLikeFunctions

A semicolon-separated list of (fully qualified) function names to
replace, with the requirement that the first parameter is retained, the
second parameter contains the printf-style format string and the
arguments to be formatted follow immediately afterwards. If neither this
option nor `PrintfLikeFunctions` are set then the default value for
this option is `fprintf; absl::FPrintF`, otherwise it is empty.
arguments to be formatted follow immediately afterwards. Qualified
member function names are supported, but the replacement function name
must be unqualified. If neither this option nor `PrintfLikeFunctions`
are set then the default value for this option is `fprintf;
absl::FPrintF`, otherwise it is empty.

.. option:: ReplacementPrintFunction

Expand Down
10 changes: 9 additions & 1 deletion clang-tools-extra/include-cleaner/lib/WalkAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
Expand Down Expand Up @@ -350,6 +349,15 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
RefType::Implicit);
return true;
}

bool VisitCXXNewExpr(CXXNewExpr *E) {
report(E->getExprLoc(), E->getOperatorNew());
return true;
}
bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
report(E->getExprLoc(), E->getOperatorDelete());
return true;
}
};

} // namespace
Expand Down
7 changes: 7 additions & 0 deletions clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,5 +555,12 @@ TEST(WalkAST, FriendDecl) {
testWalk("void $explicit^foo();", "struct Bar { friend void ^foo(); };");
testWalk("struct $explicit^Foo {};", "struct Bar { friend struct ^Foo; };");
}

TEST(WalkAST, OperatorNewDelete) {
testWalk("void* $explicit^operator new(decltype(sizeof(int)), void*);",
"struct Bar { void foo() { Bar b; ^new (&b) Bar; } };");
testWalk("struct A { static void $explicit^operator delete(void*); };",
"void foo() { A a; ^delete &a; }");
}
} // namespace
} // namespace clang::include_cleaner
84 changes: 68 additions & 16 deletions clang-tools-extra/test/clang-doc/basic-project.test
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,62 @@

// HTML-SHAPE: <h1>class Shape</h1>
// HTML-SHAPE: <p>Defined at line 8 of file {{.*}}Shape.h</p>
// HTML-SHAPE: <div>brief</div>
// HTML-SHAPE: <p> Abstract base class for shapes.</p>
// HTML-SHAPE: <p> Provides a common interface for different types of shapes.</p>
// HTML-SHAPE: <h2 id="Functions">Functions</h2>
// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">area</h3>
// HTML-SHAPE: <p>public double area()</p>
// HTML-SHAPE: <div>brief</div>
// HTML-SHAPE: <p> Calculates the area of the shape.</p>
// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3>
// HTML-SHAPE: <p>public double perimeter()</p>
// HTML-SHAPE: <div>brief</div>
// HTML-SHAPE: <p> Calculates the perimeter of the shape.</p>
// HTML-SHAPE: <div>return</div>
// HTML-SHAPE: <p> double The perimeter of the shape.</p>
// HTML-SHAPE: <h3 id="{{([0-9A-F]{40})}}">~Shape</h3>
// HTML-SHAPE: <p>public void ~Shape()</p>
// HTML-SHAPE: <p>Defined at line 13 of file {{.*}}Shape.h</p>
// HTML-SHAPE: <div>brief</div>
// HTML-SHAPE: <p> Virtual destructor.</p>

// HTML-CALC: <h1>class Calculator</h1>
// HTML-CALC: <p>Defined at line 8 of file {{.*}}Calculator.h</p>
// HTML-CALC: <p> Provides basic arithmetic operations.</p>
// HTML-CALC: <h2 id="Functions">Functions</h2>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">add</h3>
// HTML-CALC: <p>public int add(int a, int b)</p>
// HTML-CALC: <p>Defined at line 3 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">subtract</h3>
// HTML-CALC: <p>public int subtract(int a, int b)</p>
// HTML-CALC: <p>Defined at line 7 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">multiply</h3>
// HTML-CALC: <p>public int multiply(int a, int b)</p>
// HTML-CALC: <p>Defined at line 11 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">divide</h3>
// HTML-CALC: <p>public double divide(int a, int b)</p>
// HTML-CALC: <p>Defined at line 15 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <h1>class Calculator</h1>
// HTML-CALC: <p>Defined at line 8 of file {{.*}}Calculator.h</p>
// HTML-CALC: <div>brief</div>
// HTML-CALC: <p> A simple calculator class.</p>
// HTML-CALC: <p> Provides basic arithmetic operations.</p>
// HTML-CALC: <h2 id="Functions">Functions</h2>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">add</h3>
// HTML-CALC: <p>public int add(int a, int b)</p>
// HTML-CALC: <p>Defined at line 3 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <div>brief</div>
// HTML-CALC: <p> Adds two integers.</p>
// HTML-CALC: <div>return</div>
// HTML-CALC: <p> int The sum of a and b.</p>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">subtract</h3>
// HTML-CALC: <p>public int subtract(int a, int b)</p>
// HTML-CALC: <p>Defined at line 7 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <div>brief</div>
// HTML-CALC: <p> Subtracts the second integer from the first.</p>
// HTML-CALC: <div>return</div>
// HTML-CALC: <p> int The result of a - b.</p>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">multiply</h3>
// HTML-CALC: <p>public int multiply(int a, int b)</p>
// HTML-CALC: <p>Defined at line 11 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <div>brief</div>
// HTML-CALC: <p> Multiplies two integers.</p>
// HTML-CALC: <div>return</div>
// HTML-CALC: <p> int The product of a and b.</p>
// HTML-CALC: <h3 id="{{([0-9A-F]{40})}}">divide</h3>
// HTML-CALC: <p>public double divide(int a, int b)</p>
// HTML-CALC: <p>Defined at line 15 of file {{.*}}Calculator.cpp</p>
// HTML-CALC: <div>brief</div>
// HTML-CALC: <p> Divides the first integer by the second.</p>
// HTML-CALC: <div>return</div>
// HTML-CALC: <p> double The result of a / b.</p>
// HTML-CALC: <div>throw</div>
// HTML-CALC: <p>if b is zero.</p>

// HTML-RECTANGLE: <h1>class Rectangle</h1>
// HTML-RECTANGLE: <p>Defined at line 10 of file {{.*}}Rectangle.h</p>
Expand All @@ -99,15 +129,27 @@
// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">Rectangle</h3>
// HTML-RECTANGLE: <p>public void Rectangle(double width, double height)</p>
// HTML-RECTANGLE: <p>Defined at line 3 of file {{.*}}Rectangle.cpp</p>
// HTML-RECTANGLE: <div>brief</div>
// HTML-RECTANGLE: <p> Constructs a new Rectangle object.</p>
// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">area</h3>
// HTML-RECTANGLE: <p>public double area()</p>
// HTML-RECTANGLE: <p>Defined at line 6 of file {{.*}}Rectangle.cpp</p>
// HTML-RECTANGLE: <div>brief</div>
// HTML-RECTANGLE: <p> Calculates the area of the rectangle.</p>
// HTML-RECTANGLE: <div>return</div>
// HTML-RECTANGLE: <p> double The area of the rectangle.</p>
// HTML-RECTANGLE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3>
// HTML-RECTANGLE: <p>public double perimeter()</p>
// HTML-RECTANGLE: <p>Defined at line 10 of file {{.*}}Rectangle.cpp</p>
// HTML-RECTANGLE: <div>brief</div>
// HTML-RECTANGLE: <p> Calculates the perimeter of the rectangle.</p>
// HTML-RECTANGLE: <div>return</div>
// HTML-RECTANGLE: <p> double The perimeter of the rectangle.</p>

// HTML-CIRCLE: <h1>class Circle</h1>
// HTML-CIRCLE: <p>Defined at line 10 of file {{.*}}Circle.h</p>
// HTML-CIRCLE: <div>brief</div>
// HTML-CIRCLE: <p> Circle class derived from Shape.</p>
// HTML-CIRCLE: <p> Represents a circle with a given radius.</p>
// HTML-CIRCLE: <p>
// HTML-CIRCLE: Inherits from
Expand All @@ -120,12 +162,22 @@
// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">Circle</h3>
// HTML-CIRCLE: <p>public void Circle(double radius)</p>
// HTML-CIRCLE: <p>Defined at line 3 of file {{.*}}Circle.cpp</p>
// HTML-CIRCLE: <div>brief</div>
// HTML-CIRCLE: <p> Constructs a new Circle object.</p>
// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">area</h3>
// HTML-CIRCLE: <p>public double area()</p>
// HTML-CIRCLE: <p>Defined at line 5 of file {{.*}}Circle.cpp</p>
// HTML-CIRCLE: <div>brief</div>
// HTML-CIRCLE: <p> Calculates the area of the circle.</p>
// HTML-CIRCLE: <div>return</div>
// HTML-CIRCLE: <p> double The area of the circle.</p>
// HTML-CIRCLE: <h3 id="{{([0-9A-F]{40})}}">perimeter</h3>
// HTML-CIRCLE: <p>public double perimeter()</p>
// HTML-CIRCLE: <p>Defined at line 9 of file {{.*}}Circle.cpp</p>
// HTML-CIRCLE: <div>brief</div>
// HTML-CIRCLE: <p> Calculates the perimeter of the circle.</p>
// HTML-CIRCLE: <div>return</div>
// HTML-CIRCLE: <p> double The perimeter of the circle.</p>

// MD-CALC: # class Calculator
// MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#8*
Expand Down
113 changes: 81 additions & 32 deletions clang-tools-extra/test/clang-doc/enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
enum Color {
// MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
Red, ///< Red
Green, ///< Green
Blue ///< Blue
Red, ///< Comment 1
Green, ///< Comment 2
Blue ///< Comment 3
};

// MD-INDEX: ## Enums
Expand All @@ -34,23 +34,29 @@ enum Color {
// MD-INDEX: | Blue |
// MD-INDEX: **brief** For specifying RGB colors

// HTML-INDEX: <h2 id="Enums">Enums</h2>
// HTML-INDEX: <h3 id="{{([0-9A-F]{40})}}">enum Color</h3>
// HTML-INDEX: <li>Red</li>
// HTML-INDEX: <li>Green</li>
// HTML-INDEX: <li>Blue</li>
// HTML-INDEX: <th colspan="3">enum Color</th>
// HTML-INDEX: <td>Red</td>
// HTML-INDEX: <td>0</td>
// HTML-INDEX: <p> Comment 1</p>
// HTML-INDEX: <td>Green</td>
// HTML-INDEX: <td>1</td>
// HTML-INDEX: <p> Comment 2</p>
// HTML-INDEX: <td>Blue</td>
// HTML-INDEX: <td>2</td>
// HTML-INDEX: <p> Comment 3</p>

/**
* @brief Shape Types
*/
enum class Shapes {
// MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
/// Circle

/// Comment 1
Circle,
/// Rectangle
/// Comment 2
Rectangle,
/// Triangle
/// Comment 3
Triangle
};
// MD-INDEX: | enum class Shapes |
Expand All @@ -60,10 +66,17 @@ enum class Shapes {
// MD-INDEX: | Triangle |
// MD-INDEX: **brief** Shape Types

// HTML-INDEX: <h3 id="{{([0-9A-F]{40})}}">enum class Shapes</h3>
// HTML-INDEX: <li>Circle</li>
// HTML-INDEX: <li>Rectangle</li>
// HTML-INDEX: <li>Triangle</li>
// HTML-INDEX: <th colspan="3">enum class Shapes</th>
// HTML-INDEX: <td>Circle</td>
// HTML-INDEX: <td>0</td>
// HTML-INDEX: <p> Comment 1</p>
// HTML-INDEX: <td>Rectangle</td>
// HTML-INDEX: <td>1</td>
// HTML-INDEX: <p> Comment 2</p>
// HTML-INDEX: <td>Triangle</td>
// HTML-INDEX: <td>2</td>
// HTML-INDEX: <p> Comment 3</p>



class Animals {
Expand All @@ -76,18 +89,25 @@ class Animals {
enum AnimalType {
// MD-ANIMAL-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-ANIMAL-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
Dog, /// Man's best friend
Cat, /// Man's other best friend
Iguana /// A lizard
Dog, ///< Man's best friend
Cat, ///< Man's other best friend
Iguana ///< A lizard
};
};

// HTML-ANIMAL: <h1>class Animals</h1>
// HTML-ANIMAL: <h2 id="Enums">Enums</h2>
// HTML-ANIMAL: <h3 id="{{([0-9A-F]{40})}}">enum AnimalType</h3>
// HTML-ANIMAL: <li>Dog</li>
// HTML-ANIMAL: <li>Cat</li>
// HTML-ANIMAL: <li>Iguana</li>
// HTML-ANIMAL: <th colspan="3">enum AnimalType</th>
// HTML-ANIMAL: <td>Dog</td>
// HTML-ANIMAL: <td>0</td>
// HTML-ANIMAL: <p> Man&apos;s best friend</p>
// HTML-ANIMAL: <td>Cat</td>
// HTML-ANIMAL: <td>1</td>
// HTML-ANIMAL: <p> Man&apos;s other best friend</p>
// HTML-ANIMAL: <td>Iguana</td>
// HTML-ANIMAL: <td>2</td>
// HTML-ANIMAL: <p> A lizard</p>


// MD-ANIMAL: # class Animals
// MD-ANIMAL: ## Enums
Expand All @@ -106,10 +126,11 @@ namespace Vehicles {
enum Car {
// MD-VEHICLES-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-VEHICLES-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
Sedan, /// Sedan
SUV, /// SUV
Pickup, /// Pickup
Hatchback /// Hatchback

Sedan, ///< Comment 1
SUV, ///< Comment 2
Pickup, ///< Comment 3
Hatchback ///< Comment 4
};
}

Expand All @@ -124,9 +145,37 @@ namespace Vehicles {
// MD-VEHICLES: **brief** specify type of car

// HTML-VEHICLES: <h1>namespace Vehicles</h1>
// HTML-VEHICLES: <h2 id="Enums">Enums</h2>
// HTML-VEHICLES: <h3 id="{{([0-9A-F]{40})}}">enum Car</h3>
// HTML-VEHICLES: <li>Sedan</li>
// HTML-VEHICLES: <li>SUV</li>
// HTML-VEHICLES: <li>Pickup</li>
// HTML-VEHICLES: <li>Hatchback</li>
// HTML-VEHICLES: <th colspan="3">enum Car</th>
// HTML-VEHICLES: <td>Sedan</td>
// HTML-VEHICLES: <td>0</td>
// HTML-VEHICLES: <p> Comment 1</p>
// HTML-VEHICLES: <td>SUV</td>
// HTML-VEHICLES: <td>1</td>
// HTML-VEHICLES: <p> Comment 2</p>
// HTML-VEHICLES: <td>Pickup</td>
// HTML-VEHICLES: <td>2</td>
// HTML-VEHICLES: <p> Comment 3</p>
// HTML-VEHICLES: <td>Hatchback</td>
// HTML-VEHICLES: <td>3</td>
// HTML-VEHICLES: <p> Comment 4</p>


enum ColorUserSpecified {
RedUserSpecified = 'A',
GreenUserSpecified = 2,
BlueUserSpecified = 'C'
};

// MD-INDEX: | enum ColorUserSpecified |
// MD-INDEX: --
// MD-INDEX: | RedUserSpecified |
// MD-INDEX: | GreenUserSpecified |
// MD-INDEX: | BlueUserSpecified |

// HTML-INDEX: <th colspan="2">enum ColorUserSpecified</th>
// HTML-INDEX: <td>RedUserSpecified</td>
// HTML-INDEX: <td>&apos;A&apos;</td>
// HTML-INDEX: <td>GreenUserSpecified</td>
// HTML-INDEX: <td>2</td>
// HTML-INDEX: <td>BlueUserSpecified</td>
// HTML-INDEX: <td>&apos;C&apos;</td>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// RUN: %check_clang_tidy %s modernize-use-std-format %t -- \
// RUN: -config="{CheckOptions: \
// RUN: { \
// RUN: modernize-use-std-format.StrFormatLikeFunctions: 'MyClass::StrFormat', \
// RUN: modernize-use-std-format.ReplacementFormatFunction: 'format', \
// RUN: } \
// RUN: }" \
// RUN: -- -isystem %clang_tidy_headers

#include <cstdio>
#include <string.h>
#include <string>

struct MyClass
{
template <typename S, typename... Args>
std::string StrFormat(const S &format, const Args&... args);
};

std::string StrFormat_simple(MyClass &myclass, MyClass *pmyclass) {
std::string s;

s += myclass.StrFormat("MyClass::StrFormat dot %d", 42);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
// CHECK-FIXES: s += myclass.format("MyClass::StrFormat dot {}", 42);

s += pmyclass->StrFormat("MyClass::StrFormat pointer %d", 43);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
// CHECK-FIXES: s += pmyclass->format("MyClass::StrFormat pointer {}", 43);

s += (*pmyclass).StrFormat("MyClass::StrFormat deref pointer %d", 44);
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
// CHECK-FIXES: s += (*pmyclass).format("MyClass::StrFormat deref pointer {}", 44);

return s;
}

struct MyDerivedClass : public MyClass {};

std::string StrFormat_derived(MyDerivedClass &derived) {
return derived.StrFormat("MyDerivedClass::StrFormat dot %d", 42);
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'format' instead of 'StrFormat' [modernize-use-std-format]
// CHECK-FIXES: return derived.format("MyDerivedClass::StrFormat dot {}", 42);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// RUN: %check_clang_tidy %s modernize-use-std-print %t -- \
// RUN: -config="{CheckOptions: \
// RUN: { \
// RUN: modernize-use-std-print.PrintfLikeFunctions: 'MyClass::printf', \
// RUN: modernize-use-std-print.FprintfLikeFunctions: 'MyClass::fprintf', \
// RUN: modernize-use-std-print.ReplacementPrintFunction: 'print', \
// RUN: modernize-use-std-print.ReplacementPrintlnFunction: 'println', \
// RUN: } \
// RUN: }" \
// RUN: -- -isystem %clang_tidy_headers

#include <cstdio>
#include <string.h>

struct MyStruct {};

struct MyClass
{
template <typename... Args>
void printf(const char *fmt, Args &&...);
template <typename... Args>
int fprintf(MyStruct *param1, const char *fmt, Args &&...);
};

void printf_simple(MyClass &myclass, MyClass *pmyclass) {
myclass.printf("printf dot %d", 42);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
// CHECK-FIXES: myclass.print("printf dot {}", 42);

pmyclass->printf("printf pointer %d", 43);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
// CHECK-FIXES: pmyclass->print("printf pointer {}", 43);

(*pmyclass).printf("printf deref pointer %d", 44);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
// CHECK-FIXES: (*pmyclass).print("printf deref pointer {}", 44);
}

void printf_newline(MyClass &myclass, MyClass *pmyclass) {
myclass.printf("printf dot newline %c\n", 'A');
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'println' instead of 'printf' [modernize-use-std-print]
// CHECK-FIXES: myclass.println("printf dot newline {}", 'A');

pmyclass->printf("printf pointer newline %c\n", 'B');
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'println' instead of 'printf' [modernize-use-std-print]
// CHECK-FIXES: pmyclass->println("printf pointer newline {}", 'B');
}

void fprintf_simple(MyStruct *mystruct, MyClass &myclass, MyClass *pmyclass) {
myclass.fprintf(mystruct, "fprintf dot %d", 142);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'fprintf' [modernize-use-std-print]
// CHECK-FIXES: myclass.print(mystruct, "fprintf dot {}", 142);

pmyclass->fprintf(mystruct, "fprintf pointer %d", 143);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'fprintf' [modernize-use-std-print]
// CHECK-FIXES: pmyclass->print(mystruct, "fprintf pointer {}", 143);

(*pmyclass).fprintf(mystruct, "fprintf deref pointer %d", 144);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'fprintf' [modernize-use-std-print]
// CHECK-FIXES: (*pmyclass).print(mystruct, "fprintf deref pointer {}", 144);
}

struct MyDerivedClass : public MyClass {};

void printf_derived(MyDerivedClass &derived)
{
derived.printf("printf on derived class %d", 42);
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'print' instead of 'printf' [modernize-use-std-print]
// CHECK-FIXES: derived.print("printf on derived class {}", 42);
}
33 changes: 27 additions & 6 deletions clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,13 @@ TEST(HTMLGeneratorTest, emitNamespaceHTML) {
</div>
<h2 id="Enums">Enums</h2>
<div>
<h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
<table id="0000000000000000000000000000000000000000">
<thead>
<tr>
<th colspan="2">enum OneEnum</th>
</tr>
</thead>
</table>
</div>
</div>
<div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
Expand Down Expand Up @@ -214,7 +220,13 @@ TEST(HTMLGeneratorTest, emitRecordHTML) {
</div>
<h2 id="Enums">Enums</h2>
<div>
<h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
<table id="0000000000000000000000000000000000000000">
<thead>
<tr>
<th colspan="2">enum OneEnum</th>
</tr>
</thead>
</table>
</div>
</div>
<div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
Expand Down Expand Up @@ -348,10 +360,19 @@ TEST(HTMLGeneratorTest, emitEnumHTML) {
<main>
<div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
<div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
<h3 id="0000000000000000000000000000000000000000">enum class e</h3>
<ul>
<li>X</li>
</ul>
<table id="0000000000000000000000000000000000000000">
<thead>
<tr>
<th colspan="2">enum class e</th>
</tr>
</thead>
<tbody>
<tr>
<td>X</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>
Defined at line
<a href="https://www.repository.com/test.cpp#10">10</a>
Expand Down
28 changes: 8 additions & 20 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@ def __eq__(self, other):
def __ne__(self, other):
return not self.__eq__(other)

def __lt__(self, other: SourceLocation) -> bool:
return conf.lib.clang_isBeforeInTranslationUnit(self, other) # type: ignore [no-any-return]

def __le__(self, other: SourceLocation) -> bool:
return self < other or self == other

def __repr__(self):
if self.file:
filename = self.file.name
Expand Down Expand Up @@ -375,26 +381,7 @@ def __contains__(self, other):
"""Useful to detect the Token/Lexer bug"""
if not isinstance(other, SourceLocation):
return False
if other.file is None and self.start.file is None:
pass
elif (
self.start.file.name != other.file.name
or other.file.name != self.end.file.name
):
# same file name
return False
# same file, in between lines
if self.start.line < other.line < self.end.line:
return True
elif self.start.line == other.line:
# same file first line
if self.start.column <= other.column:
return True
elif other.line == self.end.line:
# same file last line
if other.column <= self.end.column:
return True
return False
return self.start <= other <= self.end

def __repr__(self):
return "<SourceRange start %r, end %r>" % (self.start, self.end)
Expand Down Expand Up @@ -3908,6 +3895,7 @@ def write_main_file_to_stdout(self):
("clang_isUnexposed", [CursorKind], bool),
("clang_isVirtualBase", [Cursor], bool),
("clang_isVolatileQualifiedType", [Type], bool),
("clang_isBeforeInTranslationUnit", [SourceLocation, SourceLocation], bool),
(
"clang_parseTranslationUnit",
[Index, c_interop_string, c_void_p, c_int, c_void_p, c_int, c_int],
Expand Down
20 changes: 20 additions & 0 deletions clang/bindings/python/tests/cindex/test_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,23 @@ def test_is_system_location(self):
two = get_cursor(tu, "two")
self.assertFalse(one.location.is_in_system_header)
self.assertTrue(two.location.is_in_system_header)

def test_operator_lt(self):
tu = get_tu("aaaaa")
t1_f = tu.get_file(tu.spelling)
tu2 = get_tu("aaaaa")

l_t1_12 = SourceLocation.from_position(tu, t1_f, 1, 2)
l_t1_13 = SourceLocation.from_position(tu, t1_f, 1, 3)
l_t1_14 = SourceLocation.from_position(tu, t1_f, 1, 4)

l_t2_13 = SourceLocation.from_position(tu2, tu2.get_file(tu2.spelling), 1, 3)

# In same file
assert l_t1_12 < l_t1_13 < l_t1_14
assert not l_t1_13 < l_t1_12

# In same file, different TU
assert l_t1_12 < l_t2_13 < l_t1_14
assert not l_t2_13 < l_t1_12
assert not l_t1_14 < l_t2_13
85 changes: 85 additions & 0 deletions clang/bindings/python/tests/cindex/test_source_range.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import os
from clang.cindex import Config

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest
from clang.cindex import SourceLocation, SourceRange, TranslationUnit

from .util import get_tu


def create_range(tu, line1, column1, line2, column2):
return SourceRange.from_locations(
SourceLocation.from_position(tu, tu.get_file(tu.spelling), line1, column1),
SourceLocation.from_position(tu, tu.get_file(tu.spelling), line2, column2),
)


class TestSourceRange(unittest.TestCase):
def test_contains(self):
tu = get_tu(
"""aaaaa
aaaaa
aaaaa
aaaaa"""
)
file = tu.get_file(tu.spelling)

l13 = SourceLocation.from_position(tu, file, 1, 3)
l21 = SourceLocation.from_position(tu, file, 2, 1)
l22 = SourceLocation.from_position(tu, file, 2, 2)
l23 = SourceLocation.from_position(tu, file, 2, 3)
l24 = SourceLocation.from_position(tu, file, 2, 4)
l25 = SourceLocation.from_position(tu, file, 2, 5)
l33 = SourceLocation.from_position(tu, file, 3, 3)
l31 = SourceLocation.from_position(tu, file, 3, 1)
r22_24 = create_range(tu, 2, 2, 2, 4)
r23_23 = create_range(tu, 2, 3, 2, 3)
r24_32 = create_range(tu, 2, 4, 3, 2)
r14_32 = create_range(tu, 1, 4, 3, 2)

assert l13 not in r22_24 # Line before start
assert l21 not in r22_24 # Column before start
assert l22 in r22_24 # Colum on start
assert l23 in r22_24 # Column in range
assert l24 in r22_24 # Column on end
assert l25 not in r22_24 # Column after end
assert l33 not in r22_24 # Line after end

assert l23 in r23_23 # In one-column range

assert l23 not in r24_32 # Outside range in first line
assert l33 not in r24_32 # Outside range in last line
assert l25 in r24_32 # In range in first line
assert l31 in r24_32 # In range in last line

assert l21 in r14_32 # In range at start of center line
assert l25 in r14_32 # In range at end of center line

# In range within included file
tu2 = TranslationUnit.from_source(
"main.c",
unsaved_files=[
(
"main.c",
"""int a[] = {
#include "numbers.inc"
};
""",
),
(
"./numbers.inc",
"""1,
2,
3,
4
""",
),
],
)

r_curly = create_range(tu2, 1, 11, 3, 1)
l_f2 = SourceLocation.from_position(tu2, tu2.get_file("./numbers.inc"), 4, 1)
assert l_f2 in r_curly
6 changes: 4 additions & 2 deletions clang/cmake/caches/CrossWinToARMLinux.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ endif()

message(STATUS "Toolchain target to build: ${LLVM_TARGETS_TO_BUILD}")

# Allow to override libc++ ABI version. Use 2 by default.
# Allow to override libc++ ABI version (1 is default).
if (NOT DEFINED LIBCXX_ABI_VERSION)
set(LIBCXX_ABI_VERSION 2)
set(LIBCXX_ABI_VERSION 1)
endif()

message(STATUS "Toolchain's Libc++ ABI version: ${LIBCXX_ABI_VERSION}")
Expand Down Expand Up @@ -217,6 +217,8 @@ set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_SHARED
set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ABI_VERSION ${LIBCXX_ABI_VERSION} CACHE STRING "")
set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "") #!!!
set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "")
# Merge libc++ and libc++abi libraries into the single libc++ library file.
set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")

# Avoid searching for the python3 interpreter during the runtimes configuration for the cross builds.
# It starts searching the python3 package using the target's sysroot path, that usually is not compatible with the build host.
Expand Down
36 changes: 31 additions & 5 deletions clang/docs/ClangFormatStyleOptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4187,7 +4187,8 @@ the configuration (without a prefix: ``Auto``).

**IndentRequiresClause** (``Boolean``) :versionbadge:`clang-format 15` :ref:`¶ <IndentRequiresClause>`
Indent the requires clause in a template. This only applies when
``RequiresClausePosition`` is ``OwnLine``, or ``WithFollowing``.
``RequiresClausePosition`` is ``OwnLine``, ``OwnLineWithBrace``,
or ``WithFollowing``.

In clang-format 12, 13 and 14 it was named ``IndentRequires``.

Expand Down Expand Up @@ -5419,23 +5420,48 @@ the configuration (without a prefix: ``Auto``).
Possible values:

* ``RCPS_OwnLine`` (in configuration: ``OwnLine``)
Always put the ``requires`` clause on its own line.
Always put the ``requires`` clause on its own line (possibly followed by
a semicolon).

.. code-block:: c++

template <typename T>
requires C<T>
requires C<T>
struct Foo {...

template <typename T>
requires C<T>
void bar(T t)
requires C<T>;

template <typename T>
requires C<T>
void bar(T t) {...

template <typename T>
void baz(T t)
requires C<T>
requires C<T>
{...

* ``RCPS_OwnLineWithBrace`` (in configuration: ``OwnLineWithBrace``)
As with ``OwnLine``, except, unless otherwise prohibited, place a
following open brace (of a function definition) to follow on the same
line.

.. code-block:: c++

void bar(T t)
requires C<T> {
return;
}

void bar(T t)
requires C<T> {}

template <typename T>
requires C<T>
void baz(T t) {
...

* ``RCPS_WithPreceding`` (in configuration: ``WithPreceding``)
Try to put the clause together with the preceding part of a declaration.
For class templates: stick to the template declaration.
Expand Down
2 changes: 1 addition & 1 deletion clang/docs/ClangFormattedStatus.rst
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ tree in terms of conformance to :doc:`ClangFormat` as of: March 06, 2022 17:32:2
- `2`
- `79`
- :part:`2%`
* - clang/lib/AST/Interp
* - clang/lib/AST/ByteCode
- `44`
- `18`
- `26`
Expand Down
2 changes: 1 addition & 1 deletion clang/docs/InternalsManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3200,7 +3200,7 @@ are similar.
always involve two functions: an ``ActOnXXX`` function that will be called
directly from the parser, and a ``BuildXXX`` function that performs the
actual semantic analysis and will (eventually!) build the AST node. It's
fairly common for the ``ActOnCXX`` function to do very little (often just
fairly common for the ``ActOnXXX`` function to do very little (often just
some minor translation from the parser's representation to ``Sema``'s
representation of the same thing), but the separation is still important:
C++ template instantiation, for example, should always call the ``BuildXXX``
Expand Down
46 changes: 22 additions & 24 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,7 @@ Attributes on Lambda-Expressions C+
Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03
Pack Indexing __cpp_pack_indexing C++26 C++03
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
Variadic Friends __cpp_variadic_friend C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
Designated initializers (N494) C99 C89
Array & element qualification (N2607) C23 C89
Expand Down Expand Up @@ -3539,7 +3540,7 @@ the debugging experience.
``__builtin_allow_runtime_check``
---------------------------------

``__builtin_allow_runtime_check`` return true if the check at the current
``__builtin_allow_runtime_check`` returns true if the check at the current
program location should be executed. It is expected to be used to implement
``assert`` like checks which can be safely removed by optimizer.

Expand All @@ -3559,28 +3560,25 @@ program location should be executed. It is expected to be used to implement

**Description**

``__builtin_allow_runtime_check`` is lowered to ` ``llvm.allow.runtime.check``
``__builtin_allow_runtime_check`` is lowered to the `llvm.allow.runtime.check
<https://llvm.org/docs/LangRef.html#llvm-allow-runtime-check-intrinsic>`_
builtin.

The ``__builtin_allow_runtime_check()`` is expected to be used with control
flow conditions such as in ``if`` to guard expensive runtime checks. The
specific rules for selecting permitted checks can differ and are controlled by
the compiler options.

Flags to control checks:
* ``-mllvm -lower-allow-check-percentile-cutoff-hot=N`` where N is PGO hotness
cutoff in range ``[0, 999999]`` to disallow checks in hot code.
* ``-mllvm -lower-allow-check-random-rate=P`` where P is number in range
``[0.0, 1.0]`` representation probability of keeping a check.
* If both flags are specified, ``-lower-allow-check-random-rate`` takes
precedence.
* If none is specified, ``__builtin_allow_runtime_check`` is lowered as
``true``, allowing all checks.

Parameter ``kind`` is a string literal representing a user selected kind for
guarded check. It's unused now. It will enable kind-specific lowering in future.
E.g. a higher hotness cutoff can be used for more expensive kind of check.
intrinsic.

The ``__builtin_allow_runtime_check()`` can be used within constrol structures
like ``if`` to guard expensive runtime checks. The return value is determined
by the following compiler options and may differ per call site:

* ``-mllvm -lower-allow-check-percentile-cutoff-hot=N``: Disable checks in hot
code marked by the profile summary with a hotness cutoff in the range
``[0, 999999]`` (a larger N disables more checks).
* ``-mllvm -lower-allow-check-random-rate=P``: Keep a check with probability P,
a floating point number in the range ``[0.0, 1.0]``.
* If both options are specified, a check is disabled if either condition is satisfied.
* If neither is specified, all checks are allowed.

Parameter ``kind``, currently unused, is a string literal specifying the check
kind. Future compiler versions may use this to allow for more granular control,
such as applying different hotness cutoffs to different check kinds.

Query for this feature with ``__has_builtin(__builtin_allow_runtime_check)``.

Expand Down Expand Up @@ -3989,7 +3987,7 @@ ellipsis (``...``) in the function signature. Alternatively, in C23 mode or
later, it may be the integer literal ``0`` if there is no parameter preceding
the ellipsis. This function initializes the given ``__builtin_va_list`` object.
It is undefined behavior to call this function on an already initialized
``__builin_va_list`` object.
``__builtin_va_list`` object.

* ``void __builtin_va_end(__builtin_va_list list)``

Expand Down Expand Up @@ -4323,7 +4321,7 @@ an appropriate value during the emission.

Note that there is no builtin matching the `llvm.coro.save` intrinsic. LLVM
automatically will insert one if the first argument to `llvm.coro.suspend` is
token `none`. If a user calls `__builin_suspend`, clang will insert `token none`
token `none`. If a user calls `__builtin_suspend`, clang will insert `token none`
as the first argument to the intrinsic.

Source location builtins
Expand Down
71 changes: 64 additions & 7 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ C++ Specific Potentially Breaking Changes
template <> // error: extraneous template head
template <typename T>
void f();

ABI Changes in This Version
---------------------------

Expand All @@ -90,6 +90,9 @@ Clang Python Bindings Potentially Breaking Changes
- Calling a property on the ``CompletionChunk`` or ``CompletionString`` class
statically now leads to an error, instead of returning a ``CachedProperty`` object
that is used internally. Properties are only available on instances.
- For a single-line ``SourceRange`` and a ``SourceLocation`` in the same line,
but after the end of the ``SourceRange``, ``SourceRange.__contains__``
used to incorrectly return ``True``. (#GH22617), (#GH52827)

What's New in Clang |release|?
==============================
Expand Down Expand Up @@ -126,6 +129,8 @@ C++2c Feature Support
- Add ``__builtin_is_virtual_base_of`` intrinsic, which supports
`P2985R0 A type trait for detecting virtual base classes <https://wg21.link/p2985r0>`_

- Implemented `P2893R3 Variadic Friends <https://wg21.link/P2893>`_

Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -144,6 +149,12 @@ Resolutions to C++ Defect Reports
of the target type, even if the type of the bit-field is larger.
(`CWG2627: Bit-fields and narrowing conversions <https://cplusplus.github.io/CWG/issues/2627.html>`_)

- ``nullptr`` is now promoted to ``void*`` when passed to a C-style variadic function.
(`CWG722: Can nullptr be passed to an ellipsis? <https://cplusplus.github.io/CWG/issues/722.html>`_)

- Allow ``void{}`` as a prvalue of type ``void``.
(`CWG2351: void{} <https://cplusplus.github.io/CWG/issues/2351.html>`_).

C Language Changes
------------------

Expand All @@ -156,6 +167,10 @@ C23 Feature Support
Non-comprehensive list of changes in this release
-------------------------------------------------

- The floating point comparison builtins (``__builtin_isgreater``,
``__builtin_isgreaterequal``, ``__builtin_isless``, etc.) and
``__builtin_signbit`` can now be used in constant expressions.

New Compiler Flags
------------------

Expand All @@ -165,6 +180,16 @@ Deprecated Compiler Flags
Modified Compiler Flags
-----------------------

- The compiler flag `-fbracket-depth` default value is increased from 256 to 2048.

- The ``-ffp-model`` option has been updated to enable a more limited set of
optimizations when the ``fast`` argument is used and to accept a new argument,
``aggressive``. The behavior of ``-ffp-model=aggressive`` is equivalent
to the previous behavior of ``-ffp-model=fast``. The updated
``-ffp-model=fast`` behavior no longer assumes finite math only and uses
the ``promoted`` algorithm for complex division when possible rather than the
less basic (limited range) algorithm.

Removed Compiler Flags
-------------------------

Expand All @@ -184,6 +209,9 @@ Attribute Changes in Clang
- The ``hybrid_patchable`` attribute is now supported on ARM64EC targets. It can be used to specify
that a function requires an additional x86-64 thunk, which may be patched at runtime.

- ``[[clang::lifetimebound]]`` is now explicitly disallowed on explicit object member functions
where they were previously silently ignored.

Improvements to Clang's diagnostics
-----------------------------------

Expand All @@ -209,6 +237,8 @@ Improvements to Clang's diagnostics

- Clang now diagnoses the use of ``main`` in an ``extern`` context as invalid according to [basic.start.main] p3. Fixes #GH101512.

- Clang now diagnoses when the result of a [[nodiscard]] function is discarded after being cast in C. Fixes #GH104391.

Improvements to Clang's time-trace
----------------------------------

Expand Down Expand Up @@ -254,10 +284,20 @@ Bug Fixes to C++ Support
specialization of a conversion function template.
- Correctly diagnose attempts to use a concept name in its own definition;
A concept name is introduced to its scope sooner to match the C++ standard. (#GH55875)
- Properly reject defaulted relational operators with invalid types for explicit object parameters,
e.g., ``bool operator==(this int, const Foo&)`` (#GH100329), and rvalue reference parameters.
- Properly reject defaulted copy/move assignment operators that have a non-reference explicit object parameter.
- Clang now properly handles the order of attributes in `extern` blocks. (#GH101990).
- Fixed an assertion failure by preventing null explicit object arguments from being deduced. (#GH102025).
- Correctly check constraints of explicit instantiations of member functions. (#GH46029)
- Fixed an assertion failure about a constraint of a friend function template references to a value with greater
template depth than the friend function template. (#GH98258)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

- Fixed a crash that occurred when dividing by zero in complex integer division. (#GH55390).

Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -270,6 +310,12 @@ Miscellaneous Clang Crashes Fixed
- Fixed a crash caused by long chains of ``sizeof`` and other similar operators
that can be followed by a non-parenthesized expression. (#GH45061)

- Fixed an crash when compiling ``#pragma STDC FP_CONTRACT DEFAULT`` with
``-ffp-contract=fast-honor-pragmas``. (#GH104830)

- Fixed a crash when function has more than 65536 parameters.
Now a diagnostic is emitted. (#GH35741)

OpenACC Specific Changes
------------------------

Expand Down Expand Up @@ -311,6 +357,12 @@ Android Support
Windows Support
^^^^^^^^^^^^^^^

- Clang no longer allows references inside a union when emulating MSVC 1900+ even if `fms-extensions` is enabled.
Starting with VS2015, MSVC 1900, this Microsoft extension is no longer allowed and always results in an error.
Clang now follows the MSVC behavior in this scenario.
When `-fms-compatibility-version=18.00` or prior is set on the command line this Microsoft extension is still
allowed as VS2013 and prior allow it.

LoongArch Support
^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -350,13 +402,18 @@ AST Matchers
- Fixed an issue with the `hasName` and `hasAnyName` matcher when matching
inline namespaces with an enclosing namespace of the same name.

- Fixed an ordering issue with the `hasOperands` matcher occuring when setting a
binding in the first matcher and using it in the second matcher.

clang-format
------------

- Adds ``BreakBinaryOperations`` option.

libclang
--------
- Add ``clang_isBeforeInTranslationUnit``. Given two source locations, it determines
whether the first one comes strictly before the second in the source code.

Static Analyzer
---------------
Expand Down Expand Up @@ -392,27 +449,27 @@ Moved checkers
Sanitizers
----------

- Added the ``-fsanitize-overflow-pattern-exclusion=`` flag which can be used
to disable specific overflow-dependent code patterns. The supported patterns
are: ``add-overflow-test``, ``negated-unsigned-const``, and
- Added the ``-fsanitize-undefined-ignore-overflow-pattern`` flag which can be
used to disable specific overflow-dependent code patterns. The supported
patterns are: ``add-overflow-test``, ``negated-unsigned-const``, and
``post-decr-while``. The sanitizer instrumentation can be toggled off for all
available patterns by specifying ``all``. Conversely, you can disable all
exclusions with ``none``.

.. code-block:: c++

/// specified with ``-fsanitize-overflow-pattern-exclusion=add-overflow-test``
/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=add-overflow-test``
int common_overflow_check_pattern(unsigned base, unsigned offset) {
if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, won't be instrumented
}
/// specified with ``-fsanitize-overflow-pattern-exclusion=negated-unsigned-const``
/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const``
void negation_overflow() {
unsigned long foo = -1UL; // No longer causes a negation overflow warning
unsigned long bar = -2UL; // and so on...
}

/// specified with ``-fsanitize-overflow-pattern-exclusion=post-decr-while``
/// specified with ``-fsanitize-undefined-ignore-overflow-pattern=post-decr-while``
void while_post_decrement() {
unsigned char count = 16;
while (count--) { /* ... */} // No longer causes unsigned-integer-overflow sanitizer to trip
Expand Down
14 changes: 7 additions & 7 deletions clang/docs/UndefinedBehaviorSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -302,38 +302,38 @@ unsigned constants, post-decrements in a while loop condition and simple
overflow checks are accepted and pervasive code patterns. However, the signal
received from sanitizers instrumenting these code patterns may be too noisy for
some projects. To disable instrumentation for these common patterns one should
use ``-fsanitize-overflow-pattern-exclusion=``.
use ``-fsanitize-undefined-ignore-overflow-pattern=``.

Currently, this option supports three overflow-dependent code idioms:

``negated-unsigned-const``

.. code-block:: c++

/// -fsanitize-overflow-pattern-exclusion=negated-unsigned-const
/// -fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const
unsigned long foo = -1UL; // No longer causes a negation overflow warning
unsigned long bar = -2UL; // and so on...

``post-decr-while``

.. code-block:: c++

/// -fsanitize-overflow-pattern-exclusion=post-decr-while
/// -fsanitize-undefined-ignore-overflow-pattern=post-decr-while
unsigned char count = 16;
while (count--) { /* ... */ } // No longer causes unsigned-integer-overflow sanitizer to trip
``add-overflow-test``

.. code-block:: c++

/// -fsanitize-overflow-pattern-exclusion=add-overflow-test
/// -fsanitize-undefined-ignore-overflow-pattern=add-overflow-test
if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings,
// won't be instrumented (same for signed types)
You can enable all exclusions with
``-fsanitize-overflow-pattern-exclusion=all`` or disable all exclusions with
``-fsanitize-overflow-pattern-exclusion=none``. Specifying ``none`` has
precedence over other values.
``-fsanitize-undefined-ignore-overflow-pattern=all`` or disable all exclusions
with ``-fsanitize-undefined-ignore-overflow-pattern=none``. Specifying ``none``
has precedence over other values.

Issue Suppression
=================
Expand Down
45 changes: 25 additions & 20 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1452,28 +1452,30 @@ describes the various floating point semantic modes and the corresponding option
"fhonor-infinities", "{on, off}"
"fsigned-zeros", "{on, off}"
"freciprocal-math", "{on, off}"
"allow_approximate_fns", "{on, off}"
"fallow-approximate-fns", "{on, off}"
"fassociative-math", "{on, off}"
"fcomplex-arithmetic", "{basic, improved, full, promoted}"

This table describes the option settings that correspond to the three
floating point semantic models: precise (the default), strict, and fast.


.. csv-table:: Floating Point Models
:header: "Mode", "Precise", "Strict", "Fast"
:widths: 25, 15, 15, 15

"except_behavior", "ignore", "strict", "ignore"
"fenv_access", "off", "on", "off"
"rounding_mode", "tonearest", "dynamic", "tonearest"
"contract", "on", "off", "fast"
"support_math_errno", "on", "on", "off"
"no_honor_nans", "off", "off", "on"
"no_honor_infinities", "off", "off", "on"
"no_signed_zeros", "off", "off", "on"
"allow_reciprocal", "off", "off", "on"
"allow_approximate_fns", "off", "off", "on"
"allow_reassociation", "off", "off", "on"
:header: "Mode", "Precise", "Strict", "Fast", "Aggressive"
:widths: 25, 25, 25, 25, 25

"except_behavior", "ignore", "strict", "ignore", "ignore"
"fenv_access", "off", "on", "off", "off"
"rounding_mode", "tonearest", "dynamic", "tonearest", "tonearest"
"contract", "on", "off", "fast", "fast"
"support_math_errno", "on", "on", "off", "off"
"no_honor_nans", "off", "off", "off", "on"
"no_honor_infinities", "off", "off", "off", "on"
"no_signed_zeros", "off", "off", "on", "on"
"allow_reciprocal", "off", "off", "on", "on"
"allow_approximate_fns", "off", "off", "on", "on"
"allow_reassociation", "off", "off", "on", "on"
"complex_arithmetic", "full", "full", "promoted", "basic"

The ``-ffp-model`` option does not modify the ``fdenormal-fp-math``
setting, but it does have an impact on whether ``crtfastmath.o`` is
Expand All @@ -1492,9 +1494,9 @@ for more details.
* Floating-point math obeys regular algebraic rules for real numbers (e.g.
``+`` and ``*`` are associative, ``x/y == x * (1/y)``, and
``(a + b) * c == a * c + b * c``),
* Operands to floating-point operations are not equal to ``NaN`` and
``Inf``, and
* ``+0`` and ``-0`` are interchangeable.
* No ``NaN`` or infinite values will be operands or results of
floating-point operations,
* ``+0`` and ``-0`` may be treated as interchangeable.

``-ffast-math`` also defines the ``__FAST_MATH__`` preprocessor
macro. Some math libraries recognize this macro and change their behavior.
Expand Down Expand Up @@ -1753,7 +1755,7 @@ for more details.
Specify floating point behavior. ``-ffp-model`` is an umbrella
option that encompasses functionality provided by other, single
purpose, floating point options. Valid values are: ``precise``, ``strict``,
and ``fast``.
``fast``, and ``aggressive``.
Details:

* ``precise`` Disables optimizations that are not value-safe on
Expand All @@ -1766,7 +1768,10 @@ for more details.
``STDC FENV_ACCESS``: by default ``FENV_ACCESS`` is disabled. This option
setting behaves as though ``#pragma STDC FENV_ACCESS ON`` appeared at the
top of the source file.
* ``fast`` Behaves identically to specifying both ``-ffast-math`` and
* ``fast`` Behaves identically to specifying ``-funsafe-math-optimizations``,
``-fno-math-errno`` and ``-fcomplex-arithmetic=promoted``
``ffp-contract=fast``
* ``aggressive`` Behaves identically to specifying both ``-ffast-math`` and
``ffp-contract=fast``

Note: If your command line specifies multiple instances
Expand Down
36 changes: 18 additions & 18 deletions clang/docs/tools/clang-formatted-files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -322,24 +322,24 @@ clang/lib/APINotes/APINotesTypes.cpp
clang/lib/APINotes/APINotesYAMLCompiler.cpp
clang/lib/AST/DataCollection.cpp
clang/lib/AST/Linkage.h
clang/lib/AST/Interp/ByteCodeGenError.cpp
clang/lib/AST/Interp/ByteCodeGenError.h
clang/lib/AST/Interp/Context.cpp
clang/lib/AST/Interp/Context.h
clang/lib/AST/Interp/Descriptor.cpp
clang/lib/AST/Interp/Disasm.cpp
clang/lib/AST/Interp/EvalEmitter.h
clang/lib/AST/Interp/Frame.cpp
clang/lib/AST/Interp/Frame.h
clang/lib/AST/Interp/InterpState.h
clang/lib/AST/Interp/Opcode.h
clang/lib/AST/Interp/Pointer.cpp
clang/lib/AST/Interp/PrimType.cpp
clang/lib/AST/Interp/Record.h
clang/lib/AST/Interp/Source.cpp
clang/lib/AST/Interp/Source.h
clang/lib/AST/Interp/State.cpp
clang/lib/AST/Interp/State.h
clang/lib/AST/ByteCode/ByteCodeGenError.cpp
clang/lib/AST/ByteCode/ByteCodeGenError.h
clang/lib/AST/ByteCode/Context.cpp
clang/lib/AST/ByteCode/Context.h
clang/lib/AST/ByteCode/Descriptor.cpp
clang/lib/AST/ByteCode/Disasm.cpp
clang/lib/AST/ByteCode/EvalEmitter.h
clang/lib/AST/ByteCode/Frame.cpp
clang/lib/AST/ByteCode/Frame.h
clang/lib/AST/ByteCode/InterpState.h
clang/lib/AST/ByteCode/Opcode.h
clang/lib/AST/ByteCode/Pointer.cpp
clang/lib/AST/ByteCode/PrimType.cpp
clang/lib/AST/ByteCode/Record.h
clang/lib/AST/ByteCode/Source.cpp
clang/lib/AST/ByteCode/Source.h
clang/lib/AST/ByteCode/State.cpp
clang/lib/AST/ByteCode/State.h
clang/lib/ASTMatchers/GtestMatchers.cpp
clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
clang/lib/Basic/Attributes.cpp
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang-c/CXSourceLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ CINDEX_LINKAGE CXSourceLocation clang_getNullLocation(void);
CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1,
CXSourceLocation loc2);

/**
* Determine for two source locations if the first comes
* strictly before the second one in the source code.
*
* \returns non-zero if the first source location comes
* strictly before the second one, zero otherwise.
*/
CINDEX_LINKAGE unsigned clang_isBeforeInTranslationUnit(CXSourceLocation loc1,
CXSourceLocation loc2);

/**
* Returns non-zero if the given source location is in a system header.
*/
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/APINotes/APINotesReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ class APINotesReader {
ObjCSelectorRef Selector,
bool IsInstanceMethod);

/// Look for information regarding the given field of a C struct.
///
/// \param Name The name of the field.
///
/// \returns information about the field, if known.
VersionedInfo<FieldInfo> lookupField(ContextID CtxID, llvm::StringRef Name);

/// Look for information regarding the given C++ method in the given C++ tag
/// context.
///
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/APINotes/APINotesWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ class APINotesWriter {
void addCXXMethod(ContextID CtxID, llvm::StringRef Name,
const CXXMethodInfo &Info, llvm::VersionTuple SwiftVersion);

/// Add information about a specific C record field.
///
/// \param CtxID The context in which this field resides, i.e. a C/C++ tag.
/// \param Name The name of the field.
/// \param Info Information about this field.
void addField(ContextID CtxID, llvm::StringRef Name, const FieldInfo &Info,
llvm::VersionTuple SwiftVersion);

/// Add information about a global variable.
///
/// \param Name The name of this global variable.
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/APINotes/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,12 @@ class GlobalFunctionInfo : public FunctionInfo {
GlobalFunctionInfo() {}
};

/// Describes API notes data for a C/C++ record field.
class FieldInfo : public VariableInfo {
public:
FieldInfo() {}
};

/// Describes API notes data for a C++ method.
class CXXMethodInfo : public FunctionInfo {
public:
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ class ParamIdx {
static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
"ParamIdx does not fit its serialization type");

#include "clang/AST/Attrs.inc"
#include "clang/AST/Attrs.inc" // IWYU pragma: export

inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const Attr *At) {
Expand Down
39 changes: 27 additions & 12 deletions clang/include/clang/AST/DeclFriend.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ class FriendDecl final
// Location of the 'friend' specifier.
SourceLocation FriendLoc;

// Location of the '...', if present.
SourceLocation EllipsisLoc;

/// True if this 'friend' declaration is unsupported. Eventually we
/// will support every possible friend declaration, but for now we
/// silently ignore some and set this flag to authorize all access.
Expand All @@ -82,10 +85,11 @@ class FriendDecl final
unsigned NumTPLists : 31;

FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
SourceLocation FriendL,
SourceLocation FriendL, SourceLocation EllipsisLoc,
ArrayRef<TemplateParameterList *> FriendTypeTPLists)
: Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL),
UnsupportedFriend(false), NumTPLists(FriendTypeTPLists.size()) {
EllipsisLoc(EllipsisLoc), UnsupportedFriend(false),
NumTPLists(FriendTypeTPLists.size()) {
for (unsigned i = 0; i < NumTPLists; ++i)
getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
}
Expand All @@ -110,7 +114,7 @@ class FriendDecl final

static FriendDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_,
SourceLocation FriendL,
SourceLocation FriendL, SourceLocation EllipsisLoc = {},
ArrayRef<TemplateParameterList *> FriendTypeTPLists = std::nullopt);
static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
unsigned FriendTypeNumTPLists);
Expand Down Expand Up @@ -143,8 +147,24 @@ class FriendDecl final
return FriendLoc;
}

/// Retrieves the location of the '...', if present.
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }

/// Retrieves the source range for the friend declaration.
SourceRange getSourceRange() const override LLVM_READONLY {
if (TypeSourceInfo *TInfo = getFriendType()) {
SourceLocation StartL =
(NumTPLists == 0) ? getFriendLoc()
: getTrailingObjects<TemplateParameterList *>()[0]
->getTemplateLoc();
SourceLocation EndL = isPackExpansion() ? getEllipsisLoc()
: TInfo->getTypeLoc().getEndLoc();
return SourceRange(StartL, EndL);
}

if (isPackExpansion())
return SourceRange(getFriendLoc(), getEllipsisLoc());

if (NamedDecl *ND = getFriendDecl()) {
if (const auto *FD = dyn_cast<FunctionDecl>(ND))
return FD->getSourceRange();
Expand All @@ -158,15 +178,8 @@ class FriendDecl final
}
return SourceRange(getFriendLoc(), ND->getEndLoc());
}
else if (TypeSourceInfo *TInfo = getFriendType()) {
SourceLocation StartL =
(NumTPLists == 0) ? getFriendLoc()
: getTrailingObjects<TemplateParameterList *>()[0]
->getTemplateLoc();
return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
}
else
return SourceRange(getFriendLoc(), getLocation());

return SourceRange(getFriendLoc(), getLocation());
}

/// Determines if this friend kind is unsupported.
Expand All @@ -177,6 +190,8 @@ class FriendDecl final
UnsupportedFriend = Unsupported;
}

bool isPackExpansion() const { return EllipsisLoc.isValid(); }

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::Friend; }
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3888,6 +3888,7 @@ class BinaryOperator : public Expr {
/// Construct an empty binary operator.
explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
BinaryOperatorBits.Opc = BO_Comma;
BinaryOperatorBits.ExcludedOverflowPattern = false;
}

public:
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -2176,8 +2176,9 @@ class LambdaExpr final : public Expr,
const_child_range children() const;
};

/// An expression "T()" which creates a value-initialized rvalue of type
/// T, which is a non-class type. See (C++98 [5.2.3p2]).
/// An expression "T()" which creates an rvalue of a non-class type T.
/// For non-void T, the rvalue is value-initialized.
/// See (C++98 [5.2.3p2]).
class CXXScalarValueInitExpr : public Expr {
friend class ASTStmtReader;

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/OpenMPClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class OMPOneStmtClause : public Base {
};

/// Class that handles pre-initialization statement for some clauses, like
/// 'shedule', 'firstprivate' etc.
/// 'schedule', 'firstprivate' etc.
class OMPClauseWithPreInit {
friend class OMPClauseReader;

Expand Down
7 changes: 6 additions & 1 deletion clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1929,6 +1929,11 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
unsigned Kind : NumOfBuiltinTypeBits;
};

public:
static constexpr int FunctionTypeNumParamsWidth = 16;
static constexpr int FunctionTypeNumParamsLimit = (1 << 16) - 1;

protected:
/// FunctionTypeBitfields store various bits belonging to FunctionProtoType.
/// Only common bits are stored here. Additional uncommon bits are stored
/// in a trailing object after FunctionProtoType.
Expand Down Expand Up @@ -1966,7 +1971,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
/// According to [implimits] 8 bits should be enough here but this is
/// somewhat easy to exceed with metaprogramming and so we would like to
/// keep NumParams as wide as reasonably possible.
unsigned NumParams : 16;
unsigned NumParams : FunctionTypeNumParamsWidth;

/// The type of exception specification this function has.
LLVM_PREFERRED_TYPE(ExceptionSpecificationType)
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -6027,7 +6027,7 @@ AST_POLYMORPHIC_MATCHER_P2(
internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2) {
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
allOf(hasLHS(Matcher2), hasRHS(Matcher1))))
allOf(hasRHS(Matcher1), hasLHS(Matcher2))))
.matches(Node, Finder, Builder);
}

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Analysis/FlowSensitive/ASTOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ struct ReferencedDecls {
/// All variables with static storage duration, notably including static
/// member variables and static variables declared within a function.
llvm::DenseSet<const VarDecl *> Globals;
/// Local variables, not including parameters or static variables declared
/// within a function.
llvm::DenseSet<const VarDecl *> Locals;
/// Free functions and member functions which are referenced (but not
/// necessarily called).
llvm::DenseSet<const FunctionDecl *> Functions;
Expand Down
26 changes: 17 additions & 9 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -533,42 +533,42 @@ def BuiltinComplex : Builtin {
def IsGreater : Builtin {
let Spellings = ["__builtin_isgreater"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
CustomTypeChecking];
CustomTypeChecking, Constexpr];
let Prototype = "int(...)";
}

def IsGreaterEqual : Builtin {
let Spellings = ["__builtin_isgreaterequal"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
CustomTypeChecking];
CustomTypeChecking, Constexpr];
let Prototype = "int(...)";
}

def IsLess : Builtin {
let Spellings = ["__builtin_isless"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
CustomTypeChecking];
CustomTypeChecking, Constexpr];
let Prototype = "int(...)";
}

def IsLessEqual : Builtin {
let Spellings = ["__builtin_islessequal"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
CustomTypeChecking];
CustomTypeChecking, Constexpr];
let Prototype = "int(...)";
}

def IsLessGreater : Builtin {
let Spellings = ["__builtin_islessgreater"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
CustomTypeChecking];
CustomTypeChecking, Constexpr];
let Prototype = "int(...)";
}

def IsUnordered : Builtin {
let Spellings = ["__builtin_isunordered"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
CustomTypeChecking];
CustomTypeChecking, Constexpr];
let Prototype = "int(...)";
}

Expand Down Expand Up @@ -646,19 +646,21 @@ def IsFPClass : Builtin {
def Signbit : Builtin {
let Spellings = ["__builtin_signbit"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
CustomTypeChecking];
CustomTypeChecking, Constexpr];
let Prototype = "int(...)";
}

def SignbitF : Builtin {
let Spellings = ["__builtin_signbitf"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
Constexpr];
let Prototype = "int(float)";
}

def SignbitL : Builtin {
let Spellings = ["__builtin_signbitl"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const,
Constexpr];
let Prototype = "int(long double)";
}

Expand Down Expand Up @@ -4743,6 +4745,12 @@ def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}

def HLSLSaturate : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_elementwise_saturate"];
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}

// Builtins for XRay.
def XRayCustomEvent : Builtin {
let Spellings = ["__xray_customevent"];
Expand Down
15 changes: 15 additions & 0 deletions clang/include/clang/Basic/BuiltinsNVPTX.def
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,21 @@ TARGET_BUILTIN(__nvvm_f2bf16_rz_relu, "yf", "", AND(SM_80,PTX70))

TARGET_BUILTIN(__nvvm_f2tf32_rna, "ZUif", "", AND(SM_80,PTX70))

TARGET_BUILTIN(__nvvm_ff_to_e4m3x2_rn, "sff", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_ff_to_e4m3x2_rn_relu, "sff", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_ff_to_e5m2x2_rn, "sff", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_ff_to_e5m2x2_rn_relu, "sff", "", AND(SM_89,PTX81))

TARGET_BUILTIN(__nvvm_f16x2_to_e4m3x2_rn, "sV2h", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_f16x2_to_e4m3x2_rn_relu, "sV2h", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_f16x2_to_e5m2x2_rn, "sV2h", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_f16x2_to_e5m2x2_rn_relu, "sV2h", "", AND(SM_89,PTX81))

TARGET_BUILTIN(__nvvm_e4m3x2_to_f16x2_rn, "V2hs", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_e4m3x2_to_f16x2_rn_relu, "V2hs", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_e5m2x2_to_f16x2_rn, "V2hs", "", AND(SM_89,PTX81))
TARGET_BUILTIN(__nvvm_e5m2x2_to_f16x2_rn_relu, "V2hs", "", AND(SM_89,PTX81))

// Bitcast

BUILTIN(__nvvm_bitcast_f2i, "if", "")
Expand Down
44 changes: 44 additions & 0 deletions clang/include/clang/Basic/BuiltinsX86.def
Original file line number Diff line number Diff line change
Expand Up @@ -2217,6 +2217,50 @@ TARGET_BUILTIN(__builtin_ia32_vcvttps2ibs512_mask, "V16UiV16fV16UiUsIi", "nV:512
TARGET_BUILTIN(__builtin_ia32_vcvttps2iubs128_mask, "V4UiV4fV4UiUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvttps2iubs256_mask, "V8UiV8fV8UiUcIi", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvttps2iubs512_mask, "V16UiV16fV16UiUsIi", "nV:512:", "avx10.2-512")

// AVX10.2 CONVERT
TARGET_BUILTIN(__builtin_ia32_vcvt2ps2phx128_mask, "V8xV4fV4fV8xUc", "ncV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvt2ps2phx256_mask, "V16xV8fV8fV16xUsIi", "ncV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvt2ps2phx512_mask, "V32xV16fV16fV32xUiIi", "ncV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2bf8_128_mask, "V16cV16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2bf8_256_mask, "V16cV32cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2bf8_512_mask, "V32cV64cV32xV32cUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2bf8s_128_mask, "V16cV16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2bf8s_256_mask, "V16cV32cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2bf8s_512_mask, "V32cV64cV32xV32cUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2hf8_128_mask, "V16cV16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2hf8_256_mask, "V16cV32cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2hf8_512_mask, "V32cV64cV32xV32cUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2hf8s_128_mask, "V16cV16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2hf8s_256_mask, "V16cV32cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtbiasph2hf8s_512_mask, "V32cV64cV32xV32cUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2bf8_128, "V16cV8xV8x", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2bf8_256, "V32cV16xV16x", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2bf8_512, "V64cV32xV32x", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2bf8s_128, "V16cV8xV8x", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2bf8s_256, "V32cV16xV16x", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2bf8s_512, "V64cV32xV32x", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2hf8_128, "V16cV8xV8x", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2hf8_256, "V32cV16xV16x", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2hf8_512, "V64cV32xV32x", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2hf8s_128, "V16cV8xV8x", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2hf8s_256, "V32cV16xV16x", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtne2ph2hf8s_512, "V64cV32xV32x", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvthf8_2ph128_mask, "V8xV16cV8xUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvthf8_2ph256_mask, "V16xV16cV16xUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvthf8_2ph512_mask, "V32xV32cV32xUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2bf8_128_mask, "V16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2bf8_256_mask, "V16cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2bf8_512_mask, "V32cV32xV32cUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2bf8s_128_mask, "V16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2bf8s_256_mask, "V16cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2bf8s_512_mask, "V32cV32xV32cUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8_128_mask, "V16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8_256_mask, "V16cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8_512_mask, "V32cV32xV32cUi", "nV:512:", "avx10.2-512")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8s_128_mask, "V16cV8xV16cUc", "nV:128:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8s_256_mask, "V16cV16xV16cUs", "nV:256:", "avx10.2-256")
TARGET_BUILTIN(__builtin_ia32_vcvtneph2hf8s_512_mask, "V32cV32xV32cUi", "nV:512:", "avx10.2-512")
#undef BUILTIN
#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN
5 changes: 3 additions & 2 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ VALUE_CODEGENOPT(Name, Bits, Default)

CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
CODEGENOPT(Crel, 1, 0) ///< -Wa,--crel
CODEGENOPT(RelaxELFRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(SSE2AVX , 1, 0) ///< -msse2avx
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
Expand Down Expand Up @@ -178,6 +176,7 @@ CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled.
CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
CODEGENOPT(MipsMsa , 1, 0) ///< Set when -Wa,-mmsa is enabled.
CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is
///< enabled.
CODEGENOPT(NoWarn , 1, 0) ///< Set when -Wa,--no-warn is enabled.
Expand All @@ -194,6 +193,8 @@ CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is en
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
CODEGENOPT(PPCUseFullRegisterNames, 1, 0) ///< Print full register names in assembly
CODEGENOPT(X86RelaxRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(X86Sse2Avx , 1, 0) ///< -Wa,-msse2avx

/// When false, this attempts to generate code as if the result of an
/// overflowing conversion matches the overflowing behavior of a target's native
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -604,9 +604,6 @@ def warn_drv_unsupported_gpopt : Warning<
"ignoring '-mgpopt' option as it cannot be used with %select{|the implicit"
" usage of }0-mabicalls">,
InGroup<UnsupportedGPOpt>;
def warn_drv_unsupported_sdata : Warning<
"ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64">,
InGroup<OptionIgnored>;
def warn_drv_unsupported_longcalls : Warning<
"ignoring '-mlong-calls' option as it is not currently supported with "
"%select{|the implicit usage of }0-mabicalls">,
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ def ext_decomp_decl_empty : ExtWarn<
"ISO C++17 does not allow a decomposition group to be empty">,
InGroup<DiagGroup<"empty-decomposition">>;

def err_function_parameter_limit_exceeded : Error<
"too many function parameters; subsequent parameters will be ignored">;

// C++26 structured bindings
def ext_decl_attrs_on_binding : ExtWarn<
"an attribute specifier sequence attached to a structured binding declaration "
Expand Down Expand Up @@ -965,6 +968,12 @@ def warn_cxx23_delete_with_message : Warning<
"'= delete' with a message is incompatible with C++ standards before C++2c">,
DefaultIgnore, InGroup<CXXPre26Compat>;

def ext_variadic_friends : ExtWarn<
"variadic 'friend' declarations are a C++2c extension">, InGroup<CXX26>;
def warn_cxx23_variadic_friends : Warning<
"variadic 'friend' declarations are incompatible with C++ standards before C++2c">,
DefaultIgnore, InGroup<CXXPre26Compat>;

// C++11 default member initialization
def ext_nonstatic_member_init : ExtWarn<
"default member initializer for non-static data member is a C++11 "
Expand Down
15 changes: 12 additions & 3 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1741,6 +1741,10 @@ def ext_friend_tag_redecl_outside_namespace : ExtWarn<
"enclosing namespace is a Microsoft extension; add a nested name specifier">,
InGroup<MicrosoftUnqualifiedFriend>;
def err_pure_friend : Error<"friend declaration cannot have a pure-specifier">;
def err_friend_template_decl_multiple_specifiers: Error<
"a friend declaration that befriends a template must contain exactly one type-specifier">;
def friend_template_decl_malformed_pack_expansion : Error<
"friend declaration expands pack %0 that is declared it its own template parameter list">;

def err_invalid_base_in_interface : Error<
"interface type cannot inherit from "
Expand Down Expand Up @@ -5663,6 +5667,8 @@ def err_explicit_instantiation_internal_linkage : Error<
def err_explicit_instantiation_not_known : Error<
"explicit instantiation of %0 does not refer to a function template, "
"variable template, member function, member class, or static data member">;
def err_explicit_instantiation_no_candidate : Error<
"no viable candidate for explicit instantiation of %0">;
def note_explicit_instantiation_here : Note<
"explicit instantiation refers here">;
def err_explicit_instantiation_data_member_not_instantiated : Error<
Expand Down Expand Up @@ -9752,7 +9758,7 @@ def err_defaulted_special_member_quals : Error<
"have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers">;
def err_defaulted_special_member_explicit_object_mismatch : Error<
"the type of the explicit object parameter of an explicitly-defaulted "
"%select{copy|move}0 assignment operator should match the type of the class %1">;
"%select{copy|move}0 assignment operator should be reference to %1">;
def err_defaulted_special_member_volatile_param : Error<
"the parameter for an explicitly-defaulted %sub{select_special_member_kind}0 "
"may not be volatile">;
Expand Down Expand Up @@ -10062,8 +10068,9 @@ def warn_null_ret : Warning<
InGroup<NonNull>;

def err_lifetimebound_no_object_param : Error<
"'lifetimebound' attribute cannot be applied; %select{static |non-}0member "
"function has no implicit object parameter">;
"'lifetimebound' attribute cannot be applied; "
"%select{non-|static |explicit object }0"
"member function has no implicit object parameter">;
def err_lifetimebound_ctor_dtor : Error<
"'lifetimebound' attribute cannot be applied to a "
"%select{constructor|destructor}0">;
Expand Down Expand Up @@ -11160,6 +11167,8 @@ def err_omp_loop_diff_cxx : Error<
"upper and lower loop bounds">;
def err_omp_loop_cannot_use_stmt : Error<
"'%0' statement cannot be used in OpenMP for loop">;
def err_omp_loop_bad_collapse_var : Error<
"cannot use variable %1 in collapsed imperfectly-nested loop %select{init|condition|increment}0 statement">;
def err_omp_simd_region_cannot_use_stmt : Error<
"'%0' statement cannot be used in OpenMP simd region">;
def warn_omp_loop_64_bit_var : Warning<
Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,6 @@ VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
"stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
"signed integer overflow handling")
LANGOPT(IgnoreNegationOverflow, 1, 0, "ignore overflow caused by negation")
LANGOPT(SanitizeOverflowIdioms, 1, 1, "enable instrumentation for common overflow idioms")
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")

BENIGN_LANGOPT(ArrowDepth, 32, 256,
Expand Down
18 changes: 12 additions & 6 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2565,7 +2565,7 @@ defm sanitize_stats : BoolOption<"f", "sanitize-stats",
"Disable">,
BothFlags<[], [ClangOption], " sanitizer statistics gathering.">>,
Group<f_clang_Group>;
def fsanitize_overflow_pattern_exclusion_EQ : CommaJoined<["-"], "fsanitize-overflow-pattern-exclusion=">,
def fsanitize_undefined_ignore_overflow_pattern_EQ : CommaJoined<["-"], "fsanitize-undefined-ignore-overflow-pattern=">,
HelpText<"Specify the overflow patterns to exclude from artihmetic sanitizer instrumentation">,
Visibility<[ClangOption, CC1Option]>,
Values<"none,all,add-overflow-test,negated-unsigned-const,post-decr-while">,
Expand Down Expand Up @@ -5236,7 +5236,7 @@ let Flags = [TargetSpecific] in {
def msse2avx : Flag<["-"], "msse2avx">, Group<m_Group>,
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Specify that the assembler should encode SSE instructions with VEX prefix">,
MarshallingInfoFlag<CodeGenOpts<"SSE2AVX">>;
MarshallingInfoFlag<CodeGenOpts<"X86Sse2Avx">>;
} // let Flags = [TargetSpecific]

defm zvector : BoolFOption<"zvector",
Expand Down Expand Up @@ -5388,7 +5388,9 @@ def mmadd4 : Flag<["-"], "mmadd4">, Group<m_mips_Features_Group>,
def mno_madd4 : Flag<["-"], "mno-madd4">, Group<m_mips_Features_Group>,
HelpText<"Disable the generation of 4-operand madd.s, madd.d and related instructions.">;
def mmsa : Flag<["-"], "mmsa">, Group<m_mips_Features_Group>,
HelpText<"Enable MSA ASE (MIPS only)">;
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Enable MSA ASE (MIPS only)">,
MarshallingInfoFlag<CodeGenOpts<"MipsMsa">>;
def mno_msa : Flag<["-"], "mno-msa">, Group<m_mips_Features_Group>,
HelpText<"Disable MSA ASE (MIPS only)">;
def mmt : Flag<["-"], "mmt">, Group<m_mips_Features_Group>,
Expand Down Expand Up @@ -6149,6 +6151,10 @@ def mvis3 : Flag<["-"], "mvis3">, Group<m_sparc_Features_Group>;
def mno_vis3 : Flag<["-"], "mno-vis3">, Group<m_sparc_Features_Group>;
def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group<m_sparc_Features_Group>;
def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group<m_sparc_Features_Group>;
def mv8plus : Flag<["-"], "mv8plus">, Group<m_sparc_Features_Group>,
HelpText<"Enable V8+ mode, allowing use of 64-bit V9 instructions in 32-bit code">;
def mno_v8plus : Flag<["-"], "mno-v8plus">, Group<m_sparc_Features_Group>,
HelpText<"Disable V8+ mode">;
foreach i = 1 ... 7 in
def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group<m_sparc_Features_Group>,
HelpText<"Reserve the G"#i#" register (SPARC only)">;
Expand Down Expand Up @@ -7134,7 +7140,7 @@ def crel : Flag<["--"], "crel">,
MarshallingInfoFlag<CodeGenOpts<"Crel">>;
def mrelax_relocations_no : Flag<["-"], "mrelax-relocations=no">,
HelpText<"Disable x86 relax relocations">,
MarshallingInfoNegativeFlag<CodeGenOpts<"RelaxELFRelocations">>;
MarshallingInfoNegativeFlag<CodeGenOpts<"X86RelaxRelocations">>;
def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
HelpText<"Save temporary labels in the symbol table. "
"Note this may change .s semantics and shouldn't generally be used "
Expand Down Expand Up @@ -7960,7 +7966,7 @@ def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-
MarshallingInfoFlag<LangOpts<"SetVisibilityForExternDecls">>;
def fbracket_depth : Separate<["-"], "fbracket-depth">,
HelpText<"Maximum nesting level for parentheses, brackets, and braces">,
MarshallingInfoInt<LangOpts<"BracketDepth">, "256">;
MarshallingInfoInt<LangOpts<"BracketDepth">, "2048">;
defm const_strings : BoolOption<"f", "const-strings",
LangOpts<"ConstStrings">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use">,
Expand Down Expand Up @@ -8841,7 +8847,7 @@ def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARA
Visibility<[DXCOption, ClangOption, CC1Option]>,
HelpText<"Override validator version for module. Format: <major.minor>;"
"Default: DXIL.dll version or current internal version">,
MarshallingInfoString<TargetOpts<"DxilValidatorVersion">>;
MarshallingInfoString<TargetOpts<"DxilValidatorVersion">, "\"1.8\"">;
def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
HelpText<"Set target profile">,
Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7,"
Expand Down
25 changes: 12 additions & 13 deletions clang/include/clang/ExtractAPI/API.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,13 @@
#define LLVM_CLANG_EXTRACTAPI_API_H

#include "clang/AST/Availability.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/RawCommentList.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/ExtractAPI/DeclarationFragments.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include <cstddef>
#include <iterator>
Expand Down Expand Up @@ -328,6 +320,8 @@ class RecordContext {
/// chain.
void stealRecordChain(RecordContext &Other);

void removeFromRecordChain(APIRecord *Record);

APIRecord::RecordKind getKind() const { return Kind; }

struct record_iterator {
Expand Down Expand Up @@ -1426,10 +1420,15 @@ class APISet {
typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);

ArrayRef<const APIRecord *> getTopLevelRecords() const {
return TopLevelRecords;
auto getTopLevelRecords() const {
return llvm::iterator_range<decltype(TopLevelRecords)::iterator>(
TopLevelRecords);
}

void removeRecord(StringRef USR);

void removeRecord(APIRecord *Record);

APISet(const llvm::Triple &Target, Language Lang,
const std::string &ProductName)
: Target(Target), Lang(Lang), ProductName(ProductName) {}
Expand All @@ -1456,7 +1455,7 @@ class APISet {
// lives in the BumpPtrAllocator.
using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
std::vector<const APIRecord *> TopLevelRecords;
llvm::SmallPtrSet<const APIRecord *, 32> TopLevelRecords;

public:
const std::string ProductName;
Expand All @@ -1482,7 +1481,7 @@ APISet::createRecord(StringRef USR, StringRef Name,
dyn_cast_if_present<RecordContext>(Record->Parent.Record))
ParentContext->addToRecordChain(Record);
else
TopLevelRecords.push_back(Record);
TopLevelRecords.insert(Record);
} else {
Record = dyn_cast<RecordTy>(Result.first->second.get());
}
Expand Down
37 changes: 35 additions & 2 deletions clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace impl {

template <typename Derived>
class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
using Base = RecursiveASTVisitor<Derived>;

protected:
ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
: Context(Context), API(API) {}
Expand Down Expand Up @@ -81,8 +83,10 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {

bool VisitNamespaceDecl(const NamespaceDecl *Decl);

bool TraverseRecordDecl(RecordDecl *Decl);
bool VisitRecordDecl(const RecordDecl *Decl);

bool TraverseCXXRecordDecl(CXXRecordDecl *Decl);
bool VisitCXXRecordDecl(const CXXRecordDecl *Decl);

bool VisitCXXMethodDecl(const CXXMethodDecl *Decl);
Expand Down Expand Up @@ -240,7 +244,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {

bool isEmbeddedInVarDeclarator(const TagDecl &D) {
return D.getName().empty() && getTypedefName(&D).empty() &&
D.isEmbeddedInDeclarator();
D.isEmbeddedInDeclarator() && !D.isFreeStanding();
}

void maybeMergeWithAnonymousTag(const DeclaratorDecl &D,
Expand All @@ -252,8 +256,10 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
clang::index::generateUSRForDecl(Tag, TagUSR);
if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
API.findRecordForUSR(TagUSR))) {
if (Record->IsEmbeddedInVarDeclarator)
if (Record->IsEmbeddedInVarDeclarator) {
NewRecordContext->stealRecordChain(*Record);
API.removeRecord(Record);
}
}
}
};
Expand Down Expand Up @@ -548,6 +554,19 @@ bool ExtractAPIVisitorBase<Derived>::VisitNamespaceDecl(
return true;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::TraverseRecordDecl(RecordDecl *Decl) {
bool Ret = Base::TraverseRecordDecl(Decl);

if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
SmallString<128> USR;
index::generateUSRForDecl(Decl, USR);
API.removeRecord(USR);
}

return Ret;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
Expand Down Expand Up @@ -588,6 +607,20 @@ bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
return true;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::TraverseCXXRecordDecl(
CXXRecordDecl *Decl) {
bool Ret = Base::TraverseCXXRecordDecl(Decl);

if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
SmallString<128> USR;
index::generateUSRForDecl(Decl, USR);
API.removeRecord(USR);
}

return Ret;
}

template <typename Derived>
bool ExtractAPIVisitorBase<Derived>::VisitCXXRecordDecl(
const CXXRecordDecl *Decl) {
Expand Down
Loading