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
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
87 changes: 71 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 Down Expand Up @@ -658,22 +699,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
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
12 changes: 9 additions & 3 deletions 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 @@ -271,15 +270,13 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
// specialized template. Implicit ones are filtered out by RAV.
bool
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *CTSD) {
// if (CTSD->isExplicitSpecialization())
if (clang::isTemplateExplicitInstantiationOrSpecialization(
CTSD->getTemplateSpecializationKind()))
report(CTSD->getLocation(),
CTSD->getSpecializedTemplate()->getTemplatedDecl());
return true;
}
bool VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *VTSD) {
// if (VTSD->isExplicitSpecialization())
if (clang::isTemplateExplicitInstantiationOrSpecialization(
VTSD->getTemplateSpecializationKind()))
report(VTSD->getLocation(),
Expand Down Expand Up @@ -352,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
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
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
1 change: 1 addition & 0 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
38 changes: 38 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ C++ Specific Potentially Breaking Changes
`-Wno-enum-constexpr-conversion`, to allow for a transition period for users.
Now, in Clang 20, **it is no longer possible to suppress the diagnostic**.

- Extraneous template headers are now ill-formed by default.
This error can be disable with ``-Wno-error=extraneous-template-head``.

.. code-block:: c++

template <> // error: extraneous template head
template <typename T>
void f();

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

Expand All @@ -81,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 @@ -117,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 Down Expand Up @@ -147,6 +161,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 Down Expand Up @@ -175,6 +193,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 @@ -200,6 +221,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 @@ -245,10 +268,17 @@ 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).

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

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

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

Expand Down Expand Up @@ -302,6 +332,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 @@ -348,6 +384,8 @@ clang-format

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
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
4 changes: 4 additions & 0 deletions clang/include/clang/AST/Availability.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ struct AvailabilityInfo {
return UnconditionallyUnavailable;
}

/// Augments the existing information with additional constraints provided by
/// \c Other.
void mergeWith(AvailabilityInfo Other);

AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
VersionTuple O, bool U, bool UD, bool UU)
: Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O),
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3206,6 +3206,10 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
/// Set the C++11 in-class initializer for this member.
void setInClassInitializer(Expr *NewInit);

/// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns
/// \p nullptr if either the attribute or the field doesn't exist.
const FieldDecl *findCountedByField() const;

private:
void setLazyInClassInitializer(LazyDeclStmtPtr NewInit);

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
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,15 @@ def BTFTypeTag : TypeAttr {
let LangOpts = [COnly];
}

def BPFFastCall : InheritableAttr,
TargetSpecificAttr<TargetBPF> {
let Spellings = [Clang<"bpf_fastcall">];
let Subjects = SubjectList<[FunctionLike]>;
let Documentation = [BPFFastCallDocs];
let LangOpts = [COnly];
let SimpleHandler = 1;
}

def WebAssemblyExportName : InheritableAttr,
TargetSpecificAttr<TargetWebAssembly> {
let Spellings = [Clang<"export_name">];
Expand Down
19 changes: 19 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -2345,6 +2345,25 @@ section.
}];
}

