Skip to content

Commit

Permalink
Merge pull request llvm#105 from AMD-Lightning-Internal/upstream_merg…
Browse files Browse the repository at this point in the history
…e_202501142308

merge main into amd-staging
  • Loading branch information
ronlieb authored Jan 15, 2025
2 parents a898d5f + 6a7c018 commit 03c4267
Show file tree
Hide file tree
Showing 128 changed files with 5,770 additions and 891 deletions.
36 changes: 35 additions & 1 deletion clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import tempfile
import threading
import traceback
from pathlib import Path

try:
import yaml
Expand Down Expand Up @@ -124,6 +125,23 @@ def merge_replacement_files(tmpdir, mergefile):
open(mergefile, "w").close()


def get_compiling_files(args):
"""Read a compile_commands.json database and return a set of file paths"""
current_dir = Path.cwd()
compile_commands_json = (
(current_dir / args.build_path) if args.build_path else current_dir
)
compile_commands_json = compile_commands_json / "compile_commands.json"
files = set()
with open(compile_commands_json) as db_file:
db_json = json.load(db_file)
for entry in db_json:
if "file" not in entry:
continue
files.add(Path(entry["file"]))
return files


def main():
parser = argparse.ArgumentParser(
description="Run clang-tidy against changed files, and "
Expand Down Expand Up @@ -234,6 +252,13 @@ def main():
action="store_true",
help="Allow empty enabled checks.",
)
parser.add_argument(
"-only-check-in-db",
dest="skip_non_compiling",
default=False,
action="store_true",
help="Only check files in the compilation database",
)

clang_tidy_args = []
argv = sys.argv[1:]
Expand All @@ -243,11 +268,13 @@ def main():

args = parser.parse_args(argv)

compiling_files = get_compiling_files(args) if args.skip_non_compiling else None

