74 changes: 55 additions & 19 deletions clang-tools-extra/test/clang-tidy/check_clang_tidy.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,43 @@
#
# ===------------------------------------------------------------------------===#

r"""
"""
ClangTidy Test Helper
=====================
This script runs clang-tidy in fix mode and verify fixes, messages or both.
This script is used to simplify writing, running, and debugging tests compatible
with llvm-lit. By default it runs clang-tidy in fix mode and uses FileCheck to
verify messages and/or fixes.
For debugging, with --export-fixes, the tool simply exports fixes to a provided
file and does not run FileCheck.
Usage:
check_clang_tidy.py [-resource-dir=<resource-dir>] \
[-assume-filename=<file-with-source-extension>] \
[-check-suffix=<comma-separated-file-check-suffixes>] \
[-check-suffixes=<comma-separated-file-check-suffixes>] \
[-std=c++(98|11|14|17|20)[-or-later]] \
<source-file> <check-name> <temp-file> \
-- [optional clang-tidy arguments]
Extra arguments, those after the first -- if any, are passed to either
clang-tidy or clang:
* Arguments between the first -- and second -- are clang-tidy arguments.
* May be only whitespace if there are no clang-tidy arguments.
* clang-tidy's --config would go here.
* Arguments after the second -- are clang arguments
Examples
--------
Example:
// RUN: %check_clang_tidy %s llvm-include-order %t -- -- -isystem %S/Inputs
Notes:
or
// RUN: %check_clang_tidy %s llvm-include-order --export-fixes=fixes.yaml %t -std=c++20
Notes
-----
-std=c++(98|11|14|17|20)-or-later:
This flag will cause multiple runs within the same check_clang_tidy
execution. Make sure you don't have shared state across these runs.
"""

import argparse
import os
import pathlib
import re
import subprocess
import sys
Expand Down Expand Up @@ -88,6 +99,7 @@ def __init__(self, args, extra_args):
self.has_check_fixes = False
self.has_check_messages = False
self.has_check_notes = False
self.export_fixes = args.export_fixes
self.fixes = MessagePrefix("CHECK-FIXES")
self.messages = MessagePrefix("CHECK-MESSAGES")
self.notes = MessagePrefix("CHECK-NOTES")
Expand Down Expand Up @@ -181,7 +193,13 @@ def run_clang_tidy(self):
[
"clang-tidy",
self.temp_file_name,
"-fix",
]
+ [
"-fix"
if self.export_fixes is None
else "--export-fixes=" + self.export_fixes
]
+ [
"--checks=-*," + self.check_name,
]
+ self.clang_tidy_extra_args
Expand Down Expand Up @@ -255,12 +273,14 @@ def check_notes(self, clang_tidy_output):

def run(self):
self.read_input()
self.get_prefixes()
if self.export_fixes is None:
self.get_prefixes()
self.prepare_test_inputs()
clang_tidy_output = self.run_clang_tidy()
self.check_fixes()
self.check_messages(clang_tidy_output)
self.check_notes(clang_tidy_output)
if self.export_fixes is None:
self.check_fixes()
self.check_messages(clang_tidy_output)
self.check_notes(clang_tidy_output)


def expand_std(std):
Expand All @@ -284,7 +304,11 @@ def csv(string):


def parse_arguments():
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(
prog=pathlib.Path(__file__).stem,
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("-expect-clang-tidy-error", action="store_true")
parser.add_argument("-resource-dir")
parser.add_argument("-assume-filename")
Expand All @@ -298,7 +322,19 @@ def parse_arguments():
type=csv,
help="comma-separated list of FileCheck suffixes",
)
parser.add_argument("-std", type=csv, default=["c++11-or-later"])
parser.add_argument(
"-export-fixes",
default=None,
type=str,
metavar="file",
help="A file to export fixes into instead of fixing.",
)
parser.add_argument(
"-std",
type=csv,
default=["c++11-or-later"],
help="Passed to clang. Special -or-later values are expanded.",
)
return parser.parse_known_args()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,16 @@ struct S {
};

} // namespace deleted_functions

namespace unused_arguments {

template<typename F>
void unused_argument1(F&&) {}

template<typename F>
void unused_argument2([[maybe_unused]] F&& f) {}

template<typename F>
void unused_argument3(F&& _) {}

} // namespace unused_arguments
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ ForwardIt unique(ForwardIt, ForwardIt);
template <class InputIt, class T>
InputIt find(InputIt, InputIt, const T&);

struct unique_disposable {
void* release();
};

class error_code {
};

Expand Down Expand Up @@ -63,4 +67,6 @@ void noWarning() {
// bugprone-unused-return-value's checked return types.
errorFunc();
(void) errorFunc();

std::unique_disposable{}.release();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,30 @@ void f2() {
return f1();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: f1();
}

void f3(bool b) {
if (b) return f1();
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: if (b) { f1(); return;
// CHECK-NEXT: }
return f2();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: f2();
// CHECK-FIXES-LENIENT: f2();
}

template<class T>
T f4() {}

void f5() {
return f4<void>();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
{ return f4<void>(); }
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:7: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: { f4<void>(); return; }
// CHECK-FIXES-LENIENT: { f4<void>(); return; }
}

void f6() { return; }
Expand All @@ -41,6 +48,8 @@ void f9() {
return (void)f7();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: (void)f7();
// CHECK-FIXES-LENIENT: (void)f7();
}

#define RETURN_VOID return (void)1
Expand All @@ -50,12 +59,12 @@ void f10() {
// CHECK-MESSAGES-INCLUDE-MACROS: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
}

template <typename A>
template <typename A>
struct C {
C(A) {}
};

template <class T>
template <class T>
C<T> f11() { return {}; }

using VOID = void;
Expand All @@ -66,4 +75,36 @@ VOID f13() {
return f12();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: f12(); return;
// CHECK-FIXES-LENIENT: f12(); return;
(void)1;
}

void f14() {
return /* comment */ f1() /* comment */ ;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: /* comment */ f1() /* comment */ ; return;
// CHECK-FIXES-LENIENT: /* comment */ f1() /* comment */ ; return;
(void)1;
}

void f15() {
return/*comment*/f1()/*comment*/;//comment
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: /*comment*/f1()/*comment*/; return;//comment
// CHECK-FIXES-LENIENT: /*comment*/f1()/*comment*/; return;//comment
(void)1;
}

void f16(bool b) {
if (b) return f1();
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: if (b) { f1(); return;
// CHECK-NEXT: }
else return f2();
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value]
// CHECK-FIXES: else { f2(); return;
// CHECK-NEXT: }
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,18 @@ int r;
// CHECK-FIXES: {{^int q;$}}
// CHECK-FIXES-NEXT: {{^#include <sys/types.h>$}}
// CHECK-FIXES-NEXT: {{^int r;$}}

namespace Issue_87303 {
#define RESET_INCLUDE_CACHE
// Expect no warnings

#define MACRO_FILENAME "duplicate-include.h"
#include MACRO_FILENAME
#include "duplicate-include.h"

#define MACRO_FILENAME_2 <duplicate-include2.h>
#include <duplicate-include2.h>
#include MACRO_FILENAME_2

#undef RESET_INCLUDE_CACHE
} // Issue_87303
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,12 @@ USER_NS::object g_s2;
// NO warnings or fixes expected as USER_NS and object are declared in a header file

SYSTEM_MACRO(var1);
// NO warnings or fixes expected as var1 is from macro expansion
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: invalid case style for global variable 'var1' [readability-identifier-naming]
// CHECK-FIXES: {{^}}SYSTEM_MACRO(g_var1);

USER_MACRO(var2);
// NO warnings or fixes expected as var2 is declared in a macro expansion
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: invalid case style for global variable 'var2' [readability-identifier-naming]
// CHECK-FIXES: {{^}}USER_MACRO(g_var2);

#define BLA int FOO_bar
BLA;
Expand Down Expand Up @@ -602,9 +604,20 @@ static void static_Function() {
// CHECK-FIXES: {{^}}#define MY_TEST_MACRO(X) X()

void MY_TEST_Macro(function) {}
// CHECK-FIXES: {{^}}void MY_TEST_MACRO(function) {}
}
}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: invalid case style for global function 'function' [readability-identifier-naming]
// CHECK-FIXES: {{^}}void MY_TEST_MACRO(Function) {}

#define MY_CAT_IMPL(l, r) l ## r
#define MY_CAT(l, r) MY_CAT_IMPL(l, r)
#define MY_MACRO2(foo) int MY_CAT(awesome_, MY_CAT(foo, __COUNTER__)) = 0
#define MY_MACRO3(foo) int MY_CAT(awesome_, foo) = 0
MY_MACRO2(myglob);
MY_MACRO3(myglob);
// No suggestions should occur even though the resulting decl of awesome_myglob#
// or awesome_myglob are not entirely within a macro argument.

} // namespace InlineNamespace
} // namespace FOO_NS

template <typename t_t> struct a {
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: invalid case style for struct 'a'
Expand Down Expand Up @@ -766,3 +779,13 @@ STATIC_MACRO void someFunc(MyFunPtr, const MyFunPtr****) {}
// CHECK-FIXES: {{^}}STATIC_MACRO void someFunc(my_fun_ptr_t, const my_fun_ptr_t****) {}
#undef STATIC_MACRO
}

struct Some_struct {
int SomeMember;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for public member 'SomeMember' [readability-identifier-naming]
// CHECK-FIXES: {{^}} int some_member;
};
Some_struct g_s1{ .SomeMember = 1 };
// CHECK-FIXES: {{^}}Some_struct g_s1{ .some_member = 1 };
Some_struct g_s2{.SomeMember=1};
// CHECK-FIXES: {{^}}Some_struct g_s2{.some_member=1};
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// RUN: not clang-tidy -checks='-*,modernize-use-override' %T/diagnostics/input.cpp -- -DCOMPILATION_ERROR 2>&1 | FileCheck -check-prefix=CHECK6 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE -std=c++20 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined,clang-diagnostic-literal-conversion' %s -- -DMACRO_FROM_COMMAND_LINE -std=c++20 -Wno-macro-redefined | FileCheck --check-prefix=CHECK7 -implicit-check-not='{{warning:|error:}}' %s
// RUN: not clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 -DPR64602 | FileCheck -check-prefix=CHECK8 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 -DPR64602

// CHECK1: error: no input files [clang-diagnostic-error]
// CHECK1: error: no such file or directory: '{{.*}}nonexistent.cpp' [clang-diagnostic-error]
Expand Down Expand Up @@ -68,6 +68,4 @@ auto S<>::foo(auto)
{
return 1;
}
// CHECK8: error: conflicting types for 'foo' [clang-diagnostic-error]
// CHECK8: note: previous declaration is here
#endif
7 changes: 7 additions & 0 deletions clang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ if(CLANG_ENABLE_LIBXML2)
endif()
endif()

if(CLANG_ENABLE_CIR)
if (NOT "${LLVM_ENABLE_PROJECTS}" MATCHES "MLIR|mlir")
message(FATAL_ERROR
"Cannot build ClangIR without MLIR in LLVM_ENABLE_PROJECTS")
endif()
endif()

include(CheckIncludeFile)
check_include_file(sys/resource.h CLANG_HAVE_RLIMITS)

Expand Down
1 change: 1 addition & 0 deletions clang/cmake/caches/Apple-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(LLVM_ENABLE_ZLIB ON CACHE BOOL "")
set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
set(LLVM_ENABLE_MODULES ON CACHE BOOL "")
set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
set(LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES OFF CACHE BOOL "")
set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
set(CLANG_SPAWN_CC1 ON CACHE BOOL "")
set(BUG_REPORT_URL "http://developer.apple.com/bugreporter/" CACHE STRING "")
Expand Down
2 changes: 2 additions & 0 deletions clang/cmake/caches/Fuchsia.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH
Python3_LIBRARIES
Python3_INCLUDE_DIRS
Python3_RPATH
SWIG_DIR
SWIG_EXECUTABLE
CMAKE_FIND_PACKAGE_PREFER_CONFIG
CMAKE_SYSROOT
CMAKE_MODULE_LINKER_FLAGS
Expand Down
2 changes: 1 addition & 1 deletion clang/cmake/caches/Release.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# General Options
set(LLVM_RELEASE_ENABLE_LTO THIN CACHE STRING "")
set(LLVM_RELEASE_ENABLE_PGO ON CACHE BOOL "")
set(LLVM_RELEASE_ENABLE_PGO OFF CACHE BOOL "")

set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "")

Expand Down
2 changes: 1 addition & 1 deletion clang/docs/ClangFormat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code.
Objective-C: .m .mm
Proto: .proto .protodevel
TableGen: .td
TextProto: .textpb .pb.txt .textproto .asciipb
TextProto: .txtpb .textpb .pb.txt .textproto .asciipb
Verilog: .sv .svh .v .vh
--cursor=<uint> - The position of the cursor when invoking
clang-format from an editor integration
Expand Down
15 changes: 15 additions & 0 deletions clang/docs/ClangFormatStyleOptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3295,6 +3295,21 @@ the configuration (without a prefix: ``Auto``).



.. _BreakFunctionDefinitionParameters:

**BreakFunctionDefinitionParameters** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ <BreakFunctionDefinitionParameters>`
If ``true``, clang-format will always break before function definition
parameters.

.. code-block:: c++

true:
void functionDefinition(
int A, int B) {}

false:
void functionDefinition(int A, int B) {}

.. _BreakInheritanceList:

**BreakInheritanceList** (``BreakInheritanceListStyle``) :versionbadge:`clang-format 7` :ref:`¶ <BreakInheritanceList>`
Expand Down
14 changes: 14 additions & 0 deletions clang/docs/HIPSupport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,20 @@ Host Code Compilation
- These relocatable objects are then linked together.
- Host code within a TU can call host functions and launch kernels from another TU.

Syntax Difference with CUDA
===========================

Clang's front end, used for both CUDA and HIP programming models, shares the same parsing and semantic analysis mechanisms. This includes the resolution of overloads concerning device and host functions. While there exists a comprehensive documentation on the syntax differences between Clang and NVCC for CUDA at `Dialect Differences Between Clang and NVCC <https://llvm.org/docs/CompileCudaWithLLVM.html#dialect-differences-between-clang-and-nvcc>`_, it is important to note that these differences also apply to HIP code compilation.

Predefined Macros for Differentiation
-------------------------------------

To facilitate differentiation between HIP and CUDA code, as well as between device and host compilations within HIP, Clang defines specific macros:

- ``__HIP__`` : This macro is defined only when compiling HIP code. It can be used to conditionally compile code specific to HIP, enabling developers to write portable code that can be compiled for both CUDA and HIP.

- ``__HIP_DEVICE_COMPILE__`` : Defined exclusively during HIP device compilation, this macro allows for conditional compilation of device-specific code. It provides a mechanism to segregate device and host code, ensuring that each can be optimized for their respective execution environments.

Function Pointers Support
=========================

Expand Down
31 changes: 16 additions & 15 deletions clang/docs/HLSL/FunctionCalls.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,22 +157,23 @@ Clang Implementation
of the changes in the prototype implementation are restoring Clang-3.7 code
that was previously modified to its original state.

The implementation in clang depends on two new AST nodes and minor extensions to
Clang's existing support for Objective-C write-back arguments. The goal of this
design is to capture the semantic details of HLSL function calls in the AST, and
minimize the amount of magic that needs to occur during IR generation.

The two new AST nodes are ``HLSLArrayTemporaryExpr`` and ``HLSLOutParamExpr``,
which respectively represent the temporaries used for passing arrays by value
and the temporaries created for function outputs.
The implementation in clang adds a new non-decaying array type, a new AST node
to represent output parameters, and minor extensions to Clang's existing support
for Objective-C write-back arguments. The goal of this design is to capture the
semantic details of HLSL function calls in the AST, and minimize the amount of
magic that needs to occur during IR generation.

Array Temporaries
-----------------

The ``HLSLArrayTemporaryExpr`` represents temporary values for input
constant-sized array arguments. This applies for all constant-sized array
arguments regardless of whether or not the parameter is constant-sized or
unsized.
The new ``ArrayParameterType`` is a sub-class of ``ConstantArrayType``
inheriting all the behaviors and methods of the parent except that it does not
decay to a pointer during overload resolution or template type deduction.

An argument of ``ConstantArrayType`` can be implicitly converted to an
equivalent non-decayed ``ArrayParameterType`` if the underlying canonical
``ConstantArrayType`` is the same. This occurs during overload resolution
instead of array to pointer decay.

.. code-block:: c++

Expand All @@ -193,7 +194,7 @@ In the example above, the following AST is generated for the call to
CallExpr 'void'
|-ImplicitCastExpr 'void (*)(float [4])' <FunctionToPointerDecay>
| `-DeclRefExpr 'void (float [4])' lvalue Function 'SizedArray' 'void (float [4])'
`-HLSLArrayTemporaryExpr 'float [4]'
`-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
`-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
In the example above, the following AST is generated for the call to
Expand All @@ -204,7 +205,7 @@ In the example above, the following AST is generated for the call to
CallExpr 'void'
|-ImplicitCastExpr 'void (*)(float [])' <FunctionToPointerDecay>
| `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])'
`-HLSLArrayTemporaryExpr 'float [4]'
`-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
`-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
In both of these cases the argument expression is of known array size so we can
Expand Down Expand Up @@ -236,7 +237,7 @@ An expected AST should be something like:
CallExpr 'void'
|-ImplicitCastExpr 'void (*)(float [])' <FunctionToPointerDecay>
| `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])'
`-HLSLArrayTemporaryExpr 'float [4]'
`-ImplicitCastExpr 'float [4]' <HLSLArrayRValue>
`-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]'
Out Parameter Temporaries
Expand Down
2 changes: 2 additions & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+
``if consteval`` __cpp_if_consteval C++23 C++20
``static operator()`` __cpp_static_call_operator C++23 C++03
Attributes on Lambda-Expressions C++23 C++11
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
Designated initializers (N494) C99 C89
Array & element qualification (N2607) C23 C89
Expand Down Expand Up @@ -1610,6 +1611,7 @@ The following type trait primitives are supported by Clang. Those traits marked
* ``__is_pod`` (C++, GNU, Microsoft, Embarcadero):
Note, the corresponding standard trait was deprecated in C++20.
* ``__is_pointer`` (C++, Embarcadero)
* ``__is_pointer_interconvertible_base_of`` (C++, GNU, Microsoft)
* ``__is_polymorphic`` (C++, GNU, Microsoft, Embarcadero)
* ``__is_reference`` (C++, Embarcadero)
* ``__is_referenceable`` (C++, GNU, Microsoft, Embarcadero):
Expand Down
76 changes: 75 additions & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ C++20 Feature Support
behavior can use the flag '-Xclang -fno-skip-odr-check-in-gmf'.
(#GH79240).

- Implemented the `__is_layout_compatible` intrinsic to support
- Implemented the `__is_layout_compatible` and `__is_pointer_interconvertible_base_of`
intrinsics to support
`P0466R5: Layout-compatibility and Pointer-interconvertibility Traits <https://wg21.link/P0466R5>`_.

- Clang now implements [module.import]p7 fully. Clang now will import module
Expand All @@ -110,6 +111,10 @@ C++20 Feature Support
templates (`P1814R0 <https://wg21.link/p1814r0>`_).
(#GH54051).

- We have sufficient confidence and experience with the concepts implementation
to update the ``__cpp_concepts`` macro to `202002L`. This enables
``<expected>`` from libstdc++ to work correctly with Clang.

C++23 Feature Support
^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -124,6 +129,8 @@ C++2c Feature Support

- Implemented `P2662R3 Pack Indexing <https://wg21.link/P2662R3>`_.

- Implemented `P2573R2: = delete("should have a reason"); <https://wg21.link/P2573R2>`_


Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -143,6 +150,9 @@ Resolutions to C++ Defect Reports
compatibility of two types.
(`CWG2759: [[no_unique_address] and common initial sequence <https://cplusplus.github.io/CWG/issues/2759.html>`_).

- Clang now diagnoses declarative nested-name-specifiers with pack-index-specifiers.
(`CWG2858: Declarative nested-name-specifiers and pack-index-specifiers <https://cplusplus.github.io/CWG/issues/2858.html>`_).

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

Expand Down Expand Up @@ -193,8 +203,15 @@ Non-comprehensive list of changes in this release
with support for any unsigned integer type. Like the previous builtins, these
new builtins are constexpr and may be used in constant expressions.

- ``__typeof_unqual__`` is available in all C modes as an extension, which behaves
like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``.

New Compiler Flags
------------------
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
sign change.
- ``-fsanitize=implicit-integer-conversion`` a group that replaces the previous
group ``-fsanitize=implicit-conversion``.

- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-field-initializers``.
This diagnostic can be disabled to make ``-Wmissing-field-initializers`` behave
Expand All @@ -208,6 +225,9 @@ Modified Compiler Flags
- Added a new diagnostic flag ``-Wreturn-mismatch`` which is grouped under
``-Wreturn-type``, and moved some of the diagnostics previously controlled by
``-Wreturn-type`` under this new flag. Fixes #GH72116.
- ``-fsanitize=implicit-conversion`` is now a group for both
``-fsanitize=implicit-integer-conversion`` and
``-fsanitize=implicit-bitfield-conversion``.

- Added ``-Wcast-function-type-mismatch`` under the ``-Wcast-function-type``
warning group. Moved the diagnostic previously controlled by
Expand Down Expand Up @@ -253,6 +273,21 @@ Attribute Changes in Clang
added a new extension query ``__has_extension(swiftcc)`` corresponding to the
``__attribute__((swiftcc))`` attribute.

- The ``_Nullable`` and ``_Nonnull`` family of type attributes can now apply
to certain C++ class types, such as smart pointers:
``void useObject(std::unique_ptr<Object> _Nonnull obj);``.

This works for standard library types including ``unique_ptr``, ``shared_ptr``,
and ``function``. See
`the attribute reference documentation <https://llvm.org/docs/AttributeReference.html#nullability-attributes>`_
for the full list.

- The ``_Nullable`` attribute can be applied to C++ class declarations:
``template <class T> class _Nullable MySmartPointer {};``.

This allows the ``_Nullable`` and ``_Nonnull`` family of type attributes to
apply to this class.

Improvements to Clang's diagnostics
-----------------------------------
- Clang now applies syntax highlighting to the code snippets it
Expand Down Expand Up @@ -313,11 +348,33 @@ Improvements to Clang's diagnostics
- New ``-Wformat-signedness`` diagnostic that warn if the format string requires an
unsigned argument and the argument is signed and vice versa.

- Clang now emits ``unused argument`` warning when the -fmodule-output flag is used
with an input that is not of type c++-module.

- Clang emits a ``-Wreturn-stack-address`` warning if a function returns a pointer or
reference to a struct literal. Fixes #GH8678

- Clang emits a ``-Wunused-but-set-variable`` warning on C++ variables whose declaration
(with initializer) entirely consist the condition expression of a if/while/for construct
but are not actually used in the body of the if/while/for construct. Fixes #GH41447

- Clang emits a diagnostic when a tentative array definition is assumed to have
a single element, but that diagnostic was never given a diagnostic group.
Added the ``-Wtentative-definition-array`` warning group to cover this.
Fixes #GH87766

- Clang now uses the correct type-parameter-key (``class`` or ``typename``) when printing
template template parameter declarations.

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

Bug Fixes in This Version
-------------------------
- Clang's ``-Wundefined-func-template`` no longer warns on pure virtual
functions.
(`#74016 <https://github.com/llvm/llvm-project/issues/74016>`_)

- Fixed missing warnings when comparing mismatched enumeration constants
in C (`#29217 <https://github.com/llvm/llvm-project/issues/29217>`).

Expand Down Expand Up @@ -452,6 +509,8 @@ Bug Fixes to C++ Support
when one of the function had more specialized templates.
Fixes (`#82509 <https://github.com/llvm/llvm-project/issues/82509>`_)
and (`#74494 <https://github.com/llvm/llvm-project/issues/74494>`_)
- Clang now supports direct lambda calls inside of a type alias template declarations.
This addresses (#GH70601), (#GH76674), (#GH79555), (#GH81145) and (#GH82104).
- Allow access to a public template alias declaration that refers to friend's
private nested type. (#GH25708).
- Fixed a crash in constant evaluation when trying to access a
Expand All @@ -468,10 +527,21 @@ Bug Fixes to C++ Support
following the first `::` were ignored).
- Fix an out-of-bounds crash when checking the validity of template partial specializations. (part of #GH86757).
- Fix an issue caused by not handling invalid cases when substituting into the parameter mapping of a constraint. Fixes (#GH86757).
- Fixed a bug that prevented member function templates of class templates declared with a deduced return type
from being explicitly specialized for a given implicit instantiation of the class template.

- Fix crash when inheriting from a cv-qualified type. Fixes:
(`#35603 <https://github.com/llvm/llvm-project/issues/35603>`_)
- Fix a crash when the using enum declaration uses an anonymous enumeration. Fixes (#GH86790).
- Handled an edge case in ``getFullyPackExpandedSize`` so that we now avoid a false-positive diagnostic. (#GH84220)
- Clang now correctly tracks type dependence of by-value captures in lambdas with an explicit
object parameter.
Fixes (#GH70604), (#GH79754), (#GH84163), (#GH84425), (#GH86054), (#GH86398), and (#GH86399).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Clang now properly preserves ``FoundDecls`` within a ``ConceptReference``. (#GH82628)
- The presence of the ``typename`` keyword is now stored in ``TemplateTemplateParmDecl``.

Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -586,10 +656,14 @@ Fixed Point Support in Clang
AST Matchers
------------

- Fixes a long-standing performance issue in parent map generation for
ancestry-based matchers such as ``hasParent`` and ``hasAncestor``, making
them significantly faster.
- ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``.
- Add ``isExplicitObjectMemberFunction``.
- Fixed ``forEachArgumentWithParam`` and ``forEachArgumentWithParamType`` to
not skip the explicit object parameter for operator calls.
- Fixed captureVars assertion failure if not capturesVariables. (#GH76425)

clang-format
------------
Expand Down
19 changes: 14 additions & 5 deletions clang/docs/UndefinedBehaviorSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ Available checks are:
Issues caught by this sanitizer are not undefined behavior,
but are often unintentional.
- ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
- ``-fsanitize=implicit-bitfield-conversion``: Implicit conversion from
integer of larger bit width to smaller bitfield, if that results in data
loss. This includes unsigned/signed truncations and sign changes, similarly
to how the ``-fsanitize=implicit-integer-conversion`` group works, but
explicitly for bitfields.
- ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
parameter which is declared to never be null.
- ``-fsanitize=null``: Use of a null pointer or creation of a null
Expand Down Expand Up @@ -193,16 +198,16 @@ Available checks are:
signed division overflow (``INT_MIN/-1``). Note that checks are still
added even when ``-fwrapv`` is enabled. This sanitizer does not check for
lossy implicit conversions performed before the computation (see
``-fsanitize=implicit-conversion``). Both of these two issues are handled
by ``-fsanitize=implicit-conversion`` group of checks.
``-fsanitize=implicit-integer-conversion``). Both of these two issues are handled
by ``-fsanitize=implicit-integer-conversion`` group of checks.
- ``-fsanitize=unreachable``: If control flow reaches an unreachable
program point.
- ``-fsanitize=unsigned-integer-overflow``: Unsigned integer overflow, where
the result of an unsigned integer computation cannot be represented in its
type. Unlike signed integer overflow, this is not undefined behavior, but
it is often unintentional. This sanitizer does not check for lossy implicit
conversions performed before such a computation
(see ``-fsanitize=implicit-conversion``).
(see ``-fsanitize=implicit-integer-conversion``).
- ``-fsanitize=vla-bound``: A variable-length array whose bound
does not evaluate to a positive value.
- ``-fsanitize=vptr``: Use of an object whose vptr indicates that it is of
Expand All @@ -224,11 +229,15 @@ You can also use the following check groups:
- ``-fsanitize=implicit-integer-arithmetic-value-change``: Catches implicit
conversions that change the arithmetic value of the integer. Enables
``implicit-signed-integer-truncation`` and ``implicit-integer-sign-change``.
- ``-fsanitize=implicit-conversion``: Checks for suspicious
behavior of implicit conversions. Enables
- ``-fsanitize=implicit-integer-conversion``: Checks for suspicious
behavior of implicit integer conversions. Enables
``implicit-unsigned-integer-truncation``,
``implicit-signed-integer-truncation``, and
``implicit-integer-sign-change``.
- ``-fsanitize=implicit-conversion``: Checks for suspicious
behavior of implicit conversions. Enables
``implicit-integer-conversion``, and
``implicit-bitfield-conversion``.
- ``-fsanitize=integer``: Checks for undefined or suspicious integer
behavior (e.g. unsigned integer overflow).
Enables ``signed-integer-overflow``, ``unsigned-integer-overflow``,
Expand Down
21 changes: 17 additions & 4 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3138,10 +3138,16 @@ are detected:
allowed in this state.
* Invalid 3rd ("``whence``") argument to ``fseek``.
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
The stream operations are by this checker usually split into two cases, a success
and a failure case. However, in the case of write operations (like ``fwrite``,
``fprintf`` and even ``fsetpos``) this behavior could produce a large amount of
unwanted reports on projects that don't have error checks around the write
operations, so by default the checker assumes that write operations always succeed.
This behavior can be controlled by the ``Pedantic`` flag: With
``-analyzer-config alpha.unix.Stream:Pedantic=true`` the checker will model the
cases where a write operation fails and report situations where this leads to
erroneous behavior. (The default is ``Pedantic=false``, where write operations
are assumed to succeed.)
.. code-block:: c
Expand Down Expand Up @@ -3196,6 +3202,13 @@ are usually not opened explicitly by the program, and are global variables).
fclose(p);
}
**Limitations**
The checker does not track the correspondence between integer file descriptors
and ``FILE *`` pointers. Operations on standard streams like ``stdin`` are not
treated specially and are therefore often not recognized (because these streams
are usually not opened explicitly by the program, and are global variables).
.. _alpha-unix-cstring-BufferOverlap:
alpha.unix.cstring.BufferOverlap (C)
Expand Down
5 changes: 2 additions & 3 deletions clang/docs/tools/clang-formatted-files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ clang/include/clang/Analysis/Analyses/CalledOnceCheck.h
clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h
clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
Expand Down Expand Up @@ -2147,8 +2146,10 @@ flang/include/flang/Parser/message.h
flang/include/flang/Parser/parse-state.h
flang/include/flang/Parser/parse-tree-visitor.h
flang/include/flang/Parser/parsing.h
flang/include/flang/Parser/preprocessor.h
flang/include/flang/Parser/provenance.h
flang/include/flang/Parser/source.h
flang/include/flang/Parser/token-sequence.h
flang/include/flang/Parser/tools.h
flang/include/flang/Parser/unparse.h
flang/include/flang/Parser/user-state.h
Expand Down Expand Up @@ -2319,7 +2320,6 @@ flang/lib/Parser/openmp-parsers.cpp
flang/lib/Parser/parse-tree.cpp
flang/lib/Parser/parsing.cpp
flang/lib/Parser/preprocessor.cpp
flang/lib/Parser/preprocessor.h
flang/lib/Parser/prescan.cpp
flang/lib/Parser/prescan.h
flang/lib/Parser/program-parsers.cpp
Expand All @@ -2328,7 +2328,6 @@ flang/lib/Parser/source.cpp
flang/lib/Parser/stmt-parser.h
flang/lib/Parser/token-parsers.h
flang/lib/Parser/token-sequence.cpp
flang/lib/Parser/token-sequence.h
flang/lib/Parser/tools.cpp
flang/lib/Parser/type-parser-implementation.h
flang/lib/Parser/type-parsers.h
Expand Down
11 changes: 9 additions & 2 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
ASTContext&>
SubstTemplateTemplateParmPacks;

mutable llvm::ContextualFoldingSet<ArrayParameterType, ASTContext &>
ArrayParameterTypes;

/// The set of nested name specifiers.
///
/// This set is managed by the NestedNameSpecifier class.
Expand Down Expand Up @@ -1367,6 +1370,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// type to the decayed type.
QualType getDecayedType(QualType Orig, QualType Decayed) const;

/// Return the uniqued reference to a specified array parameter type from the
/// original array type.
QualType getArrayParameterType(QualType Ty) const;

/// Return the uniqued reference to the atomic type for the specified
/// type.
QualType getAtomicType(QualType T) const;
Expand Down Expand Up @@ -3404,13 +3411,13 @@ const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,

/// Utility function for constructing a nullary selector.
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
const IdentifierInfo *II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(0, &II);
}

/// Utility function for constructing an unary selector.
inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
const IdentifierInfo *II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(1, &II);
}

Expand Down
22 changes: 22 additions & 0 deletions clang/include/clang/AST/ASTNodeTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct {
void Visit(TypeLoc);
void Visit(const Decl *D);
void Visit(const CXXCtorInitializer *Init);
void Visit(const OpenACCClause *C);
void Visit(const OMPClause *C);
void Visit(const BlockDecl::Capture &C);
void Visit(const GenericSelectionExpr::ConstAssociation &A);
Expand Down Expand Up @@ -239,6 +240,14 @@ class ASTNodeTraverser
});
}

void Visit(const OpenACCClause *C) {
getNodeDelegate().AddChild([=] {
getNodeDelegate().Visit(C);
for (const auto *S : C->children())
Visit(S);
});
}

void Visit(const OMPClause *C) {
getNodeDelegate().AddChild([=] {
getNodeDelegate().Visit(C);
Expand Down Expand Up @@ -799,6 +808,11 @@ class ASTNodeTraverser
Visit(C);
}

void VisitOpenACCConstructStmt(const OpenACCConstructStmt *Node) {
for (const auto *C : Node->clauses())
Visit(C);
}

void VisitInitListExpr(const InitListExpr *ILE) {
if (auto *Filler = ILE->getArrayFiller()) {
Visit(Filler, "array_filler");
Expand Down Expand Up @@ -919,6 +933,14 @@ class ASTNodeTraverser
Visit(TArg);
}

void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
Visit(Node->getExpr());
}

void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
Visit(Node->getExpr());
}

// Implements Visit methods for Attrs.
#include "clang/AST/AttrNodeTraverse.inc"
};
Expand Down
96 changes: 66 additions & 30 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,9 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {

LLVM_PREFERRED_TYPE(bool)
unsigned EscapingByref : 1;

LLVM_PREFERRED_TYPE(bool)
unsigned IsCXXCondDecl : 1;
};

union {
Expand Down Expand Up @@ -1589,6 +1592,15 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
NonParmVarDeclBits.EscapingByref = true;
}

bool isCXXCondDecl() const {
return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsCXXCondDecl;
}

void setCXXCondDecl() {
assert(!isa<ParmVarDecl>(this));
NonParmVarDeclBits.IsCXXCondDecl = true;
}

/// Determines if this variable's alignment is dependent.
bool hasDependentAlignment() const;

Expand Down Expand Up @@ -1719,7 +1731,7 @@ class ImplicitParamDecl : public VarDecl {
static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);

ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
IdentifierInfo *Id, QualType Type,
const IdentifierInfo *Id, QualType Type,
ImplicitParamKind ParamKind)
: VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
/*TInfo=*/nullptr, SC_None) {
Expand Down Expand Up @@ -1753,7 +1765,7 @@ class ParmVarDecl : public VarDecl {

protected:
ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
: VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
Expand All @@ -1765,10 +1777,10 @@ class ParmVarDecl : public VarDecl {

public:
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, Expr *DefArg);
SourceLocation StartLoc, SourceLocation IdLoc,
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass S,
Expr *DefArg);

static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);

Expand Down Expand Up @@ -1981,21 +1993,35 @@ class FunctionDecl : public DeclaratorDecl,

};

/// Stashed information about a defaulted function definition whose body has
/// not yet been lazily generated.
class DefaultedFunctionInfo final
: llvm::TrailingObjects<DefaultedFunctionInfo, DeclAccessPair> {
/// Stashed information about a defaulted/deleted function body.
class DefaultedOrDeletedFunctionInfo final
: llvm::TrailingObjects<DefaultedOrDeletedFunctionInfo, DeclAccessPair,
StringLiteral *> {
friend TrailingObjects;
unsigned NumLookups;
bool HasDeletedMessage;

size_t numTrailingObjects(OverloadToken<DeclAccessPair>) const {
return NumLookups;
}

public:
static DefaultedFunctionInfo *Create(ASTContext &Context,
ArrayRef<DeclAccessPair> Lookups);
static DefaultedOrDeletedFunctionInfo *
Create(ASTContext &Context, ArrayRef<DeclAccessPair> Lookups,
StringLiteral *DeletedMessage = nullptr);

/// Get the unqualified lookup results that should be used in this
/// defaulted function definition.
ArrayRef<DeclAccessPair> getUnqualifiedLookups() const {
return {getTrailingObjects<DeclAccessPair>(), NumLookups};
}

StringLiteral *getDeletedMessage() const {
return HasDeletedMessage ? *getTrailingObjects<StringLiteral *>()
: nullptr;
}

void setDeletedMessage(StringLiteral *Message);
};

private:
Expand All @@ -2005,12 +2031,12 @@ class FunctionDecl : public DeclaratorDecl,
ParmVarDecl **ParamInfo = nullptr;

/// The active member of this union is determined by
/// FunctionDeclBits.HasDefaultedFunctionInfo.
/// FunctionDeclBits.HasDefaultedOrDeletedInfo.
union {
/// The body of the function.
LazyDeclStmtPtr Body;
/// Information about a future defaulted function definition.
DefaultedFunctionInfo *DefaultedInfo;
DefaultedOrDeletedFunctionInfo *DefaultedOrDeletedInfo;
};

unsigned ODRHash;
Expand Down Expand Up @@ -2268,18 +2294,18 @@ class FunctionDecl : public DeclaratorDecl,

/// Returns whether this specific declaration of the function has a body.
bool doesThisDeclarationHaveABody() const {
return (!FunctionDeclBits.HasDefaultedFunctionInfo && Body) ||
return (!FunctionDeclBits.HasDefaultedOrDeletedInfo && Body) ||
isLateTemplateParsed();
}

void setBody(Stmt *B);
void setLazyBody(uint64_t Offset) {
FunctionDeclBits.HasDefaultedFunctionInfo = false;
FunctionDeclBits.HasDefaultedOrDeletedInfo = false;
Body = LazyDeclStmtPtr(Offset);
}

void setDefaultedFunctionInfo(DefaultedFunctionInfo *Info);
DefaultedFunctionInfo *getDefaultedFunctionInfo() const;
void setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo *Info);
DefaultedOrDeletedFunctionInfo *getDefalutedOrDeletedInfo() const;

/// Whether this function is variadic.
bool isVariadic() const;
Expand Down Expand Up @@ -2482,7 +2508,7 @@ class FunctionDecl : public DeclaratorDecl,
return FunctionDeclBits.IsDeleted && !isDefaulted();
}

void setDeletedAsWritten(bool D = true) { FunctionDeclBits.IsDeleted = D; }
void setDeletedAsWritten(bool D = true, StringLiteral *Message = nullptr);

/// Determines whether this function is "main", which is the
/// entry point into an executable program.
Expand Down Expand Up @@ -2638,6 +2664,13 @@ class FunctionDecl : public DeclaratorDecl,
AC.push_back(TRC);
}

/// Get the message that indicates why this function was deleted.
StringLiteral *getDeletedMessage() const {
return FunctionDeclBits.HasDefaultedOrDeletedInfo
? DefaultedOrDeletedInfo->getDeletedMessage()
: nullptr;
}

void setPreviousDeclaration(FunctionDecl * PrevDecl);

FunctionDecl *getCanonicalDecl() override;
Expand Down Expand Up @@ -3083,7 +3116,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {

protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
Expand All @@ -3099,7 +3132,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {

static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle);

Expand Down Expand Up @@ -3320,8 +3353,9 @@ class IndirectFieldDecl : public ValueDecl,
friend class ASTDeclReader;

static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, llvm::MutableArrayRef<NamedDecl *> CH);
SourceLocation L, const IdentifierInfo *Id,
QualType T,
llvm::MutableArrayRef<NamedDecl *> CH);

static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);

Expand Down Expand Up @@ -3369,9 +3403,9 @@ class TypeDecl : public NamedDecl {
void anchor() override;

protected:
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id,
SourceLocation StartL = SourceLocation())
: NamedDecl(DK, DC, L, Id), LocStart(StartL) {}
: NamedDecl(DK, DC, L, Id), LocStart(StartL) {}

public:
// Low-level accessor. If you just want the type defined by this node,
Expand Down Expand Up @@ -3413,7 +3447,7 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
protected:
TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo)
const IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
MaybeModedTInfo(TInfo, 0) {}

Expand Down Expand Up @@ -3500,13 +3534,14 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
/// type specifier.
class TypedefDecl : public TypedefNameDecl {
TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
SourceLocation IdLoc, const IdentifierInfo *Id,
TypeSourceInfo *TInfo)
: TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}

public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
const IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);

SourceRange getSourceRange() const override LLVM_READONLY;
Expand All @@ -3523,14 +3558,15 @@ class TypeAliasDecl : public TypedefNameDecl {
TypeAliasTemplateDecl *Template;

TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
SourceLocation IdLoc, const IdentifierInfo *Id,
TypeSourceInfo *TInfo)
: TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo),
Template(nullptr) {}

public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
const IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);

SourceRange getSourceRange() const override LLVM_READONLY;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -1739,7 +1739,7 @@ class DeclContext {
LLVM_PREFERRED_TYPE(bool)
uint64_t IsExplicitlyDefaulted : 1;
LLVM_PREFERRED_TYPE(bool)
uint64_t HasDefaultedFunctionInfo : 1;
uint64_t HasDefaultedOrDeletedInfo : 1;

/// For member functions of complete types, whether this is an ineligible
/// special member function or an unselected destructor. See
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/DeclCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
DL.MethodTyInfo = TS;
}

void setLambdaDependencyKind(unsigned Kind) {
getLambdaData().DependencyKind = Kind;
}

void setLambdaIsGeneric(bool IsGeneric) {
assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
Expand Down
89 changes: 42 additions & 47 deletions clang/include/clang/AST/DeclObjC.h
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ class ObjCPropertyDecl : public NamedDecl {
// Synthesize ivar for this property
ObjCIvarDecl *PropertyIvarDecl = nullptr;

ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, const IdentifierInfo *Id,
SourceLocation AtLocation, SourceLocation LParenLocation,
QualType T, TypeSourceInfo *TSI, PropertyControl propControl)
: NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
Expand All @@ -782,10 +782,12 @@ class ObjCPropertyDecl : public NamedDecl {
PropertyImplementation(propControl) {}

public:
static ObjCPropertyDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation AtLocation, SourceLocation LParenLocation, QualType T,
TypeSourceInfo *TSI, PropertyControl propControl = None);
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, const IdentifierInfo *Id,
SourceLocation AtLocation,
SourceLocation LParenLocation, QualType T,
TypeSourceInfo *TSI,
PropertyControl propControl = None);

static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);

Expand Down Expand Up @@ -952,7 +954,7 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
void anchor() override;

public:
ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id,
ObjCContainerDecl(Kind DK, DeclContext *DC, const IdentifierInfo *Id,
SourceLocation nameLoc, SourceLocation atStartLoc);

// Iterator access to instance/class properties.
Expand Down Expand Up @@ -1240,7 +1242,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
llvm::PointerIntPair<DefinitionData *, 1, bool> Data;

ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
bool IsInternal);

Expand Down Expand Up @@ -1271,13 +1273,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
}

public:
static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation atLoc,
IdentifierInfo *Id,
ObjCTypeParamList *typeParamList,
ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc = SourceLocation(),
bool isInternal = false);
static ObjCInterfaceDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc,
const IdentifierInfo *Id, ObjCTypeParamList *typeParamList,
ObjCInterfaceDecl *PrevDecl,
SourceLocation ClassLoc = SourceLocation(), bool isInternal = false);

static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);

Expand Down Expand Up @@ -1338,7 +1338,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
ObjCImplementationDecl *getImplementation() const;
void setImplementation(ObjCImplementationDecl *ImplD);

ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
ObjCCategoryDecl *
FindCategoryDeclaration(const IdentifierInfo *CategoryId) const;

// Get the local instance/class method declared in a category.
ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
Expand Down Expand Up @@ -1794,9 +1795,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
data().CategoryList = category;
}

ObjCPropertyDecl
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;
ObjCPropertyDecl *
FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;

void collectPropertiesToImplement(PropertyMap &PM) const override;

Expand Down Expand Up @@ -1954,8 +1955,8 @@ class ObjCIvarDecl : public FieldDecl {

private:
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
bool synthesized)
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
/*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
Expand All @@ -1964,10 +1965,9 @@ class ObjCIvarDecl : public FieldDecl {
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW = nullptr,
bool synthesized=false);
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, AccessControl ac,
Expr *BW = nullptr, bool synthesized = false);

static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);

Expand Down Expand Up @@ -2343,7 +2343,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl {

ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc = SourceLocation(),
SourceLocation IvarRBraceLoc = SourceLocation());
Expand All @@ -2354,15 +2354,13 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
friend class ASTDeclReader;
friend class ASTDeclWriter;

static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation AtLoc,
SourceLocation ClassNameLoc,
SourceLocation CategoryNameLoc,
IdentifierInfo *Id,
ObjCInterfaceDecl *IDecl,
ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation());
static ObjCCategoryDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc = SourceLocation(),
SourceLocation IvarRBraceLoc = SourceLocation());
static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);

ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
Expand Down Expand Up @@ -2472,10 +2470,9 @@ class ObjCImplDecl : public ObjCContainerDecl {
void anchor() override;

protected:
ObjCImplDecl(Kind DK, DeclContext *DC,
ObjCInterfaceDecl *classInterface,
IdentifierInfo *Id,
SourceLocation nameLoc, SourceLocation atStartLoc)
ObjCImplDecl(Kind DK, DeclContext *DC, ObjCInterfaceDecl *classInterface,
const IdentifierInfo *Id, SourceLocation nameLoc,
SourceLocation atStartLoc)
: ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
ClassInterface(classInterface) {}

Expand Down Expand Up @@ -2543,12 +2540,12 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
// Category name location
SourceLocation CategoryNameLoc;

ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
ObjCCategoryImplDecl(DeclContext *DC, const IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface,
SourceLocation nameLoc, SourceLocation atStartLoc,
SourceLocation CategoryNameLoc)
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
nameLoc, atStartLoc),
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, nameLoc,
atStartLoc),
CategoryNameLoc(CategoryNameLoc) {}

void anchor() override;
Expand All @@ -2557,12 +2554,10 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
friend class ASTDeclReader;
friend class ASTDeclWriter;

static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface,
SourceLocation nameLoc,
SourceLocation atStartLoc,
SourceLocation CategoryNameLoc);
static ObjCCategoryImplDecl *
Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface, SourceLocation nameLoc,
SourceLocation atStartLoc, SourceLocation CategoryNameLoc);
static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);

ObjCCategoryDecl *getCategoryDecl() const;
Expand Down
57 changes: 37 additions & 20 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -1389,27 +1389,27 @@ class NonTypeTemplateParmDecl final

NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
const IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}

NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
ArrayRef<QualType> ExpandedTypes,
ArrayRef<TypeSourceInfo *> ExpandedTInfos);

public:
static NonTypeTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
QualType T, bool ParameterPack, TypeSourceInfo *TInfo);

static NonTypeTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
ArrayRef<TypeSourceInfo *> ExpandedTInfos);

Expand Down Expand Up @@ -1581,26 +1581,36 @@ class TemplateTemplateParmDecl final
DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>;
DefArgStorage DefaultArgument;

/// Whether this template template parameter was declaration with
/// the 'typename' keyword.
///
/// If false, it was declared with the 'class' keyword.
LLVM_PREFERRED_TYPE(bool)
unsigned Typename : 1;

/// Whether this parameter is a parameter pack.
bool ParameterPack;
LLVM_PREFERRED_TYPE(bool)
unsigned ParameterPack : 1;

/// Whether this template template parameter is an "expanded"
/// parameter pack, meaning that it is a pack expansion and we
/// already know the set of template parameters that expansion expands to.
bool ExpandedParameterPack = false;
LLVM_PREFERRED_TYPE(bool)
unsigned ExpandedParameterPack : 1;

/// The number of parameters in an expanded parameter pack.
unsigned NumExpandedParams = 0;

TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P, bool ParameterPack,
IdentifierInfo *Id, TemplateParameterList *Params)
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, bool ParameterPack, IdentifierInfo *Id,
bool Typename, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
TemplateParmPosition(D, P), Typename(Typename),
ParameterPack(ParameterPack), ExpandedParameterPack(false) {}

TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P,
IdentifierInfo *Id, TemplateParameterList *Params,
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, bool Typename,
TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions);

void anchor() override;
Expand All @@ -1613,14 +1623,13 @@ class TemplateTemplateParmDecl final
static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D,
unsigned P, bool ParameterPack,
IdentifierInfo *Id,
IdentifierInfo *Id, bool Typename,
TemplateParameterList *Params);
static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D,
unsigned P,
IdentifierInfo *Id,
TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions);
static TemplateTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, bool Typename,
TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions);

static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
unsigned ID);
Expand All @@ -1634,6 +1643,14 @@ class TemplateTemplateParmDecl final
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;

/// Whether this template template parameter was declared with
/// the 'typename' keyword.
bool wasDeclaredWithTypename() const { return Typename; }

/// Set whether this template template parameter was declared with
/// the 'typename' or 'class' keyword.
void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }

/// Whether this template template parameter is a template
/// parameter pack.
///
Expand Down
45 changes: 19 additions & 26 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3163,23 +3163,12 @@ class CallExpr : public Expr {
}
};

/// Extra data stored in some MemberExpr objects.
struct MemberExprNameQualifier {
/// The nested-name-specifier that qualifies the name, including
/// source-location information.
NestedNameSpecifierLoc QualifierLoc;

/// The DeclAccessPair through which the MemberDecl was found due to
/// name qualifiers.
DeclAccessPair FoundDecl;
};

/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F.
///
class MemberExpr final
: public Expr,
private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier,
ASTTemplateKWAndArgsInfo,
private llvm::TrailingObjects<MemberExpr, NestedNameSpecifierLoc,
DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc> {
friend class ASTReader;
friend class ASTStmtReader;
Expand All @@ -3201,26 +3190,30 @@ class MemberExpr final
/// MemberLoc - This is the location of the member name.
SourceLocation MemberLoc;

size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const {
return hasQualifierOrFoundDecl();
size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
return hasQualifier();
}

size_t numTrailingObjects(OverloadToken<DeclAccessPair>) const {
return hasFoundDecl();
}

size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
return hasTemplateKWAndArgsInfo();
}

bool hasQualifierOrFoundDecl() const {
return MemberExprBits.HasQualifierOrFoundDecl;
}
bool hasFoundDecl() const { return MemberExprBits.HasFoundDecl; }

bool hasTemplateKWAndArgsInfo() const {
return MemberExprBits.HasTemplateKWAndArgsInfo;
}

MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc,
ValueDecl *MemberDecl, const DeclarationNameInfo &NameInfo,
QualType T, ExprValueKind VK, ExprObjectKind OK,
NonOdrUseReason NOUR);
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
ValueDecl *MemberDecl, DeclAccessPair FoundDecl,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs, QualType T,
ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR);
MemberExpr(EmptyShell Empty)
: Expr(MemberExprClass, Empty), Base(), MemberDecl() {}

Expand Down Expand Up @@ -3264,24 +3257,24 @@ class MemberExpr final

/// Retrieves the declaration found by lookup.
DeclAccessPair getFoundDecl() const {
if (!hasQualifierOrFoundDecl())
if (!hasFoundDecl())
return DeclAccessPair::make(getMemberDecl(),
getMemberDecl()->getAccess());
return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl;
return *getTrailingObjects<DeclAccessPair>();
}

/// Determines whether this member expression actually had
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
/// x->Base::foo.
bool hasQualifier() const { return getQualifier() != nullptr; }
bool hasQualifier() const { return MemberExprBits.HasQualifier; }

/// If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name, with source-location
/// information.
NestedNameSpecifierLoc getQualifierLoc() const {
if (!hasQualifierOrFoundDecl())
if (!hasQualifier())
return NestedNameSpecifierLoc();
return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc;
return *getTrailingObjects<NestedNameSpecifierLoc>();
}

/// If the member name was qualified, retrieves the
Expand Down
20 changes: 15 additions & 5 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,7 @@ class CXXThisExpr : public Expr {
CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK)
: Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) {
CXXThisExprBits.IsImplicit = IsImplicit;
CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
CXXThisExprBits.Loc = L;
setDependence(computeDependence(this));
}
Expand All @@ -1170,6 +1171,15 @@ class CXXThisExpr : public Expr {
bool isImplicit() const { return CXXThisExprBits.IsImplicit; }
void setImplicit(bool I) { CXXThisExprBits.IsImplicit = I; }

bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const {
return CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter;
}

void setCapturedByCopyInLambdaWithExplicitObjectParameter(bool Set) {
CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = Set;
setDependence(computeDependence(this));
}

static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXThisExprClass;
}
Expand Down Expand Up @@ -2549,15 +2559,15 @@ class CXXDeleteExpr : public Expr {
class PseudoDestructorTypeStorage {
/// Either the type source information or the name of the type, if
/// it couldn't be resolved due to type-dependence.
llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
llvm::PointerUnion<TypeSourceInfo *, const IdentifierInfo *> Type;

/// The starting source location of the pseudo-destructor type.
SourceLocation Location;

public:
PseudoDestructorTypeStorage() = default;

PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
PseudoDestructorTypeStorage(const IdentifierInfo *II, SourceLocation Loc)
: Type(II), Location(Loc) {}

PseudoDestructorTypeStorage(TypeSourceInfo *Info);
Expand All @@ -2566,8 +2576,8 @@ class PseudoDestructorTypeStorage {
return Type.dyn_cast<TypeSourceInfo *>();
}

IdentifierInfo *getIdentifier() const {
return Type.dyn_cast<IdentifierInfo *>();
const IdentifierInfo *getIdentifier() const {
return Type.dyn_cast<const IdentifierInfo *>();
}

SourceLocation getLocation() const { return Location; }
Expand Down Expand Up @@ -2698,7 +2708,7 @@ class CXXPseudoDestructorExpr : public Expr {
/// In a dependent pseudo-destructor expression for which we do not
/// have full type information on the destroyed type, provides the name
/// of the destroyed type.
IdentifierInfo *getDestroyedTypeIdentifier() const {
const IdentifierInfo *getDestroyedTypeIdentifier() const {
return DestroyedType.getIdentifier();
}

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/ExternalASTSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);

/// Update an out-of-date identifier.
virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {}
virtual void updateOutOfDateIdentifier(const IdentifierInfo &II) {}

/// Find all declarations with the given name in the given context,
/// and add them to the context by calling SetExternalVisibleDeclsForName
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/JSONNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ class JSONNodeDumper
void Visit(const TemplateArgument &TA, SourceRange R = {},
const Decl *From = nullptr, StringRef Label = {});
void Visit(const CXXCtorInitializer *Init);
void Visit(const OpenACCClause *C);
void Visit(const OMPClause *C);
void Visit(const BlockDecl::Capture &C);
void Visit(const GenericSelectionExpr::ConstAssociation &A);
Expand Down Expand Up @@ -309,6 +310,8 @@ class JSONNodeDumper
void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE);
void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *ME);
void VisitRequiresExpr(const RequiresExpr *RE);
void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node);
void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node);

void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE);
void VisitObjCMessageExpr(const ObjCMessageExpr *OME);
Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/AST/NestedNameSpecifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// cannot be resolved.
static NestedNameSpecifier *Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
IdentifierInfo *II);
const IdentifierInfo *II);

/// Builds a nested name specifier that names a namespace.
static NestedNameSpecifier *Create(const ASTContext &Context,
Expand All @@ -134,7 +134,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// Builds a nested name specifier that names a namespace alias.
static NestedNameSpecifier *Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
NamespaceAliasDecl *Alias);
const NamespaceAliasDecl *Alias);

/// Builds a nested name specifier that names a type.
static NestedNameSpecifier *Create(const ASTContext &Context,
Expand All @@ -148,7 +148,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
/// type.
static NestedNameSpecifier *Create(const ASTContext &Context,
IdentifierInfo *II);
const IdentifierInfo *II);

/// Returns the nested name specifier representing the global
/// scope.
Expand Down
245 changes: 245 additions & 0 deletions clang/include/clang/AST/OpenACCClause.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
//===- OpenACCClause.h - Classes for OpenACC clauses ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// \file
// This file defines OpenACC AST classes for clauses.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_OPENACCCLAUSE_H
#define LLVM_CLANG_AST_OPENACCCLAUSE_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/StmtIterator.h"
#include "clang/Basic/OpenACCKinds.h"

namespace clang {
/// This is the base type for all OpenACC Clauses.
class OpenACCClause {
OpenACCClauseKind Kind;
SourceRange Location;

protected:
OpenACCClause(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation EndLoc)
: Kind(K), Location(BeginLoc, EndLoc) {}

public:
OpenACCClauseKind getClauseKind() const { return Kind; }
SourceLocation getBeginLoc() const { return Location.getBegin(); }
SourceLocation getEndLoc() const { return Location.getEnd(); }

static bool classof(const OpenACCClause *) { return true; }

using child_iterator = StmtIterator;
using const_child_iterator = ConstStmtIterator;
using child_range = llvm::iterator_range<child_iterator>;
using const_child_range = llvm::iterator_range<const_child_iterator>;

child_range children();
const_child_range children() const {
auto Children = const_cast<OpenACCClause *>(this)->children();
return const_child_range(Children.begin(), Children.end());
}

virtual ~OpenACCClause() = default;
};

/// Represents a clause that has a list of parameters.
class OpenACCClauseWithParams : public OpenACCClause {
/// Location of the '('.
SourceLocation LParenLoc;

protected:
OpenACCClauseWithParams(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OpenACCClause(K, BeginLoc, EndLoc), LParenLoc(LParenLoc) {}

public:
SourceLocation getLParenLoc() const { return LParenLoc; }

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

/// A 'default' clause, has the optional 'none' or 'present' argument.
class OpenACCDefaultClause : public OpenACCClauseWithParams {
friend class ASTReaderStmt;
friend class ASTWriterStmt;

OpenACCDefaultClauseKind DefaultClauseKind;

protected:
OpenACCDefaultClause(OpenACCDefaultClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
: OpenACCClauseWithParams(OpenACCClauseKind::Default, BeginLoc, LParenLoc,
EndLoc),
DefaultClauseKind(K) {
assert((DefaultClauseKind == OpenACCDefaultClauseKind::None ||
DefaultClauseKind == OpenACCDefaultClauseKind::Present) &&
"Invalid Clause Kind");
}

public:
OpenACCDefaultClauseKind getDefaultClauseKind() const {
return DefaultClauseKind;
}

static OpenACCDefaultClause *Create(const ASTContext &C,
OpenACCDefaultClauseKind K,
SourceLocation BeginLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
};

/// Represents one of the handful of classes that has an optional/required
/// 'condition' expression as an argument.
class OpenACCClauseWithCondition : public OpenACCClauseWithParams {
Expr *ConditionExpr = nullptr;

protected:
OpenACCClauseWithCondition(OpenACCClauseKind K, SourceLocation BeginLoc,
SourceLocation LParenLoc, Expr *ConditionExpr,
SourceLocation EndLoc)
: OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc),
ConditionExpr(ConditionExpr) {}

public:
bool hasConditionExpr() const { return ConditionExpr; }
const Expr *getConditionExpr() const { return ConditionExpr; }
Expr *getConditionExpr() { return ConditionExpr; }

child_range children() {
if (ConditionExpr)
return child_range(reinterpret_cast<Stmt **>(&ConditionExpr),
reinterpret_cast<Stmt **>(&ConditionExpr + 1));
return child_range(child_iterator(), child_iterator());
}

const_child_range children() const {
if (ConditionExpr)
return const_child_range(
reinterpret_cast<Stmt *const *>(&ConditionExpr),
reinterpret_cast<Stmt *const *>(&ConditionExpr + 1));
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

/// An 'if' clause, which has a required condition expression.
class OpenACCIfClause : public OpenACCClauseWithCondition {
protected:
OpenACCIfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
Expr *ConditionExpr, SourceLocation EndLoc);

public:
static OpenACCIfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
SourceLocation LParenLoc, Expr *ConditionExpr,
SourceLocation EndLoc);
};

template <class Impl> class OpenACCClauseVisitor {
Impl &getDerived() { return static_cast<Impl &>(*this); }

public:
void VisitClauseList(ArrayRef<const OpenACCClause *> List) {
for (const OpenACCClause *Clause : List)
Visit(Clause);
}

void Visit(const OpenACCClause *C) {
if (!C)
return;

switch (C->getClauseKind()) {
case OpenACCClauseKind::Default:
VisitDefaultClause(*cast<OpenACCDefaultClause>(C));
return;
case OpenACCClauseKind::If:
VisitIfClause(*cast<OpenACCIfClause>(C));
return;
case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Seq:
case OpenACCClauseKind::Independent:
case OpenACCClauseKind::Auto:
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector:
case OpenACCClauseKind::NoHost:
case OpenACCClauseKind::Self:
case OpenACCClauseKind::Copy:
case OpenACCClauseKind::UseDevice:
case OpenACCClauseKind::Attach:
case OpenACCClauseKind::Delete:
case OpenACCClauseKind::Detach:
case OpenACCClauseKind::Device:
case OpenACCClauseKind::DevicePtr:
case OpenACCClauseKind::DeviceResident:
case OpenACCClauseKind::FirstPrivate:
case OpenACCClauseKind::Host:
case OpenACCClauseKind::Link:
case OpenACCClauseKind::NoCreate:
case OpenACCClauseKind::Present:
case OpenACCClauseKind::Private:
case OpenACCClauseKind::CopyOut:
case OpenACCClauseKind::CopyIn:
case OpenACCClauseKind::Create:
case OpenACCClauseKind::Reduction:
case OpenACCClauseKind::Collapse:
case OpenACCClauseKind::Bind:
case OpenACCClauseKind::VectorLength:
case OpenACCClauseKind::NumGangs:
case OpenACCClauseKind::NumWorkers:
case OpenACCClauseKind::DeviceNum:
case OpenACCClauseKind::DefaultAsync:
case OpenACCClauseKind::DeviceType:
case OpenACCClauseKind::DType:
case OpenACCClauseKind::Async:
case OpenACCClauseKind::Tile:
case OpenACCClauseKind::Gang:
case OpenACCClauseKind::Wait:
case OpenACCClauseKind::Invalid:
llvm_unreachable("Clause visitor not yet implemented");
}
llvm_unreachable("Invalid Clause kind");
}

#define VISIT_CLAUSE(CLAUSE_NAME) \
void Visit##CLAUSE_NAME##Clause( \
const OpenACC##CLAUSE_NAME##Clause &Clause) { \
return getDerived().Visit##CLAUSE_NAME##Clause(Clause); \
}

#include "clang/Basic/OpenACCClauses.def"
};

class OpenACCClausePrinter final
: public OpenACCClauseVisitor<OpenACCClausePrinter> {
raw_ostream &OS;

public:
void VisitClauseList(ArrayRef<const OpenACCClause *> List) {
for (const OpenACCClause *Clause : List) {
Visit(Clause);

if (Clause != List.back())
OS << ' ';
}
}
OpenACCClausePrinter(raw_ostream &OS) : OS(OS) {}

#define VISIT_CLAUSE(CLAUSE_NAME) \
void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
#include "clang/Basic/OpenACCClauses.def"
};

} // namespace clang

#endif // LLVM_CLANG_AST_OPENACCCLAUSE_H
3 changes: 3 additions & 0 deletions clang/include/clang/AST/OperationKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,9 @@ CAST_OPERATION(IntToOCLSampler)
// Truncate a vector type by dropping elements from the end (HLSL only).
CAST_OPERATION(HLSLVectorTruncation)

// Non-decaying array RValue cast (HLSL only).
CAST_OPERATION(HLSLArrayRValue)

//===- Binary Operations -------------------------------------------------===//
// Operators listed in order of precedence.
// Note that additions to this should also update the StmtVisitor class,
Expand Down
24 changes: 22 additions & 2 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ template <typename Derived> class RecursiveASTVisitor {
bool TraverseOpenACCConstructStmt(OpenACCConstructStmt *S);
bool
TraverseOpenACCAssociatedStmtConstruct(OpenACCAssociatedStmtConstruct *S);
bool VisitOpenACCClauseList(ArrayRef<const OpenACCClause *>);
};

template <typename Derived>
Expand Down Expand Up @@ -993,6 +994,12 @@ DEF_TRAVERSE_TYPE(ConstantArrayType, {
TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr())));
})

DEF_TRAVERSE_TYPE(ArrayParameterType, {
TRY_TO(TraverseType(T->getElementType()));
if (T->getSizeExpr())
TRY_TO(TraverseStmt(const_cast<Expr *>(T->getSizeExpr())));
})

DEF_TRAVERSE_TYPE(IncompleteArrayType,
{ TRY_TO(TraverseType(T->getElementType())); })

Expand Down Expand Up @@ -1260,6 +1267,11 @@ DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
TRY_TO(TraverseArrayTypeLocHelper(TL));
})

DEF_TRAVERSE_TYPELOC(ArrayParameterType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
TRY_TO(TraverseArrayTypeLocHelper(TL));
})

DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
TRY_TO(TraverseArrayTypeLocHelper(TL));
Expand Down Expand Up @@ -3925,8 +3937,8 @@ bool RecursiveASTVisitor<Derived>::VisitOMPXBareClause(OMPXBareClause *C) {

template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
OpenACCConstructStmt *) {
// TODO OpenACC: When we implement clauses, ensure we traverse them here.
OpenACCConstructStmt *C) {
TRY_TO(VisitOpenACCClauseList(C->clauses()));
return true;
}

Expand All @@ -3938,6 +3950,14 @@ bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
return true;
}

template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
ArrayRef<const OpenACCClause *>) {
// TODO OpenACC: When we have Clauses with expressions, we should visit them
// here.
return true;
}

DEF_TRAVERSE_STMT(OpenACCComputeConstruct,
{ TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })

Expand Down
15 changes: 11 additions & 4 deletions clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,13 @@ class alignas(void *) Stmt {
unsigned IsArrow : 1;

/// True if this member expression used a nested-name-specifier to
/// refer to the member, e.g., "x->Base::f", or found its member via
/// a using declaration. When true, a MemberExprNameQualifier
/// structure is allocated immediately after the MemberExpr.
/// refer to the member, e.g., "x->Base::f".
LLVM_PREFERRED_TYPE(bool)
unsigned HasQualifierOrFoundDecl : 1;
unsigned HasQualifier : 1;

// True if this member expression found its member via a using declaration.
LLVM_PREFERRED_TYPE(bool)
unsigned HasFoundDecl : 1;

/// True if this member expression specified a template keyword
/// and/or a template argument list explicitly, e.g., x->f<int>,
Expand Down Expand Up @@ -782,6 +784,11 @@ class alignas(void *) Stmt {
LLVM_PREFERRED_TYPE(bool)
unsigned IsImplicit : 1;

/// Whether there is a lambda with an explicit object parameter that
/// captures this "this" by copy.
LLVM_PREFERRED_TYPE(bool)
unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1;

/// The location of the "this".
SourceLocation Loc;
};
Expand Down
55 changes: 46 additions & 9 deletions clang/include/clang/AST/StmtOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#ifndef LLVM_CLANG_AST_STMTOPENACC_H
#define LLVM_CLANG_AST_STMTOPENACC_H

#include "clang/AST/OpenACCClause.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/SourceLocation.h"
#include <memory>

namespace clang {
/// This is the base class for an OpenACC statement-level construct, other
Expand All @@ -30,13 +32,23 @@ class OpenACCConstructStmt : public Stmt {
/// the directive.
SourceRange Range;

// TODO OPENACC: Clauses should probably be collected in this class.
/// The list of clauses. This is stored here as an ArrayRef, as this is the
/// most convienient place to access the list, however the list itself should
/// be stored in leaf nodes, likely in trailing-storage.
MutableArrayRef<const OpenACCClause *> Clauses;

protected:
OpenACCConstructStmt(StmtClass SC, OpenACCDirectiveKind K,
SourceLocation Start, SourceLocation End)
: Stmt(SC), Kind(K), Range(Start, End) {}

// Used only for initialization, the leaf class can initialize this to
// trailing storage.
void setClauseList(MutableArrayRef<const OpenACCClause *> NewClauses) {
assert(Clauses.empty() && "Cannot change clause list");
Clauses = NewClauses;
}

public:
OpenACCDirectiveKind getDirectiveKind() const { return Kind; }

Expand All @@ -47,6 +59,7 @@ class OpenACCConstructStmt : public Stmt {

SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
ArrayRef<const OpenACCClause *> clauses() const { return Clauses; }

child_range children() {
return child_range(child_iterator(), child_iterator());
Expand Down Expand Up @@ -101,24 +114,46 @@ class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt {
/// those three, as they are semantically identical, and have only minor
/// differences in the permitted list of clauses, which can be differentiated by
/// the 'Kind'.
class OpenACCComputeConstruct : public OpenACCAssociatedStmtConstruct {
class OpenACCComputeConstruct final
: public OpenACCAssociatedStmtConstruct,
public llvm::TrailingObjects<OpenACCComputeConstruct,
const OpenACCClause *> {
friend class ASTStmtWriter;
friend class ASTStmtReader;
friend class ASTContext;
OpenACCComputeConstruct()
: OpenACCAssociatedStmtConstruct(
OpenACCComputeConstructClass, OpenACCDirectiveKind::Invalid,
SourceLocation{}, SourceLocation{}, /*AssociatedStmt=*/nullptr) {}
OpenACCComputeConstruct(unsigned NumClauses)
: OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass,
OpenACCDirectiveKind::Invalid,
SourceLocation{}, SourceLocation{},
/*AssociatedStmt=*/nullptr) {
// We cannot send the TrailingObjects storage to the base class (which holds
// a reference to the data) until it is constructed, so we have to set it
// separately here.
std::uninitialized_value_construct(
getTrailingObjects<const OpenACCClause *>(),
getTrailingObjects<const OpenACCClause *>() + NumClauses);
setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
NumClauses));
}

OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start,
SourceLocation End, Stmt *StructuredBlock)
SourceLocation End,
ArrayRef<const OpenACCClause *> Clauses,
Stmt *StructuredBlock)
: OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass, K, Start,
End, StructuredBlock) {
assert((K == OpenACCDirectiveKind::Parallel ||
K == OpenACCDirectiveKind::Serial ||
K == OpenACCDirectiveKind::Kernels) &&
"Only parallel, serial, and kernels constructs should be "
"represented by this type");

// Initialize the trailing storage.
std::uninitialized_copy(Clauses.begin(), Clauses.end(),
getTrailingObjects<const OpenACCClause *>());

setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
Clauses.size()));
}

void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); }
Expand All @@ -128,10 +163,12 @@ class OpenACCComputeConstruct : public OpenACCAssociatedStmtConstruct {
return T->getStmtClass() == OpenACCComputeConstructClass;
}

static OpenACCComputeConstruct *CreateEmpty(const ASTContext &C, EmptyShell);
static OpenACCComputeConstruct *CreateEmpty(const ASTContext &C,
unsigned NumClauses);
static OpenACCComputeConstruct *
Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc,
SourceLocation EndLoc, Stmt *StructuredBlock);
SourceLocation EndLoc, ArrayRef<const OpenACCClause *> Clauses,
Stmt *StructuredBlock);

Stmt *getStructuredBlock() { return getAssociatedStmt(); }
const Stmt *getStructuredBlock() const {
Expand Down
11 changes: 10 additions & 1 deletion clang/include/clang/AST/StmtOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -6109,6 +6109,8 @@ class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
/// true if loop directive's associated loop can be a parallel for.
bool CanBeParallelFor = false;
/// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
Expand All @@ -6131,6 +6133,9 @@ class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
llvm::omp::OMPD_target_teams_loop, SourceLocation(),
SourceLocation(), CollapsedNum) {}

/// Set whether associated loop can be a parallel for.
void setCanBeParallelFor(bool ParFor) { CanBeParallelFor = ParFor; }

public:
/// Creates directive with a list of \p Clauses.
///
Expand All @@ -6145,7 +6150,7 @@ class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
static OMPTargetTeamsGenericLoopDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs);
Stmt *AssociatedStmt, const HelperExprs &Exprs, bool CanBeParallelFor);

/// Creates an empty directive with the place
/// for \a NumClauses clauses.
Expand All @@ -6159,6 +6164,10 @@ class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
unsigned CollapsedNum,
EmptyShell);

/// Return true if current loop directive's associated loop can be a
/// parallel for.
bool canBeParallelFor() const { return CanBeParallelFor; }

static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
}
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ class TextNodeDumper

void Visit(const OMPClause *C);

void Visit(const OpenACCClause *C);

void Visit(const BlockDecl::Capture &C);

void Visit(const GenericSelectionExpr::ConstAssociation &A);
Expand Down
45 changes: 40 additions & 5 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -2300,6 +2300,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isConstantArrayType() const;
bool isIncompleteArrayType() const;
bool isVariableArrayType() const;
bool isArrayParameterType() const;
bool isDependentSizedArrayType() const;
bool isRecordType() const;
bool isClassType() const;
Expand Down Expand Up @@ -3334,14 +3335,15 @@ class ArrayType : public Type, public llvm::FoldingSetNode {
return T->getTypeClass() == ConstantArray ||
T->getTypeClass() == VariableArray ||
T->getTypeClass() == IncompleteArray ||
T->getTypeClass() == DependentSizedArray;
T->getTypeClass() == DependentSizedArray ||
T->getTypeClass() == ArrayParameter;
}
};

/// Represents the canonical version of C arrays with a specified constant size.
/// For example, the canonical type for 'int A[4 + 4*100]' is a
/// ConstantArrayType where the element type is 'int' and the size is 404.
class ConstantArrayType final : public ArrayType {
class ConstantArrayType : public ArrayType {
friend class ASTContext; // ASTContext creates these.

struct ExternalSize {
Expand Down Expand Up @@ -3382,6 +3384,19 @@ class ConstantArrayType final : public ArrayType {
const Expr *SzExpr, ArraySizeModifier SzMod,
unsigned Qual);

protected:
ConstantArrayType(TypeClass Tc, const ConstantArrayType *ATy, QualType Can)
: ArrayType(Tc, ATy->getElementType(), Can, ATy->getSizeModifier(),
ATy->getIndexTypeQualifiers().getAsOpaqueValue(), nullptr) {
ConstantArrayTypeBits.HasExternalSize =
ATy->ConstantArrayTypeBits.HasExternalSize;
if (!ConstantArrayTypeBits.HasExternalSize) {
ConstantArrayTypeBits.SizeWidth = ATy->ConstantArrayTypeBits.SizeWidth;
Size = ATy->Size;
} else
SizePtr = ATy->SizePtr;
}

public:
/// Return the constant array size as an APInt.
llvm::APInt getSize() const {
Expand Down Expand Up @@ -3453,7 +3468,22 @@ class ConstantArrayType final : public ArrayType {
ArraySizeModifier SizeMod, unsigned TypeQuals);

static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray;
return T->getTypeClass() == ConstantArray ||
T->getTypeClass() == ArrayParameter;
}
};

/// Represents a constant array type that does not decay to a pointer when used
/// as a function parameter.
class ArrayParameterType : public ConstantArrayType {
friend class ASTContext; // ASTContext creates these.

ArrayParameterType(const ConstantArrayType *ATy, QualType CanTy)
: ConstantArrayType(ArrayParameter, ATy, CanTy) {}

public:
static bool classof(const Type *T) {
return T->getTypeClass() == ArrayParameter;
}
};

Expand Down Expand Up @@ -7185,7 +7215,8 @@ inline bool QualType::isCanonicalAsParam() const {
if (T->isVariablyModifiedType() && T->hasSizedVLAType())
return false;

return !isa<FunctionType>(T) && !isa<ArrayType>(T);
return !isa<FunctionType>(T) &&
(!isa<ArrayType>(T) || isa<ArrayParameterType>(T));
}

inline bool QualType::isConstQualified() const {
Expand Down Expand Up @@ -7450,6 +7481,10 @@ inline bool Type::isVariableArrayType() const {
return isa<VariableArrayType>(CanonicalType);
}

inline bool Type::isArrayParameterType() const {
return isa<ArrayParameterType>(CanonicalType);
}

inline bool Type::isDependentSizedArrayType() const {
return isa<DependentSizedArrayType>(CanonicalType);
}
Expand Down Expand Up @@ -7813,7 +7848,7 @@ inline bool Type::isTypedefNameType() const {

/// Determines whether this type can decay to a pointer type.
inline bool Type::canDecayToPointerType() const {
return isFunctionType() || isArrayType();
return isFunctionType() || (isArrayType() && !isArrayParameterType());
}

inline bool Type::hasPointerRepresentation() const {
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/TypeLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1611,6 +1611,11 @@ class ConstantArrayTypeLoc :
ConstantArrayType> {
};

/// Wrapper for source info for array parameter types.
class ArrayParameterTypeLoc
: public InheritingConcreteTypeLoc<
ConstantArrayTypeLoc, ArrayParameterTypeLoc, ArrayParameterType> {};

class IncompleteArrayTypeLoc :
public InheritingConcreteTypeLoc<ArrayTypeLoc,
IncompleteArrayTypeLoc,
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ let Class = ConstantArrayType in {
}]>;
}

let Class = ArrayParameterType in {
def : Creator<[{ return ctx.getAdjustedParameterType(
ctx.getConstantArrayType(elementType,sizeValue,
size,sizeModifier,
indexQualifiers.getCVRQualifiers())); }]>;
}

let Class = IncompleteArrayType in {
def : Creator<[{
return ctx.getIncompleteArrayType(elementType, sizeModifier,
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4961,6 +4961,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, internal::Matcher<LambdaCapture>,
/// capturesVar(hasName("x")) matches `x` and `x = 1`.
AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher<ValueDecl>,
InnerMatcher) {
if (!Node.capturesVariable())
return false;
auto *capturedVar = Node.getCapturedVar();
return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
}
Expand Down
Loading