def BPFFastCallDocs : Documentation {
let Category = DocCatType;
let Content = [{
Functions annotated with this attribute are likely to be inlined by BPF JIT.
It is assumed that inlined implementation uses less caller saved registers,
than a regular function.
Specifically, the following registers are likely to be preserved:
- ``R0`` if function return value is ``void``;
- ``R2-R5` if function takes 1 argument;
- ``R3-R5` if function takes 2 arguments;
- ``R4-R5` if function takes 3 arguments;
- ``R5`` if function takes 4 arguments;

For such functions Clang generates code pattern that allows BPF JIT
to recognize and remove unnecessary spills and fills of the preserved
registers.
}];
}

def MipsInterruptDocs : Documentation {
let Category = DocCatFunction;
let Heading = "interrupt (MIPS)";
Expand Down
20 changes: 11 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
4 changes: 2 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 @@ -194,6 +192,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
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,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
16 changes: 12 additions & 4 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 @@ -5428,7 +5432,8 @@ def err_template_spec_extra_headers : Error<
"extraneous template parameter list in template specialization or "
"out-of-line template definition">;
def ext_template_spec_extra_headers : ExtWarn<
"extraneous template parameter list in template specialization">;
"extraneous template parameter list in template specialization">,
InGroup<DiagGroup<"extraneous-template-head">>, DefaultError;
def note_explicit_template_spec_does_not_need_header : Note<
"'template<>' header not required for explicitly-specialized class %0 "
"declared here">;
Expand Down Expand Up @@ -9751,7 +9756,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 @@ -10061,8 +10066,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 @@ -11159,6 +11165,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
10 changes: 7 additions & 3 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5231,7 +5231,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 @@ -6144,6 +6144,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 @@ -7129,7 +7133,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 @@ -8836,7 +8840,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
34 changes: 29 additions & 5 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -2858,7 +2858,8 @@ struct FormatStyle {
PPDirectiveIndentStyle IndentPPDirectives;

/// 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``.
/// \code
Expand Down Expand Up @@ -3944,22 +3945,45 @@ struct FormatStyle {
/// ``IndentRequires`` option is only used if the ``requires`` is put on the
/// start of a line.
enum RequiresClausePositionStyle : int8_t {
/// Always put the ``requires`` clause on its own line.
/// Always put the ``requires`` clause on its own line (possibly followed by
/// a semicolon).
/// \code
/// 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>
/// {...
/// \endcode
RCPS_OwnLine,
/// As with ``OwnLine``, except, unless otherwise prohibited, place a
/// following open brace (of a function definition) to follow on the same
/// line.
/// \code
/// 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) {
/// ...
/// \endcode
RCPS_OwnLineWithBrace,
/// Try to put the clause together with the preceding part of a declaration.
/// For class templates: stick to the template declaration.
/// For function templates: stick to the template declaration.
Expand Down
50 changes: 0 additions & 50 deletions clang/include/clang/Rewrite/Core/DeltaTree.h

This file was deleted.

11 changes: 7 additions & 4 deletions clang/include/clang/Rewrite/Core/HTMLRewrite.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
#include "clang/Basic/SourceLocation.h"
#include <string>

namespace llvm {
class RewriteBuffer;
} // namespace llvm

namespace clang {

class Rewriter;
class RewriteBuffer;
class Preprocessor;

namespace html {
Expand Down Expand Up @@ -53,9 +56,9 @@ namespace html {

/// HighlightRange - This is the same as the above method, but takes
/// decomposed file locations.
void HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
const char *BufferStart,
const char *StartTag, const char *EndTag);
void HighlightRange(llvm::RewriteBuffer &RB, unsigned B, unsigned E,
const char *BufferStart, const char *StartTag,
const char *EndTag);

/// EscapeText - HTMLize a specified file so that special characters are
/// are translated so that they are not interpreted as HTML tags.
Expand Down
223 changes: 0 additions & 223 deletions clang/include/clang/Rewrite/Core/RewriteRope.h

This file was deleted.

19 changes: 10 additions & 9 deletions clang/include/clang/Rewrite/Core/Rewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Rewrite/Core/RewriteBuffer.h"
#include "llvm/ADT/RewriteBuffer.h"
#include "llvm/ADT/StringRef.h"
#include <map>
#include <string>
Expand All @@ -32,7 +32,7 @@ class SourceManager;
class Rewriter {
SourceManager *SourceMgr = nullptr;
const LangOptions *LangOpts = nullptr;
std::map<FileID, RewriteBuffer> RewriteBuffers;
std::map<FileID, llvm::RewriteBuffer> RewriteBuffers;

public:
struct RewriteOptions {
Expand All @@ -49,7 +49,7 @@ class Rewriter {
///
/// FIXME: This sometimes corrupts the file's rewrite buffer due to
/// incorrect indexing in the implementation (see the FIXME in
/// clang::RewriteBuffer::RemoveText). Moreover, it's inefficient because
/// llvm::RewriteBuffer::RemoveText). Moreover, it's inefficient because
/// it must scan the buffer from the beginning to find the start of the
/// line. When feasible, it's better for the caller to check for a blank
/// line and then, if found, expand the removal range to include it.
Expand All @@ -62,8 +62,9 @@ class Rewriter {
RewriteOptions() {}
};

using buffer_iterator = std::map<FileID, RewriteBuffer>::iterator;
using const_buffer_iterator = std::map<FileID, RewriteBuffer>::const_iterator;
using buffer_iterator = std::map<FileID, llvm::RewriteBuffer>::iterator;
using const_buffer_iterator =
std::map<FileID, llvm::RewriteBuffer>::const_iterator;

explicit Rewriter() = default;
explicit Rewriter(SourceManager &SM, const LangOptions &LO)
Expand Down Expand Up @@ -191,13 +192,13 @@ class Rewriter {
/// buffer, and allows you to write on it directly. This is useful if you
/// want efficient low-level access to apis for scribbling on one specific
/// FileID's buffer.
RewriteBuffer &getEditBuffer(FileID FID);
llvm::RewriteBuffer &getEditBuffer(FileID FID);

/// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
/// If no modification has been made to it, return null.
const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
std::map<FileID, RewriteBuffer>::const_iterator I =
RewriteBuffers.find(FID);
const llvm::RewriteBuffer *getRewriteBufferFor(FileID FID) const {
std::map<FileID, llvm::RewriteBuffer>::const_iterator I =
RewriteBuffers.find(FID);
return I == RewriteBuffers.end() ? nullptr : &I->second;
}

Expand Down
331 changes: 147 additions & 184 deletions clang/include/clang/Sema/Sema.h

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions clang/include/clang/Sema/SemaAMDGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
#ifndef LLVM_CLANG_SEMA_SEMAAMDGPU_H
#define LLVM_CLANG_SEMA_SEMAAMDGPU_H

#include "clang/AST/Attr.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class AttributeCommonInfo;
class ParsedAttr;

class SemaAMDGPU : public SemaBase {
public:
SemaAMDGPU(Sema &S);
Expand Down
19 changes: 11 additions & 8 deletions clang/include/clang/Sema/SemaARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@
#ifndef LLVM_CLANG_SEMA_SEMAARM_H
#define LLVM_CLANG_SEMA_SEMAARM_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <tuple>

namespace llvm {
template <typename T, unsigned N> class SmallVector;
} // namespace llvm

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaARM : public SemaBase {
public:
Expand Down Expand Up @@ -60,10 +63,10 @@ class SemaARM : public SemaBase {
unsigned ExpectedFieldNum, bool AllowName);
bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);

bool MveAliasValid(unsigned BuiltinID, StringRef AliasName);
bool CdeAliasValid(unsigned BuiltinID, StringRef AliasName);
bool SveAliasValid(unsigned BuiltinID, StringRef AliasName);
bool SmeAliasValid(unsigned BuiltinID, StringRef AliasName);
bool MveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
bool CdeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
bool SveAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
bool SmeAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
void handleBuiltinAliasAttr(Decl *D, const ParsedAttr &AL);
void handleNewAttr(Decl *D, const ParsedAttr &AL);
void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL);
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaAVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAAVR_H
#define LLVM_CLANG_SEMA_SEMAAVR_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaAVR : public SemaBase {
Expand Down
4 changes: 1 addition & 3 deletions clang/include/clang/Sema/SemaBPF.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMABPF_H
#define LLVM_CLANG_SEMA_SEMABPF_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
Expand Down
20 changes: 15 additions & 5 deletions clang/include/clang/Sema/SemaCUDA.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,34 @@
#ifndef LLVM_CLANG_SEMA_SEMACUDA_H
#define LLVM_CLANG_SEMA_SEMACUDA_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/Redeclarable.h"
#include "clang/Basic/Cuda.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include <string>
#include <utility>

namespace clang {
namespace sema {
class Capture;
} // namespace sema

class ASTReader;
class ASTWriter;
enum class CUDAFunctionTarget;
enum class CXXSpecialMemberKind;
class ParsedAttributesView;
class Scope;

class SemaCUDA : public SemaBase {
public:
Expand Down
10 changes: 5 additions & 5 deletions clang/include/clang/Sema/SemaCodeCompletion.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,26 @@
#ifndef LLVM_CLANG_SEMA_SEMACODECOMPLETION_H
#define LLVM_CLANG_SEMA_SEMACODECOMPLETION_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/StringRef.h"
#include <optional>

namespace clang {
class DeclGroupRef;
class MacroInfo;
class Scope;
class TemplateName;

class SemaCodeCompletion : public SemaBase {
public:
Expand Down
11 changes: 5 additions & 6 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@
#ifndef LLVM_CLANG_SEMA_SEMAHLSL_H
#define LLVM_CLANG_SEMA_SEMAHLSL_H

#include "clang/AST/ASTFwd.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/TargetParser/Triple.h"
#include <initializer_list>

namespace clang {
class AttributeCommonInfo;
class IdentifierInfo;
class ParsedAttr;
class Scope;

class SemaHLSL : public SemaBase {
public:
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaHexagon.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMAHEXAGON_H
#define LLVM_CLANG_SEMA_SEMAHEXAGON_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaLoongArch.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
#ifndef LLVM_CLANG_SEMA_SEMALOONGARCH_H
#define LLVM_CLANG_SEMA_SEMALOONGARCH_H

#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class TargetInfo;

class SemaLoongArch : public SemaBase {
public:
SemaLoongArch(Sema &S);
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaM68k.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAM68K_H
#define LLVM_CLANG_SEMA_SEMAM68K_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaM68k : public SemaBase {
Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Sema/SemaMIPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@
#ifndef LLVM_CLANG_SEMA_SEMAMIPS_H
#define LLVM_CLANG_SEMA_SEMAMIPS_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaMIPS : public SemaBase {
public:
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaMSP430.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAMSP430_H
#define LLVM_CLANG_SEMA_SEMAMSP430_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaMSP430 : public SemaBase {
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaNVPTX.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
#ifndef LLVM_CLANG_SEMA_SEMANVPTX_H
#define LLVM_CLANG_SEMA_SEMANVPTX_H

#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class TargetInfo;

class SemaNVPTX : public SemaBase {
public:
SemaNVPTX(Sema &S);
Expand Down
16 changes: 9 additions & 7 deletions clang/include/clang/Sema/SemaObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
#ifndef LLVM_CLANG_SEMA_SEMAOBJC_H
#define LLVM_CLANG_SEMA_SEMAOBJC_H

#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Type.h"
Expand All @@ -27,24 +24,29 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ObjCMethodList.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Redeclaration.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <memory>
#include <optional>
#include <type_traits>
#include <utility>

namespace clang {

class AttributeCommonInfo;
class AvailabilitySpec;
enum class CheckedConversionKind;
class DeclGroupRef;
class LookupResult;
struct ObjCDictionaryElement;
class ParsedAttr;
class ParsedAttributesView;
class Scope;
struct SkipBodyInfo;

class SemaObjC : public SemaBase {
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@

#include "clang/AST/DeclGroup.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <optional>
#include <utility>
#include <variant>

namespace clang {
class IdentifierInfo;
class OpenACCClause;

class SemaOpenACC : public SemaBase {
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaOpenCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#ifndef LLVM_CLANG_SEMA_SEMAOPENCL_H
#define LLVM_CLANG_SEMA_SEMAOPENCL_H

#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Decl;
class ParsedAttr;

class SemaOpenCL : public SemaBase {
Expand Down
19 changes: 10 additions & 9 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,36 @@
#ifndef LLVM_CLANG_SEMA_SEMAOPENMP_H
#define LLVM_CLANG_SEMA_SEMAOPENMP_H

#include "clang/AST/ASTFwd.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Frontend/OpenMP/OMP.h.inc"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include <optional>
#include <string>
#include <utility>

namespace clang {
namespace sema {
class FunctionScopeInfo;
} // namespace sema

class DeclContext;
class DeclGroupRef;
class ParsedAttr;
class Scope;

class SemaOpenMP : public SemaBase {
public:
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Sema/SemaPPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
#ifndef LLVM_CLANG_SEMA_SEMAPPC_H
#define LLVM_CLANG_SEMA_SEMAPPC_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class TargetInfo;

class SemaPPC : public SemaBase {
public:
SemaPPC(Sema &S);
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/SemaPseudoObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
#ifndef LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H
#define LLVM_CLANG_SEMA_SEMAPSEUDOOBJECT_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/OperationKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class Scope;

class SemaPseudoObject : public SemaBase {
public:
Expand Down
13 changes: 8 additions & 5 deletions clang/include/clang/Sema/SemaRISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@
#ifndef LLVM_CLANG_SEMA_SEMARISCV_H
#define LLVM_CLANG_SEMA_SEMARISCV_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/RISCVIntrinsicManager.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <memory>

namespace clang {
namespace sema {
class RISCVIntrinsicManager;
} // namespace sema

class ParsedAttr;
class TargetInfo;

class SemaRISCV : public SemaBase {
public:
Expand All @@ -39,7 +42,7 @@ class SemaRISCV : public SemaBase {
bool isValidRVVBitcast(QualType srcType, QualType destType);

void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
bool isAliasValid(unsigned BuiltinID, StringRef AliasName);
bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);

/// Indicate RISC-V vector builtin functions enabled or not.
bool DeclareRVVBuiltins = false;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMASYCL_H
#define LLVM_CLANG_SEMA_SEMASYCL_H

#include "clang/AST/Decl.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/SemaSwift.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
#ifndef LLVM_CLANG_SEMA_SEMASWIFT_H
#define LLVM_CLANG_SEMA_SEMASWIFT_H

#include "clang/AST/Attr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaBase.h"
#include "llvm/ADT/StringRef.h"

namespace clang {
class AttributeCommonInfo;
class Decl;
enum class ParameterABI;
class ParsedAttr;
class SwiftNameAttr;

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaSystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_SEMA_SEMASYSTEMZ_H
#define LLVM_CLANG_SEMA_SEMASYSTEMZ_H

#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
Expand Down
9 changes: 4 additions & 5 deletions clang/include/clang/Sema/SemaWasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
#ifndef LLVM_CLANG_SEMA_SEMAWASM_H
#define LLVM_CLANG_SEMA_SEMAWASM_H

#include "clang/AST/Attr.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaWasm : public SemaBase {
public:
SemaWasm(Sema &S);
Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Sema/SemaX86.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
#ifndef LLVM_CLANG_SEMA_SEMAX86_H
#define LLVM_CLANG_SEMA_SEMAX86_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTFwd.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaBase.h"

namespace clang {
class ParsedAttr;
class TargetInfo;

class SemaX86 : public SemaBase {
public:
Expand Down
20 changes: 19 additions & 1 deletion clang/lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 29; // SwiftConformsTo
const uint16_t VERSION_MINOR = 30; // fields

const uint8_t kSwiftCopyable = 1;
const uint8_t kSwiftNonCopyable = 2;
Expand Down Expand Up @@ -72,6 +72,10 @@ enum BlockID {
/// used in other tables.
OBJC_SELECTOR_BLOCK_ID,

/// The fields data block, which maps names fields of C records to
/// information about the field.
FIELD_BLOCK_ID,

/// The global variables data block, which maps global variable names to
/// information about the global variable.
GLOBAL_VARIABLE_BLOCK_ID,
Expand Down Expand Up @@ -199,6 +203,20 @@ using CXXMethodDataLayout =
>;
} // namespace cxx_method_block

namespace field_block {
enum {
FIELD_DATA = 1,
};

using FieldDataLayout =
llvm::BCRecordLayout<FIELD_DATA, // record ID
llvm::BCVBR<16>, // table offset within the blob (see
// below)
llvm::BCBlob // map from C (context id, name)
// tuples to C field information
>;
} // namespace field_block

namespace objc_selector_block {
enum {
OBJC_SELECTOR_DATA = 1,
Expand Down
130 changes: 130 additions & 0 deletions clang/lib/APINotes/APINotesReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,28 @@ class ObjCPropertyTableInfo
}
};

/// Used to deserialize the on-disk C record field table.
class FieldTableInfo
: public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
public:
static internal_key_type ReadKey(const uint8_t *Data, unsigned Length) {
auto CtxID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
auto NameID = endian::readNext<uint32_t, llvm::endianness::little>(Data);
return {CtxID, NameID};
}

hash_value_type ComputeHash(internal_key_type Key) {
return static_cast<size_t>(Key.hashValue());
}

static FieldInfo readUnversioned(internal_key_type Key,
const uint8_t *&Data) {
FieldInfo Info;
ReadVariableInfo(Data, Info);
return Info;
}
};

/// Read serialized ParamInfo.
void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) {
ReadVariableInfo(Data, Info);
Expand Down Expand Up @@ -653,6 +675,12 @@ class APINotesReader::Implementation {
/// The Objective-C property table.
std::unique_ptr<SerializedObjCPropertyTable> ObjCPropertyTable;

using SerializedFieldTable =
llvm::OnDiskIterableChainedHashTable<FieldTableInfo>;

/// The C record field table.
std::unique_ptr<SerializedFieldTable> FieldTable;

using SerializedObjCMethodTable =
llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;

Expand Down Expand Up @@ -720,6 +748,8 @@ class APINotesReader::Implementation {
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readCXXMethodBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readFieldBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor,
llvm::SmallVectorImpl<uint64_t> &Scratch);
bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor,
Expand Down Expand Up @@ -1252,6 +1282,81 @@ bool APINotesReader::Implementation::readCXXMethodBlock(
return false;
}

bool APINotesReader::Implementation::readFieldBlock(
llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
if (Cursor.EnterSubBlock(FIELD_BLOCK_ID))
return true;

llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance();
if (!MaybeNext) {
// FIXME this drops the error on the floor.
consumeError(MaybeNext.takeError());
return false;
}
llvm::BitstreamEntry Next = MaybeNext.get();
while (Next.Kind != llvm::BitstreamEntry::EndBlock) {
if (Next.Kind == llvm::BitstreamEntry::Error)
return true;

if (Next.Kind == llvm::BitstreamEntry::SubBlock) {
// Unknown sub-block, possibly for use by a future version of the
// API notes format.
if (Cursor.SkipBlock())
return true;

MaybeNext = Cursor.advance();
if (!MaybeNext) {
// FIXME this drops the error on the floor.
consumeError(MaybeNext.takeError());
return false;
}
Next = MaybeNext.get();
continue;
}

Scratch.clear();
llvm::StringRef BlobData;
llvm::Expected<unsigned> MaybeKind =
Cursor.readRecord(Next.ID, Scratch, &BlobData);
if (!MaybeKind) {
// FIXME this drops the error on the floor.
consumeError(MaybeKind.takeError());
return false;
}
unsigned Kind = MaybeKind.get();
switch (Kind) {
case field_block::FIELD_DATA: {
// Already saw field table.
if (FieldTable)
return true;

uint32_t tableOffset;
field_block::FieldDataLayout::readRecord(Scratch, tableOffset);
auto base = reinterpret_cast<const uint8_t *>(BlobData.data());

FieldTable.reset(SerializedFieldTable::Create(
base + tableOffset, base + sizeof(uint32_t), base));
break;
}

default:
// Unknown record, possibly for use by a future version of the
// module format.
break;
}

MaybeNext = Cursor.advance();
if (!MaybeNext) {
// FIXME this drops the error on the floor.
consumeError(MaybeNext.takeError());
return false;
}
Next = MaybeNext.get();
}

return false;
}

bool APINotesReader::Implementation::readObjCSelectorBlock(
llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) {
if (Cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID))
Expand Down Expand Up @@ -1812,6 +1917,14 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer,
}
break;

case FIELD_BLOCK_ID:
if (!HasValidControlBlock ||
Implementation->readFieldBlock(Cursor, Scratch)) {
Failed = true;
return;
}
break;

case OBJC_SELECTOR_BLOCK_ID:
if (!HasValidControlBlock ||
Implementation->readObjCSelectorBlock(Cursor, Scratch)) {
Expand Down Expand Up @@ -2031,6 +2144,23 @@ auto APINotesReader::lookupObjCMethod(ContextID CtxID, ObjCSelectorRef Selector,
return {Implementation->SwiftVersion, *Known};
}

auto APINotesReader::lookupField(ContextID CtxID, llvm::StringRef Name)
-> VersionedInfo<FieldInfo> {
if (!Implementation->FieldTable)
return std::nullopt;

std::optional<IdentifierID> NameID = Implementation->getIdentifier(Name);
if (!NameID)
return std::nullopt;

auto Known = Implementation->FieldTable->find(
SingleDeclTableKey(CtxID.Value, *NameID));
if (Known == Implementation->FieldTable->end())
return std::nullopt;

return {Implementation->SwiftVersion, *Known};
}

auto APINotesReader::lookupCXXMethod(ContextID CtxID, llvm::StringRef Name)
-> VersionedInfo<CXXMethodInfo> {
if (!Implementation->CXXMethodTable)
Expand Down
73 changes: 73 additions & 0 deletions clang/lib/APINotes/APINotesWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ class APINotesWriter::Implementation {
llvm::SmallVector<std::pair<VersionTuple, ObjCPropertyInfo>, 1>>
ObjCProperties;

/// Information about C record fields.
///
/// Indexed by the context ID and name ID.
llvm::DenseMap<SingleDeclTableKey,
llvm::SmallVector<std::pair<VersionTuple, FieldInfo>, 1>>
Fields;

/// Information about Objective-C methods.
///
/// Indexed by the context ID, selector ID, and Boolean (stored as a char)
Expand Down Expand Up @@ -158,6 +165,7 @@ class APINotesWriter::Implementation {
void writeObjCPropertyBlock(llvm::BitstreamWriter &Stream);
void writeObjCMethodBlock(llvm::BitstreamWriter &Stream);
void writeCXXMethodBlock(llvm::BitstreamWriter &Stream);
void writeFieldBlock(llvm::BitstreamWriter &Stream);
void writeObjCSelectorBlock(llvm::BitstreamWriter &Stream);
void writeGlobalVariableBlock(llvm::BitstreamWriter &Stream);
void writeGlobalFunctionBlock(llvm::BitstreamWriter &Stream);
Expand Down Expand Up @@ -190,6 +198,7 @@ void APINotesWriter::Implementation::writeToStream(llvm::raw_ostream &OS) {
writeObjCPropertyBlock(Stream);
writeObjCMethodBlock(Stream);
writeCXXMethodBlock(Stream);
writeFieldBlock(Stream);
writeObjCSelectorBlock(Stream);
writeGlobalVariableBlock(Stream);
writeGlobalFunctionBlock(Stream);
Expand Down Expand Up @@ -858,6 +867,62 @@ void APINotesWriter::Implementation::writeCXXMethodBlock(
}
}

namespace {
/// Used to serialize the on-disk C field table.
class FieldTableInfo
: public VersionedTableInfo<FieldTableInfo, SingleDeclTableKey, FieldInfo> {
public:
unsigned getKeyLength(key_type_ref) {
return sizeof(uint32_t) + sizeof(uint32_t);
}

void EmitKey(raw_ostream &OS, key_type_ref Key, unsigned) {
llvm::support::endian::Writer writer(OS, llvm::endianness::little);
writer.write<uint32_t>(Key.parentContextID);
writer.write<uint32_t>(Key.nameID);
}

hash_value_type ComputeHash(key_type_ref key) {
return static_cast<size_t>(key.hashValue());
}

unsigned getUnversionedInfoSize(const FieldInfo &FI) {
return getVariableInfoSize(FI);
}

void emitUnversionedInfo(raw_ostream &OS, const FieldInfo &FI) {
emitVariableInfo(OS, FI);
}
};
} // namespace

void APINotesWriter::Implementation::writeFieldBlock(
llvm::BitstreamWriter &Stream) {
llvm::BCBlockRAII Scope(Stream, FIELD_BLOCK_ID, 3);

if (Fields.empty())
return;

{
llvm::SmallString<4096> HashTableBlob;
uint32_t Offset;
{
llvm::OnDiskChainedHashTableGenerator<FieldTableInfo> Generator;
for (auto &FD : Fields)
Generator.insert(FD.first, FD.second);

llvm::raw_svector_ostream BlobStream(HashTableBlob);
// Make sure that no bucket is at offset 0
llvm::support::endian::write<uint32_t>(BlobStream, 0,
llvm::endianness::little);
Offset = Generator.Emit(BlobStream);
}

field_block::FieldDataLayout FieldData(Stream);
FieldData.emit(Scratch, Offset, HashTableBlob);
}
}

namespace {
/// Used to serialize the on-disk Objective-C selector table.
class ObjCSelectorTableInfo {
Expand Down Expand Up @@ -1423,6 +1488,14 @@ void APINotesWriter::addCXXMethod(ContextID CtxID, llvm::StringRef Name,
Implementation->CXXMethods[Key].push_back({SwiftVersion, Info});
}

void APINotesWriter::addField(ContextID CtxID, llvm::StringRef Name,
const FieldInfo &Info,
VersionTuple SwiftVersion) {
IdentifierID NameID = Implementation->getIdentifier(Name);
SingleDeclTableKey Key(CtxID.Value, NameID);
Implementation->Fields[Key].push_back({SwiftVersion, Info});
}

void APINotesWriter::addGlobalVariable(std::optional<Context> Ctx,
llvm::StringRef Name,
const GlobalVariableInfo &Info,
Expand Down
Loading