# Extract changed lines for each file.
filename = None
lines_by_file = {}
for line in sys.stdin:
match = re.search('^\\+\\+\\+\\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line)
match = re.search(r'^\+\+\+\ "?(.*?/){%s}([^ \t\n"]*)' % args.p, line)
if match:
filename = match.group(2)
if filename is None:
Expand All @@ -260,6 +287,13 @@ def main():
if not re.match("^%s$" % args.iregex, filename, re.IGNORECASE):
continue

# Skip any files not in the compiling list
if (
compiling_files is not None
and (Path.cwd() / filename) not in compiling_files
):
continue

match = re.search(r"^@@.*\+(\d+)(,(\d+))?", line)
if match:
start_line = int(match.group(1))
Expand Down
4 changes: 4 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ Improvements to clang-query
Improvements to clang-tidy
--------------------------

- Improved :program:`clang-tidy-diff.py` script. Add the `-only-check-in-db`
option to exclude files not present in the compilation database, avoiding
false-negative results.

- Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
happening on certain platforms when interrupting the script.

Expand Down
25 changes: 25 additions & 0 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,14 @@ def get_field_offsetof(self):
"""Returns the offsetof the FIELD_DECL pointed by this Cursor."""
return conf.lib.clang_Cursor_getOffsetOfField(self) # type: ignore [no-any-return]

def get_base_offsetof(self, parent):
"""Returns the offsetof the CXX_BASE_SPECIFIER pointed by this Cursor."""
return conf.lib.clang_getOffsetOfBase(parent, self) # type: ignore [no-any-return]

def is_virtual_base(self):
"""Returns whether the CXX_BASE_SPECIFIER pointed by this Cursor is virtual."""
return conf.lib.clang_isVirtualBase(self) # type: ignore [no-any-return]

def is_anonymous(self):
"""
Check whether this is a record type without a name, or a field where
Expand Down Expand Up @@ -2687,6 +2695,21 @@ def visitor(field, children):
conf.lib.clang_Type_visitFields(self, fields_visit_callback(visitor), fields)
return iter(fields)

def get_bases(self):
"""Return an iterator for accessing the base classes of this type."""

def visitor(base, children):
assert base != conf.lib.clang_getNullCursor()

# Create reference to TU so it isn't GC'd before Cursor.
base._tu = self._tu
bases.append(base)
return 1 # continue

bases: list[Cursor] = []
conf.lib.clang_visitCXXBaseClasses(self, fields_visit_callback(visitor), bases)
return iter(bases)

def get_exception_specification_kind(self):
"""
Return the kind of the exception specification; a value from
Expand Down Expand Up @@ -3940,6 +3963,7 @@ def set_property(self, property, value):
("clang_getNumDiagnosticsInSet", [c_object_p], c_uint),
("clang_getNumElements", [Type], c_longlong),
("clang_getNumOverloadedDecls", [Cursor], c_uint),
("clang_getOffsetOfBase", [Cursor, Cursor], c_longlong),
("clang_getOverloadedDecl", [Cursor, c_uint], Cursor),
("clang_getPointeeType", [Type], Type),
("clang_getRange", [SourceLocation, SourceLocation], SourceRange),
Expand Down Expand Up @@ -3992,6 +4016,7 @@ def set_property(self, property, value):
[TranslationUnit, SourceRange, POINTER(POINTER(Token)), POINTER(c_uint)],
),
("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], c_uint),
("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], c_uint),
("clang_Cursor_getNumArguments", [Cursor], c_int),
("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
Expand Down
25 changes: 25 additions & 0 deletions clang/bindings/python/tests/cindex/test_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,3 +534,28 @@ def test_pretty(self):
self.assertEqual(f.type.get_canonical().pretty_printed(pp), "X")
pp.set_property(PrintingPolicyProperty.SuppressTagKeyword, False)
self.assertEqual(f.type.get_canonical().pretty_printed(pp), "struct X")

def test_base_classes(self):
source = """
class A { int a; };
class B { int b; };
class C { int c; };
template <typename T>
class Template : public A, public B, virtual C {
};
Template<int> instance;
int bar;
"""
tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
cursor = get_cursor(tu, "instance")
cursor_type = cursor.type
cursor_type_decl = cursor_type.get_declaration()
self.assertEqual(cursor.kind, CursorKind.VAR_DECL)
bases = list(cursor_type.get_bases())
self.assertEqual(len(bases), 3)
self.assertFalse(bases[0].is_virtual_base())
self.assertEqual(bases[0].get_base_offsetof(cursor_type_decl), 64)
self.assertFalse(bases[1].is_virtual_base())
self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
self.assertTrue(bases[2].is_virtual_base())
self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
10 changes: 10 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,10 @@ libclang
whether the first one comes strictly before the second in the source code.
- Add ``clang_getTypePrettyPrinted``. It allows controlling the PrintingPolicy used
to pretty-print a type.
- Added ``clang_visitCXXBaseClasses``, which allows visiting the base classes
of a class.
- Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
class in a class's layout.

Static Analyzer
---------------
Expand Down Expand Up @@ -1405,6 +1409,12 @@ Python Binding Changes
declaration is an anonymous union or anonymous struct.
- Added ``Type.pretty_printed`, a binding for ``clang_getTypePrettyPrinted``,
which allows changing the formatting of pretty-printed types.
- Added ``Cursor.is_virtual_base``, a binding for ``clang_isVirtualBase``,
which checks whether a base class is virtual.
- Added ``Type.get_bases``, a binding for ``clang_visitCXXBaseClasses``, which
allows visiting the base classes of a class.
- Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
which allows computing the offset of a base class in a class's layout.

OpenMP Support
--------------
Expand Down
36 changes: 34 additions & 2 deletions clang/include/clang-c/Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -3605,8 +3605,8 @@ CINDEX_LINKAGE enum CXTypeNullabilityKind clang_Type_getNullability(CXType T);

/**
* List the possible error codes for \c clang_Type_getSizeOf,
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
* \c clang_Cursor_getOffsetOf.
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf,
* \c clang_Cursor_getOffsetOf, and \c clang_getOffsetOfBase.
*
* A value of this enumeration type can be returned if the target type is not
* a valid argument to sizeof, alignof or offsetof.
Expand Down Expand Up @@ -3771,6 +3771,15 @@ CINDEX_LINKAGE enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T);
*/
CINDEX_LINKAGE unsigned clang_isVirtualBase(CXCursor);

/**
* Returns the offset in bits of a CX_CXXBaseSpecifier relative to the parent
* class.
*
* Returns a small negative number if the offset cannot be computed. See
* CXTypeLayoutError for error codes.
*/
CINDEX_LINKAGE long long clang_getOffsetOfBase(CXCursor Parent, CXCursor Base);

/**
* Represents the C++ access control level to a base class for a
* cursor with kind CX_CXXBaseSpecifier.
Expand Down Expand Up @@ -6648,6 +6657,29 @@ typedef enum CXVisitorResult (*CXFieldVisitor)(CXCursor C,
CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, CXFieldVisitor visitor,
CXClientData client_data);

/**
* Visit the base classes of a type.
*
* This function visits all the direct base classes of a the given cursor,
* invoking the given \p visitor function with the cursors of each
* visited base. The traversal may be ended prematurely, if
* the visitor returns \c CXFieldVisit_Break.
*
* \param T the record type whose field may be visited.
*
* \param visitor the visitor function that will be invoked for each
* field of \p T.
*
* \param client_data pointer data supplied by the client, which will
* be passed to the visitor each time it is invoked.
*
* \returns a non-zero value if the traversal was terminated
* prematurely by the visitor returning \c CXFieldVisit_Break.
*/
CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType T,
CXFieldVisitor visitor,
CXClientData client_data);

/**
* Describes the kind of binary operators.
*/
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/ByteCode/Disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,10 @@ LLVM_DUMP_METHOD void EvaluationResult::dump() const {
case LValue: {
assert(Source);
QualType SourceType;
if (const auto *D = Source.dyn_cast<const Decl *>()) {
if (const auto *D = dyn_cast<const Decl *>(Source)) {
if (const auto *VD = dyn_cast<ValueDecl>(D))
SourceType = VD->getType();
} else if (const auto *E = Source.dyn_cast<const Expr *>()) {
} else if (const auto *E = dyn_cast<const Expr *>(Source)) {
SourceType = E->getType();
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/ExternalASTMerger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ bool ExternalASTMerger::HasImporterForOrigin(ASTContext &OriginContext) {
template <typename CallbackType>
void ExternalASTMerger::ForEachMatchingDC(const DeclContext *DC,
CallbackType Callback) {
if (Origins.count(DC)) {
ExternalASTMerger::DCOrigin Origin = Origins[DC];
if (auto It = Origins.find(DC); It != Origins.end()) {
ExternalASTMerger::DCOrigin Origin = It->second;
LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
Callback(Importer, Importer.GetReverse(), Origin.DC);
} else {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4889,6 +4889,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
if (IPD->getParameterKind() == ImplicitParamKind::CXXThis ||
IPD->getParameterKind() == ImplicitParamKind::ObjCSelf)
Flags |= llvm::DINode::FlagObjectPointer;
} else if (const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
if (PVD->isExplicitObjectParameter())
Flags |= llvm::DINode::FlagObjectPointer;
}

// Note: Older versions of clang used to emit byval references with an extra
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Sema/SemaCodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ class ResultBuilder {
return;
}

if (const NamedDecl *PrevND =
DeclOrVector.dyn_cast<const NamedDecl *>()) {
if (const NamedDecl *PrevND = dyn_cast<const NamedDecl *>(DeclOrVector)) {
// 1 -> 2 elements: create the vector of results and push in the
// existing declaration.
DeclIndexPairVector *Vec = new DeclIndexPairVector;
Expand Down Expand Up @@ -702,7 +701,7 @@ ResultBuilder::ShadowMapEntry::begin() const {
if (DeclOrVector.isNull())
return iterator();

if (const NamedDecl *ND = DeclOrVector.dyn_cast<const NamedDecl *>())
if (const NamedDecl *ND = dyn_cast<const NamedDecl *>(DeclOrVector))
return iterator(ND, SingleDeclIndex);

return iterator(cast<DeclIndexPairVector *>(DeclOrVector)->begin());
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ void ExplodedNode::NodeGroup::addNode(ExplodedNode *N, ExplodedGraph &G) {
return;
}

ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>();
ExplodedNodeVector *V = dyn_cast<ExplodedNodeVector *>(Storage);

if (!V) {
// Switch from single-node to multi-node representation.
Expand All @@ -251,7 +251,7 @@ unsigned ExplodedNode::NodeGroup::size() const {
const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
if (Storage.isNull())
return 0;
if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
if (ExplodedNodeVector *V = dyn_cast<ExplodedNodeVector *>(Storage))
return V->size();
return 1;
}
Expand All @@ -263,7 +263,7 @@ ExplodedNode * const *ExplodedNode::NodeGroup::begin() const {
const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
if (Storage.isNull())
return nullptr;
if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
if (ExplodedNodeVector *V = dyn_cast<ExplodedNodeVector *>(Storage))
return V->begin();
return Storage.getAddrOfPtr1();
}
Expand All @@ -275,7 +275,7 @@ ExplodedNode * const *ExplodedNode::NodeGroup::end() const {
const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
if (Storage.isNull())
return nullptr;
if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
if (ExplodedNodeVector *V = dyn_cast<ExplodedNodeVector *>(Storage))
return V->end();
return Storage.getAddrOfPtr1() + 1;
}
Expand Down
29 changes: 29 additions & 0 deletions clang/test/CodeGenCXX/debug-info-object-pointer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: %clang_cc1 -x c++ -std=c++23 -debug-info-kind=limited -emit-llvm < %s | FileCheck %s

// CHECK: !DISubprogram(name: "bar",
// CHECK-SAME: flags: DIFlagPrototyped
// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
// CHECK-SAME: flags: DIFlagArtificial | DIFlagObjectPointer
//
// // FIXME: DIFlagObjectPointer not attached to the explicit object
// // argument in the subprogram declaration.
// CHECK: !DISubprogram(name: "explicit_this",
// flags: DIFlagPrototyped
// CHECK-NOT: DIFlagObjectPointer
// CHECK-NOT: DIFlagArtificial
//
// CHECK: !DILocalVariable(name: "this", arg: 1
// CHECK-SAME: flags: DIFlagArtificial | DIFlagObjectPointer
//
// CHECK-NOT: DIFlagArtificial
// CHECK: !DILocalVariable(arg: 1, {{.*}}, flags: DIFlagObjectPointer)

struct Foo {
void bar() {}
void explicit_this(this Foo &&) {}
};

void f() {
Foo{}.bar();
Foo{}.explicit_this();
}
Loading

0 comments on commit 03c4267

Please sign in to comment.