6 changes: 5 additions & 1 deletion clang-tools-extra/pseudo/lib/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ add_clang_library(clangPseudoCXX
cxx_gen

LINK_LIBS
clangBasic
clangPseudo
clangPseudoGrammar
)

clang_target_link_libraries(clangPseudoCXX
PRIVATE
clangBasic
)
11 changes: 1 addition & 10 deletions clang-tools-extra/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,8 @@ if (NOT WIN32 OR NOT LLVM_LINK_LLVM_DYLIB)
PLUGIN_TOOL clang-tidy)
endif()

if(CLANG_BUILT_STANDALONE)
# LLVMHello library is needed below
if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Transforms/Hello
AND NOT TARGET LLVMHello)
add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Transforms/Hello
lib/Transforms/Hello)
endif()
endif()

if(TARGET CTTestTidyModule)
list(APPEND CLANG_TOOLS_TEST_DEPS CTTestTidyModule LLVMHello)
list(APPEND CLANG_TOOLS_TEST_DEPS CTTestTidyModule)
target_include_directories(CTTestTidyModule PUBLIC BEFORE "${CLANG_TOOLS_SOURCE_DIR}")
if(CLANG_PLUGIN_SUPPORT AND (WIN32 OR CYGWIN))
set(LLVM_LINK_COMPONENTS
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/test/clang-tidy/CTTestTidyModule.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// REQUIRES: plugins
// RUN: clang-tidy -checks='-*,mytest*' --list-checks -load %llvmshlibdir/CTTestTidyModule%pluginext -load %llvmshlibdir/LLVMHello%pluginext | FileCheck --check-prefix=CHECK-LIST %s
// RUN: clang-tidy -checks='-*,mytest*' --list-checks -load %llvmshlibdir/CTTestTidyModule%pluginext | FileCheck --check-prefix=CHECK-LIST %s
// CHECK-LIST: Enabled checks:
// CHECK-LIST-NEXT: mytest1
// CHECK-LIST-NEXT: mytest2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,37 @@ void instantiate(const int &param, const float &paramf, int &mut_param, float &m
}

} // namespace valid

namespace overload {

int const &overload_base(int const &a) { return a; }
int const &overload_base(int &&a);

int const &overload_ret_type(int const &a) { return a; }
void overload_ret_type(int &&a);

int const &overload_params1(int p1, int const &a) { return a; }
int const & overload_params1(int p1, int &&a);

int const &overload_params2(int p1, int const &a, int p2) { return a; }
int const &overload_params2(int p1, int &&a, int p2);

int const &overload_params3(T p1, int const &a, int p2) { return a; }
int const &overload_params3(int p1, int &&a, T p2);

int const &overload_params_const(int p1, int const &a, int const p2) { return a; }
int const &overload_params_const(int const p1, int &&a, int p2);

int const &overload_params_difference1(int p1, int const &a, int p2) { return a; }
// CHECK-MESSAGES: :[[@LINE-1]]:79: warning: returning a constant reference parameter
int const &overload_params_difference1(long p1, int &&a, int p2);

int const &overload_params_difference2(int p1, int const &a, int p2) { return a; }
// CHECK-MESSAGES: :[[@LINE-1]]:79: warning: returning a constant reference parameter
int const &overload_params_difference2(int p1, int &&a, long p2);

int const &overload_params_difference3(int p1, int const &a, int p2) { return a; }
// CHECK-MESSAGES: :[[@LINE-1]]:79: warning: returning a constant reference parameter
int const &overload_params_difference3(int p1, long &&a, int p2);

} // namespace overload
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,24 @@ int Test5() {

int sum = 0;
sum += sizeof(&S);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(__typeof(&S));
sum += sizeof(&TS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(__typeof(&TS));
sum += sizeof(STRKWD MyStruct*);
sum += sizeof(__typeof(STRKWD MyStruct*));
sum += sizeof(TypedefStruct*);
sum += sizeof(__typeof(TypedefStruct*));
sum += sizeof(PTTS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PMyStruct);
sum += sizeof(PS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PS2);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&A10);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer

#ifdef __cplusplus
MyStruct &rS = S;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true, bugprone-sizeof-expression.WarnOnSizeOfPointer: true}}" --

class C {
int size() { return sizeof(this); }
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)'
};

#define LEN 8

int X;
extern int A[10];
extern short B[10];

#pragma pack(1)
struct S { char a, b, c; };

enum E { E_VALUE = 0 };
enum class EC { VALUE = 0 };

bool AsBool() { return false; }
int AsInt() { return 0; }
E AsEnum() { return E_VALUE; }
EC AsEnumClass() { return EC::VALUE; }
S AsStruct() { return {}; }

struct M {
int AsInt() { return 0; }
E AsEnum() { return E_VALUE; }
S AsStruct() { return {}; }
};

int Test1(const char* ptr) {
int sum = 0;
sum += sizeof(LEN);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
sum += sizeof(LEN + 1);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
sum += sizeof(sum, LEN);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(..., ...)'
sum += sizeof(AsBool());
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
sum += sizeof(AsInt());
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
sum += sizeof(AsEnum());
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
sum += sizeof(AsEnumClass());
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
sum += sizeof(M{}.AsInt());
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
sum += sizeof(M{}.AsEnum());
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
sum += sizeof(sizeof(X));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
sum += sizeof(LEN + sizeof(X));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
sum += sizeof(LEN + LEN + sizeof(X));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
sum += sizeof(LEN + (LEN + sizeof(X)));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
sum += sizeof(LEN + -sizeof(X));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
sum += sizeof(LEN + - + -sizeof(X));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
sum += sizeof(char) / sizeof(char);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
sum += sizeof(A) / sizeof(S);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
sum += sizeof(char) / sizeof(int);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
sum += sizeof(char) / sizeof(A);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
sum += sizeof(B[0]) / sizeof(A);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
sum += sizeof(ptr) / sizeof(char);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(ptr) / sizeof(ptr[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(ptr) / sizeof(char*);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(ptr) / sizeof(void*);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(ptr) / sizeof(const void volatile*);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(ptr) / sizeof(char);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(int) * sizeof(char);
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication
sum += sizeof(ptr) * sizeof(ptr[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication
sum += sizeof(int) * (2 * sizeof(char));
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication
sum += (2 * sizeof(char)) * sizeof(int);
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious 'sizeof' by 'sizeof' multiplication
if (sizeof(A) < 0x100000) sum += 42;
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant
if (sizeof(A) <= 0xFFFFFFFEU) sum += 42;
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant
return sum;
}

int Test5() {
typedef int Array10[10];
typedef C ArrayC[10];

struct MyStruct {
Array10 arr;
Array10* ptr;
};
typedef const MyStruct TMyStruct;
typedef const MyStruct *PMyStruct;
typedef TMyStruct *PMyStruct2;

static TMyStruct kGlocalMyStruct = {};
static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct;

MyStruct S;
PMyStruct PS;
PMyStruct2 PS2;
Array10 A10;
C *PtrArray[10];
C *PC;

char *PChar;
int *PInt, **PPInt;
MyStruct **PPMyStruct;

int sum = 0;
sum += sizeof(&S.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&kGlocalMyStruct.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&kGlocalMyStructPtr->arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(S.arr + 0);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(+ S.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof((int*)S.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer

sum += sizeof(S.ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(kGlocalMyStruct.ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(kGlocalMyStructPtr->ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer

sum += sizeof(&kGlocalMyStruct);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&S);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(MyStruct*);
sum += sizeof(PMyStruct);
sum += sizeof(PS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PS2);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&A10);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PtrArray) / sizeof(PtrArray[1]);
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(A10) / sizeof(PtrArray[0]);
sum += sizeof(PC) / sizeof(PtrArray[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
// CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
sum += sizeof(ArrayC) / sizeof(PtrArray[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator

sum += sizeof(PChar);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PInt);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PPInt);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PPMyStruct);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer

return sum;
}

void some_generic_function(const void *arg, int argsize);
int *IntP, **IntPP;
C *ClassP, **ClassPP;

void GenericFunctionTest() {
// The `sizeof(pointer)` checks ignore situations where the pointer is
// produced by dereferencing a pointer-to-pointer, because this is unlikely
// to be an accident and can appear in legitimate code that tries to call
// a generic function which emulates dynamic typing within C.
some_generic_function(IntPP, sizeof(*IntPP));
some_generic_function(ClassPP, sizeof(*ClassPP));
// Using `...[0]` instead of the dereference operator is another common
// variant, which is also widespread in the idiomatic array-size calculation:
// `sizeof(array) / sizeof(array[0])`.
some_generic_function(IntPP, sizeof(IntPP[0]));
some_generic_function(ClassPP, sizeof(ClassPP[0]));
// FIXME: There is a third common pattern where the generic function is
// called with `&Variable` and `sizeof(Variable)`. Right now these are
// reported by the `sizeof(pointer)` checks, but this causes some false
// positives, so it would be good to create an exception for them.
some_generic_function(&IntPP, sizeof(IntP));
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
some_generic_function(&ClassPP, sizeof(ClassP));
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
}

int ValidExpressions() {
int A[] = {1, 2, 3, 4};
static const char str[] = "hello";
static const char* ptr[] { "aaa", "bbb", "ccc" };
typedef C *CA10[10];
C *PtrArray[10];
CA10 PtrArray1;

int sum = 0;
if (sizeof(A) < 10)
sum += sizeof(A);
sum += sizeof(int);
sum += sizeof(AsStruct());
sum += sizeof(M{}.AsStruct());
sum += sizeof(A[sizeof(A) / sizeof(int)]);
// Here the outer sizeof is reported, but the inner ones are accepted:
sum += sizeof(&A[sizeof(A) / sizeof(int)]);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(sizeof(0)); // Special case: sizeof size_t.
sum += sizeof(void*);
sum += sizeof(void const *);
sum += sizeof(void const *) / 4;
sum += sizeof(str);
sum += sizeof(str) / sizeof(char);
sum += sizeof(str) / sizeof(str[0]);
sum += sizeof(ptr) / sizeof(ptr[0]);
sum += sizeof(ptr) / sizeof(*(ptr));
sum += sizeof(PtrArray) / sizeof(PtrArray[0]);
// Canonical type of PtrArray1 is same as PtrArray.
sum = sizeof(PtrArray) / sizeof(PtrArray1[0]);
// There is no warning for 'sizeof(T*)/sizeof(Q)' case.
sum += sizeof(PtrArray) / sizeof(A[0]);
return sum;
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ int Test1(const char* ptr) {
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'
sum += sizeof(ptr) / sizeof(char);
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
sum += sizeof(ptr) / sizeof(ptr[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
sum += sizeof(int) * sizeof(char);
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication
sum += sizeof(ptr) * sizeof(ptr[0]);
Expand Down Expand Up @@ -207,50 +205,57 @@ int Test5() {
C *PtrArray[10];
C *PC;

char *PChar;
int *PInt, **PPInt;
MyStruct **PPMyStruct;

int sum = 0;
sum += sizeof(&S.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&kGlocalMyStruct.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&kGlocalMyStructPtr->arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(S.arr + 0);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(+ S.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof((int*)S.arr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer

sum += sizeof(S.ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(kGlocalMyStruct.ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(kGlocalMyStructPtr->ptr);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer

sum += sizeof(&kGlocalMyStruct);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&S);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(MyStruct*);
sum += sizeof(PMyStruct);
sum += sizeof(PS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PS2);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&A10);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PtrArray) / sizeof(PtrArray[1]);
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(A10) / sizeof(PtrArray[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
sum += sizeof(PC) / sizeof(PtrArray[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
// CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
// CHECK-MESSAGES: :[[@LINE-3]]:23: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
sum += sizeof(ArrayC) / sizeof(PtrArray[0]);
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
// CHECK-MESSAGES: :[[@LINE-2]]:27: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate

// These pointers do not point to aggregate types, so they are not reported in this mode:
sum += sizeof(PChar);
sum += sizeof(PInt);
sum += sizeof(PPInt);
sum += sizeof(PPMyStruct);

return sum;
}
Expand Down Expand Up @@ -293,6 +298,32 @@ bool Baz() { return sizeof(A) < N; }
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: suspicious comparison of 'sizeof(expr)' to a constant
bool Test7() { return Baz<-1>(); }

void some_generic_function(const void *arg, int argsize);
int *IntP, **IntPP;
C *ClassP, **ClassPP;

void GenericFunctionTest() {
// The `sizeof(pointer)` checks ignore situations where the pointer is
// produced by dereferencing a pointer-to-pointer, because this is unlikely
// to be an accident and can appear in legitimate code that tries to call
// a generic function which emulates dynamic typing within C.
some_generic_function(IntPP, sizeof(*IntPP));
some_generic_function(ClassPP, sizeof(*ClassPP));
// Using `...[0]` instead of the dereference operator is another common
// variant, which is also widespread in the idiomatic array-size calculation:
// `sizeof(array) / sizeof(array[0])`.
some_generic_function(IntPP, sizeof(IntPP[0]));
some_generic_function(ClassPP, sizeof(ClassPP[0]));
// FIXME: There is a third common pattern where the generic function is
// called with `&Variable` and `sizeof(Variable)`. Right now these are
// reported by the `sizeof(pointer)` checks, but this causes some false
// positives, so it would be good to create an exception for them.
// NOTE: `sizeof(IntP)` is only reported with `WarnOnSizeOfPointer=true`.
some_generic_function(&IntPP, sizeof(IntP));
some_generic_function(&ClassPP, sizeof(ClassP));
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
}

int ValidExpressions() {
int A[] = {1, 2, 3, 4};
static const char str[] = "hello";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC2' used; consider using a 'constexpr' variadic template function

// These are all examples of common macros that shouldn't have constexpr suggestions.
#define CONCAT_NAME(a, b) a##b

#define CONCAT_STR(a, b) #a #b

#define COMMA ,

#define NORETURN [[noreturn]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,38 @@ void foo(const StructWithFieldContainer &Src) {
B.push_back(Number);
}
}

namespace gh95596 {

void f(std::vector<int>& t) {
{
std::vector<int> gh95596_0;
// CHECK-FIXES: gh95596_0.reserve(10);
for (unsigned i = 0; i < 10; ++i)
gh95596_0.push_back(i);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
}
{
std::vector<int> gh95596_1;
// CHECK-FIXES: gh95596_1.reserve(10);
for (int i = 0U; i < 10; ++i)
gh95596_1.push_back(i);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
}
{
std::vector<int> gh95596_2;
// CHECK-FIXES: gh95596_2.reserve(10);
for (unsigned i = 0U; i < 10; ++i)
gh95596_2.push_back(i);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
}
{
std::vector<int> gh95596_3;
// CHECK-FIXES: gh95596_3.reserve(10U);
for (int i = 0; i < 10U; ++i)
gh95596_3.push_back(i);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
}
}

} // namespace gh95596
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,18 @@ void f8() {
int f9() { return M2(1); }

template <typename T>
T f10(const int x10) {
T f_unknown_target(const int x10) {
return std::move(x10);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable 'x10' of the trivially-copyable type 'const int' has no effect; remove std::move() [performance-move-const-arg]
// CHECK-FIXES: return x10;
}

void f11() {
f10<int>(1);
f10<double>(1);
f_unknown_target<int>(1);
f_unknown_target<double>(1);
}

A&& f_return_right_ref() {
static A a{};
return std::move(a);
}

class NoMoveSemantics {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ struct ExpensiveToCopyType {

template <typename T>
struct Container {
using reference = T&;
using const_reference = const T&;

bool empty() const;
const T& operator[](int) const;
const T& operator[](int);
Expand All @@ -42,8 +45,8 @@ struct Container {
void nonConstMethod();
bool constMethod() const;

const T& at(int) const;
T& at(int);
reference at(int) const;
const_reference at(int);

};

Expand Down Expand Up @@ -207,6 +210,28 @@ void PositiveOperatorCallConstValueParam(const Container<ExpensiveToCopyType> C)
VarCopyConstructed.constMethod();
}

void PositiveOperatorValueParam(Container<ExpensiveToCopyType> C) {
const auto AutoAssigned = C[42];
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
// CHECK-FIXES: const auto& AutoAssigned = C[42];
AutoAssigned.constMethod();

const auto AutoCopyConstructed(C[42]);
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
// CHECK-FIXES: const auto& AutoCopyConstructed(C[42]);
AutoCopyConstructed.constMethod();

const ExpensiveToCopyType VarAssigned = C.at(42);
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
// CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = C.at(42);
VarAssigned.constMethod();

const ExpensiveToCopyType VarCopyConstructed(C.at(42));
// CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
// CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(C.at(42));
VarCopyConstructed.constMethod();
}

void PositiveOperatorCallConstValueParamAlias(const ExpensiveToCopyContainerAlias C) {
const auto AutoAssigned = C[42];
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
Expand Down
48 changes: 43 additions & 5 deletions clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ template <int Indirections> void RunTest(StringRef Snippet) {
StringRef CommonCode = R"(
struct ConstTag{};
struct NonConstTag{};
struct Tag1{};
struct S {
void constMethod() const;
Expand All @@ -59,6 +60,13 @@ template <int Indirections> void RunTest(StringRef Snippet) {
void operator[](int);
void operator[](int) const;
int& at(int);
const int& at(int) const;
const int& at(Tag1);
int& weird_overload();
const double& weird_overload() const;
bool operator==(const S&) const;
int int_member;
Expand Down Expand Up @@ -161,9 +169,11 @@ TEST(ConstReferenceDeclRefExprsTest, ConstRefVar) {
useIntConstRef(/*const*/target.int_member);
useIntPtr(/*const*/target.ptr_member);
useIntConstPtr(&/*const*/target.int_member);
(void)/*const*/target.at(3);
const S& const_target_ref = /*const*/target;
const S* const_target_ptr = &/*const*/target;
(void)/*const*/target.at(3);
}
)");
}
Expand All @@ -187,7 +197,7 @@ TEST(ConstReferenceDeclRefExprsTest, ValueVar) {
/*const*/target.staticMethod();
target.nonConstMethod();
/*const*/target(ConstTag{});
target[42];
/*const*/target[42];
/*const*/target(ConstTag{});
target(NonConstTag{});
useRef(target);
Expand All @@ -211,6 +221,14 @@ TEST(ConstReferenceDeclRefExprsTest, ValueVar) {
const S& const_target_ref = /*const*/target;
const S* const_target_ptr = &/*const*/target;
S* target_ptr = &target;
(void)/*const*/target.at(3);
++target.at(3);
const int civ = /*const*/target.at(3);
const int& cir = /*const*/target.at(3);
int& ir = target.at(3);
target.at(Tag1{});
target.weird_overload();
}
)");
}
Expand All @@ -227,7 +245,7 @@ TEST(ConstReferenceDeclRefExprsTest, RefVar) {
/*const*/target.staticMethod();
target.nonConstMethod();
/*const*/target(ConstTag{});
target[42];
/*const*/target[42];
useConstRef((/*const*/target));
(/*const*/target).constMethod();
(void)(/*const*/target == /*const*/target);
Expand All @@ -249,6 +267,14 @@ TEST(ConstReferenceDeclRefExprsTest, RefVar) {
const S& const_target_ref = /*const*/target;
const S* const_target_ptr = &/*const*/target;
S* target_ptr = &target;
(void)/*const*/target.at(3);
++target.at(3);
const int civ = /*const*/target.at(3);
const int& cir = /*const*/target.at(3);
int& ir = target.at(3);
target.at(Tag1{});
target.weird_overload();
}
)");
}
Expand All @@ -266,8 +292,8 @@ TEST(ConstReferenceDeclRefExprsTest, PtrVar) {
/*const*/target->staticMethod();
target->nonConstMethod();
(*/*const*/target)(ConstTag{});
(*target)[42];
target->operator[](42);
(*/*const*/target)[42];
/*const*/target->operator[](42);
useConstRef((*/*const*/target));
(/*const*/target)->constMethod();
(void)(*/*const*/target == */*const*/target);
Expand All @@ -284,7 +310,15 @@ TEST(ConstReferenceDeclRefExprsTest, PtrVar) {
const S& const_target_ref = */*const*/target;
const S* const_target_ptr = /*const*/target;
S* target_ptr = target; // FIXME: we could chect const usage of `target_ptr`.
S* target_ptr = target; // FIXME: we could chect const usage of `target_ptr`
(void)/*const*/target->at(3);
++target->at(3);
const int civ = /*const*/target->at(3);
const int& cir = /*const*/target->at(3);
int& ir = target->at(3);
target->at(Tag1{});
target->weird_overload();
}
)");
}
Expand Down Expand Up @@ -319,6 +353,10 @@ TEST(ConstReferenceDeclRefExprsTest, ConstPtrVar) {
const S& const_target_ref = */*const*/target;
const S* const_target_ptr = /*const*/target;
(void)/*const*/target->at(3);
const int civ = /*const*/target->at(3);
const int& cir = /*const*/target->at(3);
}
)");
}
Expand Down
22 changes: 9 additions & 13 deletions clang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,9 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wno-long-long")
endif ()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nested-anon-types" )
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nested-anon-types" )
endif ()
endif ()

# Determine HOST_LINK_VERSION on Darwin.
Expand Down Expand Up @@ -848,23 +850,17 @@ if (CLANG_ENABLE_BOOTSTRAP)
set(CLANG_BOOTSTRAP_TARGETS check-llvm check-clang check-all)
endif()
foreach(target ${CLANG_BOOTSTRAP_TARGETS})
# Install targets have side effects, so we always want to execute them.
# "install" is reserved by CMake and can't be used as a step name for
# ExternalProject_Add_Step, so we can match against "^install-" instead of
# "^install" to get a tighter match. CMake's installation scripts already
# skip up-to-date files, so there's no behavior change if you install to the
# same destination multiple times.
if(target MATCHES "^install-")
set(step_always ON)
else()
set(step_always OFF)
endif()

ExternalProject_Add_Step(${NEXT_CLANG_STAGE} ${target}
COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target ${target}
COMMENT "Performing ${target} for '${NEXT_CLANG_STAGE}'"
DEPENDEES configure
ALWAYS ${step_always}
# We need to set ALWAYS to ON here, otherwise these targets won't be
# built on a second invocation of ninja. The targets have their own
# logic to determine if they should build or not so setting ALWAYS ON
# here does not mean the targets will always rebuild it just means that
# they will check their dependenices and see if they need to be built.
ALWAYS ON
EXCLUDE_FROM_MAIN ON
USES_TERMINAL 1
)
Expand Down
8 changes: 4 additions & 4 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ def name(self):

@classmethod
def from_id(cls, id):
if id >= len(cls._kinds) or cls._kinds[id] is None:
if id < 0 or id >= len(cls._kinds) or cls._kinds[id] is None:
raise ValueError("Unknown template argument kind %d" % id)
return cls._kinds[id]

Expand Down Expand Up @@ -1336,7 +1336,7 @@ def __repr__(self):
CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271)

# OpenMP teams distribute simd directive.
CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(272)
CursorKind.OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(272)

# OpenMP teams distribute parallel for simd directive.
CursorKind.OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(273)
Expand Down Expand Up @@ -2215,7 +2215,7 @@ def name(self):

@staticmethod
def from_id(id):
if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
if id < 0 or id >= len(StorageClass._kinds) or not StorageClass._kinds[id]:
raise ValueError("Unknown storage class %d" % id)
return StorageClass._kinds[id]

Expand Down Expand Up @@ -2395,7 +2395,7 @@ def __repr__(self):
TypeKind.OCLRESERVEID = TypeKind(160)

TypeKind.OBJCOBJECT = TypeKind(161)
TypeKind.OBJCCLASS = TypeKind(162)
TypeKind.OBJCTYPEPARAM = TypeKind(162)
TypeKind.ATTRIBUTED = TypeKind(163)

TypeKind.OCLINTELSUBGROUPAVCMCEPAYLOAD = TypeKind(164)
Expand Down
47 changes: 47 additions & 0 deletions clang/bindings/python/tests/cindex/test_enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import unittest

from clang.cindex import (
CursorKind,
TemplateArgumentKind,
ExceptionSpecificationKind,
AvailabilityKind,
AccessSpecifier,
TypeKind,
RefQualifierKind,
LinkageKind,
TLSKind,
StorageClass,
)


class TestCursorKind(unittest.TestCase):
enums = [
CursorKind,
TemplateArgumentKind,
ExceptionSpecificationKind,
AvailabilityKind,
AccessSpecifier,
TypeKind,
RefQualifierKind,
LinkageKind,
TLSKind,
StorageClass,
]

def test_from_id(self):
"""Check that kinds can be constructed from valid IDs"""
for enum in self.enums:
self.assertEqual(enum.from_id(2), enum._kinds[2])
with self.assertRaises(ValueError):
enum.from_id(len(enum._kinds))
with self.assertRaises(ValueError):
enum.from_id(-1)

def test_unique_kinds(self):
"""Check that no kind name has been used multiple times"""
for enum in self.enums:
for id in range(len(enum._kinds)):
try:
enum.from_id(id).name
except ValueError:
pass
40 changes: 35 additions & 5 deletions clang/cmake/caches/Fuchsia-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,14 @@ if(FUCHSIA_SDK)
set(LLVM_RUNTIME_MULTILIB_hwasan+noexcept_TARGETS "aarch64-unknown-fuchsia;riscv64-unknown-fuchsia" CACHE STRING "")
endif()

foreach(target armv6m-unknown-eabi)
foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m-unknown-eabi)
list(APPEND BUILTIN_TARGETS "${target}")
set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Generic CACHE STRING "")
set(BUILTINS_${target}_CMAKE_SYSTEM_PROCESSOR arm CACHE STRING "")
set(BUILTINS_${target}_CMAKE_SYSROOT "" CACHE STRING "")
set(BUILTINS_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
foreach(lang C;CXX;ASM)
set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "--target=${target} -mcpu=cortex-m0plus -mthumb" CACHE STRING "")
set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "--target=${target} -mthumb" CACHE STRING "")
endforeach()
foreach(type SHARED;MODULE;EXE)
set(BUILTINS_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")
Expand All @@ -321,16 +321,31 @@ foreach(target armv6m-unknown-eabi)
set(RUNTIMES_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE STRING "")
foreach(lang C;CXX;ASM)
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -mcpu=cortex-m0plus -mthumb" CACHE STRING "")
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -mthumb" CACHE STRING "")
endforeach()
foreach(type SHARED;MODULE;EXE)
set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")
endforeach()
set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "libc" CACHE STRING "")
set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "libc;libcxx" CACHE STRING "")
endforeach()

foreach(target riscv32-unknown-elf)
Expand Down Expand Up @@ -361,9 +376,24 @@ foreach(target riscv32-unknown-elf)
endforeach()
set(RUNTIMES_${target}_LLVM_LIBC_FULL_BUILD ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBC_ENABLE_USE_BY_CLANG ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_UNICODE OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_WIDE_CHARACTERS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "")
set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "libc" CACHE STRING "")
set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "libc;libcxx" CACHE STRING "")
endforeach()

set(LLVM_BUILTIN_TARGETS "${BUILTIN_TARGETS}" CACHE STRING "")
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 @@ -30,7 +30,7 @@ endfunction()
#
# cmake -D LLVM_RELEASE_ENABLE_PGO=ON -C Release.cmake
set(LLVM_RELEASE_ENABLE_LTO THIN CACHE STRING "")
set(LLVM_RELEASE_ENABLE_PGO OFF CACHE BOOL "")
set(LLVM_RELEASE_ENABLE_PGO ON CACHE BOOL "")
set(LLVM_RELEASE_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "")
set(LLVM_RELEASE_ENABLE_PROJECTS "clang;lld;lldb;clang-tools-extra;bolt;polly;mlir;flang" CACHE STRING "")
# Note we don't need to add install here, since it is one of the pre-defined
Expand Down
6 changes: 5 additions & 1 deletion clang/cmake/modules/AddClang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,12 @@ macro(add_clang_library name)
else()
set(LIBTYPE STATIC)
endif()
if(NOT XCODE)
if(NOT XCODE AND NOT MSVC_IDE)
# The Xcode generator doesn't handle object libraries correctly.
# The Visual Studio CMake generator does handle object libraries
# correctly, but it is preferable to list the libraries with their
# source files (instead of the object files and the source files in
# a separate target in the "Object Libraries" folder)
list(APPEND LIBTYPE OBJECT)
endif()
set_property(GLOBAL APPEND PROPERTY CLANG_STATIC_LIBS ${name})
Expand Down
37 changes: 34 additions & 3 deletions clang/docs/APINotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@ entries:

Name: MyFramework

:Classes, Protocols, Tags, Typedefs, Globals, Enumerators, Functions:
:Classes, Protocols, Tags, Typedefs, Globals, Enumerators, Functions, Namespaces:

Arrays of top-level declarations. Each entry in the array must have a
'Name' key with its Objective-C name. "Tags" refers to structs, enums, and
unions; "Enumerators" refers to enum cases.
'Name' key with its Objective-C or C++ name. "Tags" refers to structs,
C++ classes, enums, and unions; "Classes" refers to Objective-C classes;
"Enumerators" refers to enum cases.

::

Expand Down Expand Up @@ -157,6 +158,36 @@ declaration kind), all of which are optional:
- Class: NSBundle
SwiftName: Bundle

:SwiftImportAs:

For a class, possible values are ``owned`` (equivalent to
``SWIFT_SELF_CONTAINED``) or ``reference`` (equivalent to
``SWIFT_SHARED_REFERENCE``, also requires specifying ``SwiftReleaseOp`` and
``SwiftRetainOp``).

For a method, possible values are ``unsafe`` (equivalent
to ``SWIFT_RETURNS_INDEPENDENT_VALUE``) or ``computed_property`` (equivalent to
``SWIFT_COMPUTED_PROPERTY``).

::

Tags:
- Name: RefCountedStorage
SwiftImportAs: reference
SwiftReleaseOp: RCRelease
SwiftRetainOp: RCRetain

:SwiftCopyable:

Allows annotating a C++ class as non-copyable in Swift. Equivalent to
``SWIFT_NONCOPYABLE``, or to an explicit conformance ``: ~Copyable``.

::

Tags:
- Name: tzdb
SwiftCopyable: false

:Availability, AvailabilityMsg:

A value of "nonswift" is equivalent to ``NS_SWIFT_UNAVAILABLE``. A value of
Expand Down
4 changes: 2 additions & 2 deletions clang/docs/CommandGuide/clang.rst
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ number of cross compilers, or may only support a native target.

Specify the architecture to build for (all platforms).

.. option:: -mmacosx-version-min=<version>
.. option:: -mmacos-version-min=<version>

When building for macOS, specify the minimum version supported by your
application.
Expand Down Expand Up @@ -723,7 +723,7 @@ ENVIRONMENT

.. envvar:: MACOSX_DEPLOYMENT_TARGET

If :option:`-mmacosx-version-min` is unspecified, the default deployment
If :option:`-mmacos-version-min` is unspecified, the default deployment
target is read from this environment variable. This option only affects
Darwin targets.

Expand Down
4 changes: 2 additions & 2 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2063,7 +2063,7 @@ Objective-C @available
----------------------
It is possible to use the newest SDK but still build a program that can run on
older versions of macOS and iOS by passing ``-mmacosx-version-min=`` /
older versions of macOS and iOS by passing ``-mmacos-version-min=`` /
``-miphoneos-version-min=``.
Before LLVM 5.0, when calling a function that exists only in the OS that's
Expand All @@ -2084,7 +2084,7 @@ When a method that's introduced in the OS newer than the target OS is called, a
void my_fun(NSSomeClass* var) {
// If fancyNewMethod was added in e.g. macOS 10.12, but the code is
// built with -mmacosx-version-min=10.11, then this unconditional call
// built with -mmacos-version-min=10.11, then this unconditional call
// will emit a -Wunguarded-availability warning:
[var fancyNewMethod];
}
Expand Down
52 changes: 50 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ Clang Frontend Potentially Breaking Changes
- The ``hasTypeLoc`` AST matcher will no longer match a ``classTemplateSpecializationDecl``;
existing uses should switch to ``templateArgumentLoc`` or ``hasAnyTemplateArgumentLoc`` instead.

Clang Python Bindings Potentially Breaking Changes
--------------------------------------------------
- Renamed ``CursorKind`` variant 272 from ``OMP_TEAMS_DISTRIBUTE_DIRECTIVE``
to ``OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE``. The previous name was incorrect, it was a duplicate
of variant 271.
- Renamed ``TypeKind`` variant 162 from ``OBJCCLASS`` to ``OBJCTYPEPARAM``.
The previous name was incorrect, it was a duplicate of variant 28.

What's New in Clang |release|?
==============================
Some of the major new features and improvements to Clang are listed
Expand Down Expand Up @@ -199,6 +207,12 @@ C++20 Feature Support
to update the ``__cpp_concepts`` macro to `202002L`. This enables
``<expected>`` from libstdc++ to work correctly with Clang.

- User defined constructors are allowed for copy-list-initialization with CTAD.
The example code for deduction guides for std::map in
(`cppreference <https://en.cppreference.com/w/cpp/container/map/deduction_guides>`_)
will now work.
(#GH62925).

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

Expand Down Expand Up @@ -260,6 +274,9 @@ Resolutions to C++ Defect Reports
- Clang now requires a template argument list after a template keyword.
(`CWG96: Syntactic disambiguation using the template keyword <https://cplusplus.github.io/CWG/issues/96.html>`_).

- Clang now considers ``noexcept(typeid(expr))`` more carefully, instead of always assuming that ``std::bad_typeid`` can be thrown.
(`CWG2191: Incorrect result for noexcept(typeid(v)) <https://cplusplus.github.io/CWG/issues/2191.html>`_).

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

Expand Down Expand Up @@ -343,6 +360,9 @@ Non-comprehensive list of changes in this release
- Added ``__is_bitwise_cloneable`` which is used to check whether a type
can be safely copied by memcpy/memmove.

- ``#pragma GCC diagnostic warning "-Wfoo"`` can now downgrade ``-Werror=foo``
errors and certain default-to-error ``-W`` diagnostics to warnings.

New Compiler Flags
------------------
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
Expand Down Expand Up @@ -575,6 +595,21 @@ Improvements to Clang's time-trace
- Clang now specifies that using ``auto`` in a lambda parameter is a C++14 extension when
appropriate. (`#46059: <https://github.com/llvm/llvm-project/issues/46059>`_).

Improvements to Coverage Mapping
--------------------------------

- Macros defined in system headers are not expanded in coverage
mapping. Conditional expressions in system header macros are no
longer taken into account for branch coverage. They can be included
with ``-mllvm -system-headers-coverage``.
(`#78920: <https://github.com/llvm/llvm-project/issues/78920>`_)
- MC/DC Coverage has been improved.
(`#82448: <https://github.com/llvm/llvm-project/pull/82448>`_)

- The maximum number of conditions is no longer limited to 6. See
`this <SourceBasedCodeCoverage.html#mc-dc-instrumentation>` for
more details.

Bug Fixes in This Version
-------------------------
- Clang's ``-Wundefined-func-template`` no longer warns on pure virtual
Expand Down Expand Up @@ -846,6 +881,13 @@ Bug Fixes to C++ Support
- Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
- Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307),
(#GH88081), (#GH89496), (#GH90669) and (#GH91633).
- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)
- Fixed a failed assertion when attempting to convert an integer representing the difference
between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (#GH95366).
- Fix immediate escalation bugs in the presence of dependent call arguments. (#GH94935)
- Clang now diagnoses explicit specializations with storage class specifiers in all contexts.


Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -903,11 +945,13 @@ Arm and AArch64 Support
a feature modifier for -march and -mcpu as well as via target attributes
like ``target_version`` or ``target_clones``.
- Support has been added for the following processors (-mcpu identifiers in parenthesis):
* Arm Cortex-R52+ (cortex-r52plus).
* Arm Cortex-R82AE (cortex-r82ae).
* Arm Cortex-A78AE (cortex-a78ae).
* Arm Cortex-A520AE (cortex-a520ae).
* Arm Cortex-A720AE (cortex-a720ae).
* Arm Cortex-R82AE (cortex-r82ae).
* Arm Cortex-R52+ (cortex-r52plus).
* Arm Cortex-A725 (cortex-a725).
* Arm Cortex-X925 (cortex-x925).
* Arm Neoverse-N3 (neoverse-n3).
* Arm Neoverse-V3 (neoverse-v3).
* Arm Neoverse-V3AE (neoverse-v3ae).
Expand All @@ -918,6 +962,10 @@ Android Support
Windows Support
^^^^^^^^^^^^^^^

- The clang-cl ``/Ot`` compiler option ("optimize for speed", also implied by
``/O2``) now maps to clang's ``-O3`` optimizataztion level instead of ``-O2``.
Users who prefer the old behavior can use ``clang-cl /Ot /clang:-O2 ...``.

- Clang-cl now supports function targets with intrinsic headers. This allows
for runtime feature detection of intrinsics. Previously under clang-cl
``immintrin.h`` and similar intrinsic headers would only include the intrinsics
Expand Down
29 changes: 25 additions & 4 deletions clang/docs/SourceBasedCodeCoverage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -484,10 +484,31 @@ MC/DC Instrumentation
---------------------

When instrumenting for Modified Condition/Decision Coverage (MC/DC) using the
clang option ``-fcoverage-mcdc``, users are limited to at most **six** leaf-level
conditions in a boolean expression. A warning will be generated for boolean
expressions that contain more than six, and they will not be instrumented for
MC/DC.
clang option ``-fcoverage-mcdc``, there are two hard limits.

The maximum number of terms is limited to 32767, which is practical for
handwritten expressions. To be more restrictive in order to enforce coding rules,
use ``-Xclang -fmcdc-max-conditions=n``. Expressions with exceeded condition
counts ``n`` will generate warnings and will be excluded in the MC/DC coverage.

The number of test vectors (the maximum number of possible combinations of
expressions) is limited to 2,147,483,646. In this case, approximately
256MiB (==2GiB/8) is used to record test vectors.

To reduce memory usage, users can limit the maximum number of test vectors per
expression with ``-Xclang -fmcdc-max-test-vectors=m``.
If the number of test vectors resulting from the analysis of an expression
exceeds ``m``, a warning will be issued and the expression will be excluded
from the MC/DC coverage.

The number of test vectors ``m``, for ``n`` terms in an expression, can be
``m <= 2^n`` in the theoretical worst case, but is usually much smaller.
In simple cases, such as expressions consisting of a sequence of single
operators, ``m == n+1``. For example, ``(a && b && c && d && e && f && g)``
requires 8 test vectors.

Expressions such as ``((a0 && b0) || (a1 && b1) || ...)`` can cause the
number of test vectors to increase exponentially.

Also, if a boolean expression is embedded in the nest of another boolean
expression but separated by a non-logical operator, this is also not supported.
Expand Down
19 changes: 16 additions & 3 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ and ``#pragma clang diagnostic`` are synonyms for Clang. GCC will ignore

The pragma may control any warning that can be used from the command
line. Warnings may be set to ignored, warning, error, or fatal. The
following example code will tell Clang or GCC to ignore the -Wall
following example code will tell Clang or GCC to ignore the ``-Wall``
warnings:

.. code-block:: c
Expand Down Expand Up @@ -1186,6 +1186,15 @@ severity levels. They can be used to change severity of a particular diagnostic
for a region of source file. A notable difference from GCC is that diagnostic
not enabled via command line arguments can't be enabled this way yet.

Some diagnostics associated with a ``-W`` flag have the error severity by
default. They can be ignored or downgraded to warnings:

.. code-block:: cpp
// C only
#pragma GCC diagnostic warning "-Wimplicit-function-declaration"
int main(void) { puts(""); }
In addition to controlling warnings and errors generated by the compiler, it is
possible to generate custom warning and error messages through the following
pragmas:
Expand Down Expand Up @@ -3338,6 +3347,9 @@ below. If multiple flags are present, the last one is used.
By default, Clang does not emit type information for types that are defined
but not used in a program. To retain the debug info for these unused types,
the negation **-fno-eliminate-unused-debug-types** can be used.
This can be particulary useful on Windows, when using NATVIS files that
can reference const symbols that would otherwise be stripped, even in full
debug or standalone debug modes.

Controlling Macro Debug Info Generation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -4632,12 +4644,13 @@ Execute ``clang-cl /?`` to see a list of supported options:
/Ob0 Disable function inlining
/Ob1 Only inline functions which are (explicitly or implicitly) marked inline
/Ob2 Inline functions as deemed beneficial by the compiler
/Ob3 Same as /Ob2
/Od Disable optimization
/Og No effect
/Oi- Disable use of builtin functions
/Oi Enable use of builtin functions
/Os Optimize for size
/Ot Optimize for speed
/Os Optimize for size (like clang -Os)
/Ot Optimize for speed (like clang -O3)
/Ox Deprecated (same as /Og /Oi /Ot /Oy /Ob2); use /O2 instead
/Oy- Disable frame pointer omission (x86 only, default)
/Oy Enable frame pointer omission (x86 only)
Expand Down
15 changes: 0 additions & 15 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2452,21 +2452,6 @@ Check for pointer subtractions on two pointers pointing to different memory chun
int d = &y - &x; // warn
}
.. _alpha-core-SizeofPtr:
alpha.core.SizeofPtr (C)
""""""""""""""""""""""""
Warn about unintended use of ``sizeof()`` on pointer expressions.
.. code-block:: c
struct s {};
int test(struct s *p) {
return sizeof(p);
// warn: sizeof(ptr) can produce an unexpected result
}
.. _alpha-core-StackAddressAsyncEscape:
alpha.core.StackAddressAsyncEscape (C)
Expand Down
1 change: 1 addition & 0 deletions clang/docs/tools/clang-formatted-files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ clang/tools/libclang/CXCursor.h
clang/tools/scan-build-py/tests/functional/src/include/clean-one.h
clang/unittests/Analysis/CFGBuildResult.h
clang/unittests/Analysis/MacroExpansionContextTest.cpp
clang/unittests/Analysis/FlowSensitive/ASTOpsTest.cpp
clang/unittests/Analysis/FlowSensitive/CNFFormula.cpp
clang/unittests/Analysis/FlowSensitive/DataflowAnalysisContextTest.cpp
clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
Expand Down
12 changes: 9 additions & 3 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
#include "clang/Basic/RISCVVTypes.def"
#define WASM_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define AMDGPU_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
#include "clang/Basic/AMDGPUTypes.def"

// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
Expand Down Expand Up @@ -1771,6 +1773,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType DeducedType,
bool IsDependent) const;

private:
QualType getDeducedTemplateSpecializationTypeInternal(TemplateName Template,
QualType DeducedType,
bool IsDependent,
QualType Canon) const;

public:
/// Return the unique reference to the type for the specified TagDecl
/// (struct/union/class/enum) decl.
QualType getTagDeclType(const TagDecl *Decl) const;
Expand Down Expand Up @@ -3203,9 +3212,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// valid feature names.
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;

std::vector<std::string>
filterFunctionTargetVersionAttrs(const TargetVersionAttr *TV) const;

void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
const FunctionDecl *) const;
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/ASTUnresolvedSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ASTUnresolvedSet {
}

void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) {
Decls.push_back(DeclAccessPair::makeLazy(ID.get(), AS), C);
Decls.push_back(DeclAccessPair::makeLazy(ID.getRawValue(), AS), C);
}

/// Replaces the given declaration with the new one, once.
Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/AST/CommentCommands.td
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; }
// HeaderDoc command for template parameter documentation.
def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }

def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; }
def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; }
def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; }
def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; let NumArgs = 1; }
def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; let NumArgs = 1; }
def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; let NumArgs = 1;}

def Deprecated : BlockCommand<"deprecated"> {
let IsEmptyParagraphAllowed = 1;
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/CommentParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ class Parser {
ArrayRef<Comment::Argument>
parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);

/// Parse arguments for \throws command supported args are in form of class
/// or template.
ArrayRef<Comment::Argument>
parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);

BlockCommandComment *parseBlockCommand();
InlineCommandComment *parseInlineCommand();

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,9 @@ class alignas(8) Decl {
/// Whether this declaration comes from another module unit.
bool isInAnotherModuleUnit() const;

/// Whether this declaration comes from the same module unit being compiled.
bool isInCurrentModuleUnit() const;

/// Whether the definition of the declaration should be emitted in external
/// sources.
bool shouldEmitInExternalSource() const;
Expand Down
57 changes: 45 additions & 12 deletions clang/include/clang/AST/DeclID.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define LLVM_CLANG_AST_DECLID_H

#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/iterator.h"

#include <climits>
Expand Down Expand Up @@ -115,12 +116,8 @@ class DeclIDBase {
DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {}
explicit DeclIDBase(DeclID ID) : ID(ID) {}

explicit DeclIDBase(unsigned LocalID, unsigned ModuleFileIndex) {
ID = (DeclID)LocalID | ((DeclID)ModuleFileIndex << 32);
}

public:
DeclID get() const { return ID; }
DeclID getRawValue() const { return ID; }

explicit operator DeclID() const { return ID; }

Expand All @@ -134,12 +131,33 @@ class DeclIDBase {

unsigned getLocalDeclIndex() const;

// The DeclID may be compared with predefined decl ID.
friend bool operator==(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID == RHS;
}
friend bool operator!=(const DeclIDBase &LHS, const DeclID &RHS) {
return !operator==(LHS, RHS);
}
friend bool operator<(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID < RHS;
}
friend bool operator<=(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID <= RHS;
}
friend bool operator>(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID > RHS;
}
friend bool operator>=(const DeclIDBase &LHS, const DeclID &RHS) {
return LHS.ID >= RHS;
}

friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID == RHS.ID;
}
friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID != RHS.ID;
}

// We may sort the decl ID.
friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) {
return LHS.ID < RHS.ID;
Expand All @@ -158,16 +176,27 @@ class DeclIDBase {
DeclID ID;
};

class ASTWriter;
class ASTReader;
namespace serialization {
class ModuleFile;
} // namespace serialization

class LocalDeclID : public DeclIDBase {
using Base = DeclIDBase;

public:
LocalDeclID() : Base() {}
LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
explicit LocalDeclID(DeclID ID) : Base(ID) {}

explicit LocalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
: Base(LocalID, ModuleFileIndex) {}
// Every Decl ID is a local decl ID to the module being writing in ASTWriter.
friend class ASTWriter;
friend class GlobalDeclID;

public:
LocalDeclID() : Base() {}

static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF,
DeclID ID);

LocalDeclID &operator++() {
++ID;
Expand All @@ -188,8 +217,8 @@ class GlobalDeclID : public DeclIDBase {
GlobalDeclID() : Base() {}
explicit GlobalDeclID(DeclID ID) : Base(ID) {}

explicit GlobalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
: Base(LocalID, ModuleFileIndex) {}
explicit GlobalDeclID(unsigned ModuleFileIndex, unsigned LocalID)
: Base((DeclID)ModuleFileIndex << 32 | (DeclID)LocalID) {}

// For DeclIDIterator<GlobalDeclID> to be able to convert a GlobalDeclID
// to a LocalDeclID.
Expand Down Expand Up @@ -230,7 +259,11 @@ template <> struct DenseMapInfo<clang::GlobalDeclID> {
}

static unsigned getHashValue(const GlobalDeclID &Key) {
return DenseMapInfo<DeclID>::getHashValue(Key.get());
// Our default hash algorithm for 64 bits integer may not be very good.
// In GlobalDeclID's case, it is pretty common that the lower 32 bits can
// be same.
// FIXME: Remove this when we fix the underlying issue.
return llvm::hash_value(Key.getRawValue());
}

static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) {
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,10 @@ class CXXTypeidExpr : public Expr {
reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand);
return const_child_range(begin, begin + 1);
}

/// Whether this is of a form like "typeid(*ptr)" that can throw a
/// std::bad_typeid if a pointer is a null pointer ([expr.typeid]p2)
bool hasNullCheck() const;
};

/// A member reference to an MSPropertyDecl.
Expand Down
7 changes: 6 additions & 1 deletion clang/include/clang/AST/PrettyPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct PrintingPolicy {
PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true),
UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false),
CleanUglifiedParameters(false), EntireContentsOfLargeArray(true),
UseEnumerators(true) {}
UseEnumerators(true), UseHLSLTypes(LO.HLSL) {}

/// Adjust this printing policy for cases where it's known that we're
/// printing C++ code (for instance, if AST dumping reaches a C++-only
Expand Down Expand Up @@ -342,6 +342,11 @@ struct PrintingPolicy {
LLVM_PREFERRED_TYPE(bool)
unsigned UseEnumerators : 1;

/// Whether or not we're printing known HLSL code and should print HLSL
/// sugared types when possible.
LLVM_PREFERRED_TYPE(bool)
unsigned UseHLSLTypes : 1;

/// Callbacks to use to allow the behavior of printing to be customized.
const PrintingCallbacks *Callbacks = nullptr;
};
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/TemplateBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ class TemplateArgument {
bool IncludeType) const;

/// Debugging aid that dumps the template argument.
void dump(raw_ostream &Out) const;
void dump(raw_ostream &Out, const ASTContext &Context) const;

/// Debugging aid that dumps the template argument to standard error.
void dump() const;
Expand Down
6 changes: 4 additions & 2 deletions clang/include/clang/AST/TemplateName.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,15 @@ class TemplateName {
Qualified Qual = Qualified::AsWritten) const;

/// Debugging aid that dumps the template name.
void dump(raw_ostream &OS) const;
void dump(raw_ostream &OS, const ASTContext &Context) const;

/// Debugging aid that dumps the template name to standard
/// error.
void dump() const;

void Profile(llvm::FoldingSetNodeID &ID);
void Profile(llvm::FoldingSetNodeID &ID) {
ID.AddPointer(Storage.getOpaqueValue());
}

/// Retrieve the template name as a void pointer.
void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
Expand Down
14 changes: 7 additions & 7 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -3015,6 +3015,9 @@ class BuiltinType : public Type {
// WebAssembly reference types
#define WASM_TYPE(Name, Id, SingletonId) Id,
#include "clang/Basic/WebAssemblyReferenceTypes.def"
// AMDGPU types
#define AMDGPU_TYPE(Name, Id, SingletonId) Id,
#include "clang/Basic/AMDGPUTypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
Expand Down Expand Up @@ -6050,30 +6053,27 @@ class DeducedTemplateSpecializationType : public DeducedType,

DeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedAsType,
bool IsDeducedAsDependent)
bool IsDeducedAsDependent, QualType Canon)
: DeducedType(DeducedTemplateSpecialization, DeducedAsType,
toTypeDependence(Template.getDependence()) |
(IsDeducedAsDependent
? TypeDependence::DependentInstantiation
: TypeDependence::None),
DeducedAsType.isNull() ? QualType(this, 0)
: DeducedAsType.getCanonicalType()),
Canon),
Template(Template) {}

public:
/// Retrieve the name of the template that we are deducing.
TemplateName getTemplateName() const { return Template;}

void Profile(llvm::FoldingSetNodeID &ID) {
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getTemplateName(), getDeducedType(), isDependentType());
}

static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
QualType Deduced, bool IsDependent) {
Template.Profile(ID);
QualType CanonicalType =
Deduced.isNull() ? Deduced : Deduced.getCanonicalType();
ID.AddPointer(CanonicalType.getAsOpaquePtr());
Deduced.Profile(ID);
ID.AddBoolean(IsDependent || Template.isDependent());
}

Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,10 @@ let Class = BuiltinType in {
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/WebAssemblyReferenceTypes.def"

#define AMDGPU_TYPE(NAME, ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/AMDGPUTypes.def"

#define BUILTIN_TYPE(ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/AST/BuiltinTypes.def"
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,9 @@ class CapabilityExpr {

bool shouldIgnore() const { return sexpr() == nullptr; }

bool isInvalid() const { return sexpr() && isa<til::Undefined>(sexpr()); }
bool isInvalid() const { return isa_and_nonnull<til::Undefined>(sexpr()); }

bool isUniversal() const { return sexpr() && isa<til::Wildcard>(sexpr()); }
bool isUniversal() const { return isa_and_nonnull<til::Wildcard>(sexpr()); }
};

// Translate clang::Expr to til::SExpr.
Expand Down
21 changes: 21 additions & 0 deletions clang/include/clang/Basic/AMDGPUTypes.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- AMDGPUTypes.def - Metadata about AMDGPU types -----------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file defines various AMDGPU builtin types.
//
//===----------------------------------------------------------------------===//

#ifndef AMDGPU_OPAQUE_PTR_TYPE
#define AMDGPU_OPAQUE_PTR_TYPE(Name, MangledName, AS, Width, Align, Id, SingletonId) \
AMDGPU_TYPE(Name, Id, SingletonId)
#endif

AMDGPU_OPAQUE_PTR_TYPE("__amdgpu_buffer_rsrc_t", "__amdgpu_buffer_rsrc_t", 8, 128, 128, AMDGPUBufferRsrc, AMDGPUBufferRsrcTy)

#undef AMDGPU_TYPE
#undef AMDGPU_OPAQUE_PTR_TYPE
5 changes: 0 additions & 5 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1060,11 +1060,6 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
.Case("ShaderModel", "shadermodel")
.Default(Platform);
}
static llvm::StringRef getPrettyEnviromentName(llvm::Triple::EnvironmentType EnvironmentType) {
if (EnvironmentType >= llvm::Triple::Pixel && EnvironmentType <= llvm::Triple::Amplification)
return llvm::Triple::getEnvironmentTypeName(EnvironmentType);
return "";
}
static llvm::Triple::EnvironmentType getEnvironmentType(llvm::StringRef Environment) {
return llvm::StringSwitch<llvm::Triple::EnvironmentType>(Environment)
.Case("pixel", llvm::Triple::Pixel)
Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -482,11 +482,11 @@ def SqrtF16F128 : Builtin, F16F128MathTemplate {
let Prototype = "T(T)";
}

def TanF128 : Builtin {
let Spellings = ["__builtin_tanf128"];
def TanF16F128 : Builtin, F16F128MathTemplate {
let Spellings = ["__builtin_tan"];
let Attributes = [FunctionWithBuiltinPrefix, NoThrow,
ConstIgnoringErrnoAndExceptions];
let Prototype = "__float128(__float128)";
let Prototype = "T(T)";
}

def TanhF128 : Builtin {
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f32x4, "V4fV4fV4fV4f", "nc", "relaxed
TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f32x4, "V4fV4fV4fV4f", "nc", "relaxed-simd")
TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f64x2, "V2dV2dV2dV2d", "nc", "relaxed-simd")
TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f64x2, "V2dV2dV2dV2d", "nc", "relaxed-simd")
TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f16x8, "V8hV8hV8hV8h", "nc", "half-precision")
TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f16x8, "V8hV8hV8hV8h", "nc", "half-precision")

TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i8x16, "V16ScV16ScV16ScV16Sc", "nc", "relaxed-simd")
TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i16x8, "V8sV8sV8sV8s", "nc", "relaxed-simd")
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to
CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping
///< regions.
CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code coverage criteria.
VALUE_CODEGENOPT(MCDCMaxConds, 16, 32767) ///< MC/DC Maximum conditions.
VALUE_CODEGENOPT(MCDCMaxTVs, 32, 0x7FFFFFFE) ///< MC/DC Maximum test vectors.

/// If -fpcc-struct-return or -freg-struct-return is specified.
ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -809,4 +809,7 @@ def warn_android_unversioned_fallback : Warning<

def err_drv_triple_version_invalid : Error<
"version '%0' in target triple '%1' is invalid">;

def warn_missing_include_dirs : Warning<
"no such include directory: '%0'">, InGroup<MissingIncludeDirs>, DefaultIgnore;
}
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">;
def MissingBraces : DiagGroup<"missing-braces">;
def MissingDeclarations: DiagGroup<"missing-declarations">;
def : DiagGroup<"missing-format-attribute">;
def : DiagGroup<"missing-include-dirs">;
def MissingIncludeDirs : DiagGroup<"missing-include-dirs">;
def MissingNoreturn : DiagGroup<"missing-noreturn">;
def MultiChar : DiagGroup<"multichar">;
def : DiagGroup<"nested-externs">;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def err_unsupported_environment : Error<"environment '%0' is not supported: '%1'
def err_unsupported_os : Error<"os '%0' is not supported: '%1'">;
def err_cannot_read_input_list : Error<"could not read %0 input list '%1': %2">;
def err_invalid_label: Error<"label '%0' is reserved: use a different label name for -X<label>">;
def err_directory_scanning: Error<"could not read directory '%0': %1">;
def err_more_than_one_library: Error<"more than one framework/dynamic library found">;
} // end of command line category.

let CategoryName = "Verification" in {
Expand Down
13 changes: 7 additions & 6 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3200,9 +3200,8 @@ def err_attribute_bad_sve_vector_size : Error<
def err_attribute_arm_feature_sve_bits_unsupported : Error<
"%0 is only supported when '-msve-vector-bits=<bits>' is specified with a "
"value of 128, 256, 512, 1024 or 2048">;
def warn_attribute_arm_sm_incompat_builtin : Warning<
"builtin call has undefined behaviour when called from a %0 function">,
InGroup<DiagGroup<"undefined-arm-streaming">>;
def err_attribute_arm_sm_incompat_builtin : Error<
"builtin can only be called from a %0 function">;
def warn_attribute_arm_za_builtin_no_za_state : Warning<
"builtin call is not valid when calling from a function without active ZA state">,
InGroup<DiagGroup<"undefined-arm-za">>;
Expand Down Expand Up @@ -5361,9 +5360,6 @@ def err_not_class_template_specialization : Error<
"parameter}0">;
def ext_explicit_specialization_storage_class : ExtWarn<
"explicit specialization cannot have a storage class">;
def err_explicit_specialization_inconsistent_storage_class : Error<
"explicit specialization has extraneous, inconsistent storage class "
"'%select{none|extern|static|__private_extern__|auto|register}0'">;
def err_dependent_function_template_spec_no_match : Error<
"no candidate function template was found for dependent"
" %select{member|friend}0 function template specialization">;
Expand Down Expand Up @@ -9015,6 +9011,11 @@ def err_cuda_ovl_target : Error<
"cannot overload %select{__device__|__global__|__host__|__host__ __device__}2 function %3">;
def note_cuda_ovl_candidate_target_mismatch : Note<
"candidate template ignored: target attributes do not match">;
def warn_offload_incompatible_redeclare : Warning<
"target-attribute based function overloads are not supported by NVCC and will be treated as a function redeclaration:"
"new declaration is %select{__device__|__global__|__host__|__host__ __device__}0 function, "
"old declaration is %select{__device__|__global__|__host__|__host__ __device__}1 function">,
InGroup<DiagGroup<"nvcc-compat">>, DefaultIgnore;

def err_cuda_device_builtin_surftex_cls_template : Error<
"illegal device builtin %select{surface|texture}0 reference "
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ FEATURE(nullability, true)
FEATURE(nullability_on_arrays, true)
FEATURE(nullability_on_classes, true)
FEATURE(nullability_nullable_result, true)
FEATURE(numerical_stability_sanitizer, LangOpts.Sanitize.has(SanitizerKind::NumericalStability))
FEATURE(memory_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory |
SanitizerKind::KernelMemory))
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ LANGOPT(RenderScript , 1, 0, "RenderScript")

LANGOPT(HLSL, 1, 0, "HLSL")
ENUM_LANGOPT(HLSLVersion, HLSLLangStd, 16, HLSL_Unset, "HLSL Version")
LANGOPT(HLSLStrictAvailability, 1, 0,
"Strict availability diagnostic mode for HLSL built-in functions.")

LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device")
LANGOPT(CUDAAllowVariadicFunctions, 1, 0, "allowing variadic functions in CUDA device code")
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/Sanitizers.def
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ SANITIZER("fuzzer-no-link", FuzzerNoLink)
// ThreadSanitizer
SANITIZER("thread", Thread)

// Numerical stability sanitizer.
SANITIZER("numerical", NumericalStability)

// LeakSanitizer
SANITIZER("leak", Leak)

Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/SourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,11 @@ class SourceManager : public RefCountedBase<SourceManager> {
isInTheSameTranslationUnit(std::pair<FileID, unsigned> &LOffs,
std::pair<FileID, unsigned> &ROffs) const;

/// \param Loc a source location in a loaded AST (of a PCH/Module file).
/// \returns a FileID uniquely identifies the AST of a loaded
/// module/PCH where `Loc` is at.
FileID getUniqueLoadedASTFileID(SourceLocation Loc) const;

/// Determines whether the two decomposed source location is in the same TU.
bool isInTheSameTranslationUnitImpl(
const std::pair<FileID, unsigned> &LOffs,
Expand Down
1,550 changes: 781 additions & 769 deletions clang/include/clang/Basic/arm_sve.td

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clang/include/clang/Basic/arm_sve_sme_incl.td
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def IsStreamingCompatible : FlagType<0x4000000000>;
def IsReadZA : FlagType<0x8000000000>;
def IsWriteZA : FlagType<0x10000000000>;
def IsReductionQV : FlagType<0x20000000000>;
def IsStreamingOrSVE2p1 : FlagType<0x40000000000>; // Use for intrinsics that are common between sme/sme2 and sve2p1.
def VerifyRuntimeMode : FlagType<0x40000000000>; // Use for intrinsics that are common between SVE and SME.
def IsInZA : FlagType<0x80000000000>;
def IsOutZA : FlagType<0x100000000000>;
def IsInOutZA : FlagType<0x200000000000>;
Expand Down
36 changes: 29 additions & 7 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>,
DocName<"Target-dependent compilation options">,
Visibility<[ClangOption, CLOption]>;

def hlsl_Group : OptionGroup<"<HLSL group>">, Group<f_Group>,
DocName<"HLSL options">,
Visibility<[ClangOption]>;

// Feature groups - these take command line options that correspond directly to
// target specific features and can be translated directly from command line
// options.
Expand Down Expand Up @@ -1790,6 +1794,14 @@ defm mcdc_coverage : BoolFOption<"coverage-mcdc",
"Enable MC/DC criteria when generating code coverage">,
NegFlag<SetFalse, [], [ClangOption], "Disable MC/DC coverage criteria">,
BothFlags<[], [ClangOption, CLOption]>>;
def fmcdc_max_conditions_EQ : Joined<["-"], "fmcdc-max-conditions=">,
Group<f_Group>, Visibility<[CC1Option]>,
HelpText<"Maximum number of conditions in MC/DC coverage">,
MarshallingInfoInt<CodeGenOpts<"MCDCMaxConds">, "32767">;
def fmcdc_max_test_vectors_EQ : Joined<["-"], "fmcdc-max-test-vectors=">,
Group<f_Group>, Visibility<[CC1Option]>,
HelpText<"Maximum number of test vectors in MC/DC coverage">,
MarshallingInfoInt<CodeGenOpts<"MCDCMaxTVs">, "0x7FFFFFFE">;
def fprofile_generate : Flag<["-"], "fprofile-generate">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
Expand Down Expand Up @@ -2114,7 +2126,7 @@ def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>,
MarshallingInfoNegativeFlag<DiagnosticOpts<"ElideType">>;
def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>;
defm eliminate_unused_debug_types : OptOutCC1FFlag<"eliminate-unused-debug-types",
"Do not emit ", "Emit ", " debug info for defined but unused types">;
"Do not emit ", "Emit ", " debug info for defined but unused types", [ClangOption, CLOption]>;
def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Emit all declarations, even if unused">,
Expand Down Expand Up @@ -7028,6 +7040,12 @@ def as_secure_log_file : Separate<["-"], "as-secure-log-file">,

} // let Visibility = [CC1Option, CC1AsOption]

let Visibility = [CC1Option, FC1Option] in {
def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
HelpText<"Link and internalize needed symbols from the given bitcode file "
"before performing optimizations.">;
} // let Visibility = [CC1Option, FC1Option]

let Visibility = [CC1Option] in {

def llvm_verify_each : Flag<["-"], "llvm-verify-each">,
Expand Down Expand Up @@ -7130,9 +7148,6 @@ defm constructor_aliases : BoolMOption<"constructor-aliases",
" emitting complete constructors and destructors as aliases when possible">>;
def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
HelpText<"Link the given bitcode file before performing optimizations.">;
def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
HelpText<"Link and internalize needed symbols from the given bitcode file "
"before performing optimizations.">;
defm link_builtin_bitcode_postopt: BoolMOption<"link-builtin-bitcode-postopt",
CodeGenOpts<"LinkBitcodePostopt">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption], "Link builtin bitcodes after the "
Expand Down Expand Up @@ -7885,6 +7900,11 @@ def finclude_default_header : Flag<["-"], "finclude-default-header">,
def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">,
HelpText<"Add OpenCL builtin function declarations (experimental)">;

def fhlsl_strict_availability : Flag<["-"], "fhlsl-strict-availability">,
HelpText<"Enables strict availability diagnostic mode for HLSL built-in functions.">,
Group<hlsl_Group>,
MarshallingInfoFlag<LangOpts<"HLSLStrictAvailability">>;

def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">,
HelpText<"Preserve 3-component vector type">,
MarshallingInfoFlag<CodeGenOpts<"PreserveVec3Type">>,
Expand Down Expand Up @@ -8116,7 +8136,7 @@ def show_inst : Flag<["-"], "show-inst">,
def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
HelpText<"The string to embed in the Dwarf debug AT_producer record.">;

def defsym : Separate<["-"], "defsym">,
def defsym : Separate<["--"], "defsym">,
HelpText<"Define a value for a symbol">;

} // let Visibility = [CC1AsOption]
Expand Down Expand Up @@ -8262,6 +8282,8 @@ def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>,
HelpText<"Only inline functions explicitly or implicitly marked inline">;
def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>,
HelpText<"Inline functions as deemed beneficial by the compiler">;
def : CLFlag<"Ob3">, Alias<_SLASH_O>, AliasArgs<["b3"]>,
HelpText<"Same as /Ob2">;
def : CLFlag<"Od", [CLOption, DXCOption]>, Alias<_SLASH_O>, AliasArgs<["d"]>,
HelpText<"Disable optimization">;
def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>,
Expand All @@ -8271,9 +8293,9 @@ def : CLFlag<"Oi">, Alias<_SLASH_O>, AliasArgs<["i"]>,
def : CLFlag<"Oi-">, Alias<_SLASH_O>, AliasArgs<["i-"]>,
HelpText<"Disable use of builtin functions">;
def : CLFlag<"Os">, Alias<_SLASH_O>, AliasArgs<["s"]>,
HelpText<"Optimize for size">;
HelpText<"Optimize for size (like clang -Os)">;
def : CLFlag<"Ot">, Alias<_SLASH_O>, AliasArgs<["t"]>,
HelpText<"Optimize for speed">;
HelpText<"Optimize for speed (like clang -O3)">;
def : CLFlag<"Ox">, Alias<_SLASH_O>, AliasArgs<["x"]>,
HelpText<"Deprecated (like /Og /Oi /Ot /Oy /Ob2); use /O2">;
def : CLFlag<"Oy">, Alias<_SLASH_O>, AliasArgs<["y"]>,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/SanitizerArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ class SanitizerArgs {
bool needsCfiDiagRt() const;
bool needsStatsRt() const { return Stats; }
bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
bool needsNsanRt() const {
return Sanitizers.has(SanitizerKind::NumericalStability);
}

bool hasMemTag() const {
return hasMemtagHeap() || hasMemtagStack() || hasMemtagGlobals();
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ class ToolChain {

/// ComputeEffectiveClangTriple - Return the Clang triple to use for this
/// target, which may take into account the command line arguments. For
/// example, on Darwin the -mmacosx-version-min= command line argument (which
/// example, on Darwin the -mmacos-version-min= command line argument (which
/// sets the deployment target) determines the version in the triple passed to
/// Clang.
virtual std::string ComputeEffectiveClangTriple(
Expand Down
13 changes: 6 additions & 7 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -5387,10 +5387,11 @@ extern const char *DefaultFallbackStyle;
/// \returns FormatStyle as specified by ``StyleName``. If ``StyleName`` is
/// "file" and no file is found, returns ``FallbackStyle``. If no style could be
/// determined, returns an Error.
Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
StringRef FallbackStyle, StringRef Code = "",
llvm::vfs::FileSystem *FS = nullptr,
bool AllowUnknownOptions = false);
Expected<FormatStyle>
getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyle,
StringRef Code = "", llvm::vfs::FileSystem *FS = nullptr,
bool AllowUnknownOptions = false,
llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr);

// Guesses the language from the ``FileName`` and ``Code`` to be formatted.
// Defaults to FormatStyle::LK_Cpp.
Expand Down Expand Up @@ -5430,9 +5431,7 @@ bool isClangFormatOff(StringRef Comment);
} // end namespace format
} // end namespace clang

namespace std {
template <>
struct is_error_code_enum<clang::format::ParseError> : std::true_type {};
} // namespace std
struct std::is_error_code_enum<clang::format::ParseError> : std::true_type {};

#endif // LLVM_CLANG_FORMAT_FORMAT_H
2 changes: 1 addition & 1 deletion clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ class FrontendOptions {
std::string ProductName;

// Currently this is only used as part of the `-extract-api` action.
// A comma seperated list of files providing a list of APIs to
// A comma separated list of files providing a list of APIs to
// ignore when extracting documentation.
std::vector<std::string> ExtractAPIIgnoresFileList;

Expand Down
4 changes: 1 addition & 3 deletions clang/include/clang/Frontend/PrecompiledPreamble.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,7 @@ class BuildPreambleErrorCategory final : public std::error_category {
std::error_code make_error_code(BuildPreambleError Error);
} // namespace clang

namespace std {
template <>
struct is_error_code_enum<clang::BuildPreambleError> : std::true_type {};
} // namespace std
struct std::is_error_code_enum<clang::BuildPreambleError> : std::true_type {};

#endif
7 changes: 2 additions & 5 deletions clang/include/clang/Frontend/SerializedDiagnosticReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,8 @@ class SerializedDiagnosticReader {
} // namespace serialized_diags
} // namespace clang

namespace std {

template <>
struct is_error_code_enum<clang::serialized_diags::SDError> : std::true_type {};

} // namespace std
struct std::is_error_code_enum<clang::serialized_diags::SDError>
: std::true_type {};

#endif // LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICREADER_H
81 changes: 81 additions & 0 deletions clang/include/clang/InstallAPI/DirectoryScanner.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//===- InstallAPI/DirectoryScanner.h ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
/// The DirectoryScanner for collecting library files on the file system.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_INSTALLAPI_DIRECTORYSCANNER_H
#define LLVM_CLANG_INSTALLAPI_DIRECTORYSCANNER_H

#include "clang/Basic/FileManager.h"
#include "clang/InstallAPI/Library.h"

namespace clang::installapi {

enum ScanMode {
/// Scanning Framework directory.
ScanFrameworks,
/// Scanning Dylib directory.
ScanDylibs,
};

class DirectoryScanner {
public:
DirectoryScanner(FileManager &FM, ScanMode Mode = ScanMode::ScanFrameworks)
: FM(FM), Mode(Mode) {}

/// Scan for all input files throughout directory.
///
/// \param Directory Path of input directory.
llvm::Error scan(StringRef Directory);

/// Take over ownership of stored libraries.
std::vector<Library> takeLibraries() { return std::move(Libraries); };

/// Get all the header files in libraries.
///
/// \param Libraries Reference of collection of libraries.
static HeaderSeq getHeaders(ArrayRef<Library> Libraries);

private:
/// Collect files for dylibs in usr/(local)/lib within directory.
llvm::Error scanForUnwrappedLibraries(StringRef Directory);

/// Collect files for any frameworks within directory.
llvm::Error scanForFrameworks(StringRef Directory);

/// Get a library from the libraries collection.
Library &getOrCreateLibrary(StringRef Path, std::vector<Library> &Libs) const;

/// Collect multiple frameworks from directory.
llvm::Error scanMultipleFrameworks(StringRef Directory,
std::vector<Library> &Libs) const;
/// Collect files from nested frameworks.
llvm::Error scanSubFrameworksDirectory(StringRef Directory,
std::vector<Library> &Libs) const;

/// Collect files from framework path.
llvm::Error scanFrameworkDirectory(StringRef Path, Library &Framework) const;

/// Collect header files from path.
llvm::Error scanHeaders(StringRef Path, Library &Lib, HeaderType Type,
StringRef BasePath,
StringRef ParentPath = StringRef()) const;

/// Collect files from Version directories inside Framework directories.
llvm::Error scanFrameworkVersionsDirectory(StringRef Path,
Library &Lib) const;
FileManager &FM;
ScanMode Mode;
StringRef RootPath;
std::vector<Library> Libraries;
};

} // namespace clang::installapi

#endif // LLVM_CLANG_INSTALLAPI_DIRECTORYSCANNER_H
2 changes: 1 addition & 1 deletion clang/include/clang/InstallAPI/DylibVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class DylibVerifier : llvm::MachO::RecordVisitor {

// Check if an internal declaration in zippered library has an
// external declaration for a different platform. This results
// in the symbol being in a "seperate" platform slice.
// in the symbol being in a "separate" platform slice.
bool shouldIgnoreInternalZipperedSymbol(const Record *R,
const SymbolContext &SymCtx) const;

Expand Down
13 changes: 13 additions & 0 deletions clang/include/clang/InstallAPI/HeaderFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ class HeaderFile {
Other.Excluded, Other.Extra,
Other.Umbrella);
}

bool operator<(const HeaderFile &Other) const {
/// For parsing of headers based on ordering,
/// group by type, then whether its an umbrella.
/// Capture 'extra' headers last.
/// This optimizes the chance of a sucessful parse for
/// headers that violate IWYU.
if (isExtra() && Other.isExtra())
return std::tie(Type, Umbrella) < std::tie(Other.Type, Other.Umbrella);

return std::tie(Type, Umbrella, Extra, FullPath) <
std::tie(Other.Type, Other.Umbrella, Other.Extra, Other.FullPath);
}
};

/// Glob that represents a pattern of header files to retreive.
Expand Down
65 changes: 65 additions & 0 deletions clang/include/clang/InstallAPI/Library.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//===- InstallAPI/Library.h -------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
/// Defines the content of a library, such as public and private
/// header files, and whether it is a framework.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_INSTALLAPI_LIBRARY_H
#define LLVM_CLANG_INSTALLAPI_LIBRARY_H

#include "clang/InstallAPI/HeaderFile.h"
#include "clang/InstallAPI/MachO.h"

namespace clang::installapi {

class Library {
public:
Library(StringRef Directory) : BaseDirectory(Directory) {}

/// Capture the name of the framework by the install name.
///
/// \param InstallName The install name of the library encoded in a dynamic
/// library.
static StringRef getFrameworkNameFromInstallName(StringRef InstallName);

/// Get name of library by the discovered file path.
StringRef getName() const;

/// Get discovered path of library.
StringRef getPath() const { return BaseDirectory; }

/// Add a header file that belongs to the library.
///
/// \param FullPath Path to header file.
/// \param Type Access level of header.
/// \param IncludePath The way the header should be included.
void addHeaderFile(StringRef FullPath, HeaderType Type,
StringRef IncludePath = StringRef()) {
Headers.emplace_back(FullPath, Type, IncludePath);
}

/// Determine if library is empty.
bool empty() {
return SubFrameworks.empty() && Headers.empty() &&
FrameworkVersions.empty();
}

private:
std::string BaseDirectory;
HeaderSeq Headers;
std::vector<Library> SubFrameworks;
std::vector<Library> FrameworkVersions;
bool IsUnwrappedDylib{false};

friend class DirectoryScanner;
};

} // namespace clang::installapi

#endif // LLVM_CLANG_INSTALLAPI_LIBRARY_H
1 change: 1 addition & 0 deletions clang/include/clang/InstallAPI/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ using RecordLinkage = llvm::MachO::RecordLinkage;
using Record = llvm::MachO::Record;
using EncodeKind = llvm::MachO::EncodeKind;
using GlobalRecord = llvm::MachO::GlobalRecord;
using InterfaceFile = llvm::MachO::InterfaceFile;
using ObjCContainerRecord = llvm::MachO::ObjCContainerRecord;
using ObjCInterfaceRecord = llvm::MachO::ObjCInterfaceRecord;
using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord;
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Lex/HeaderSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ struct HeaderFileInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned isModuleHeader : 1;

/// Whether this header is a `textual header` in a module.
/// Whether this header is a `textual header` in a module. If a header is
/// textual in one module and normal in another module, this bit will not be
/// set, only `isModuleHeader`.
LLVM_PREFERRED_TYPE(bool)
unsigned isTextualModuleHeader : 1;

Expand Down
54 changes: 48 additions & 6 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ class Preprocessor {

MacroState &S = CurSubmoduleState->Macros[II];
auto *MD = S.getLatest();
while (MD && isa<VisibilityMacroDirective>(MD))
while (isa_and_nonnull<VisibilityMacroDirective>(MD))
MD = MD->getPrevious();
return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD),
S.getActiveModuleMacros(*this, II),
Expand Down Expand Up @@ -2883,11 +2883,41 @@ class Preprocessor {
/// otherwise.
SourceLocation CurrentSafeBufferOptOutStart; // It is used to report the start location of an never-closed region.

// An ordered sequence of "-Wunsafe-buffer-usage" opt-out regions in one
// translation unit. Each region is represented by a pair of start and end
// locations. A region is "open" if its' start and end locations are
// identical.
SmallVector<std::pair<SourceLocation, SourceLocation>, 8> SafeBufferOptOutMap;
using SafeBufferOptOutRegionsTy =
SmallVector<std::pair<SourceLocation, SourceLocation>, 16>;
// An ordered sequence of "-Wunsafe-buffer-usage" opt-out regions in this
// translation unit. Each region is represented by a pair of start and
// end locations.
SafeBufferOptOutRegionsTy SafeBufferOptOutMap;

// The "-Wunsafe-buffer-usage" opt-out regions in loaded ASTs. We use the
// following structure to manage them by their ASTs.
struct {
// A map from unique IDs to region maps of loaded ASTs. The ID identifies a
// loaded AST. See `SourceManager::getUniqueLoadedASTID`.
llvm::DenseMap<FileID, SafeBufferOptOutRegionsTy> LoadedRegions;

// Returns a reference to the safe buffer opt-out regions of the loaded
// AST where `Loc` belongs to. (Construct if absent)
SafeBufferOptOutRegionsTy &
findAndConsLoadedOptOutMap(SourceLocation Loc, SourceManager &SrcMgr) {
return LoadedRegions[SrcMgr.getUniqueLoadedASTFileID(Loc)];
}

// Returns a reference to the safe buffer opt-out regions of the loaded
// AST where `Loc` belongs to. (This const function returns nullptr if
// absent.)
const SafeBufferOptOutRegionsTy *
lookupLoadedOptOutMap(SourceLocation Loc,
const SourceManager &SrcMgr) const {
FileID FID = SrcMgr.getUniqueLoadedASTFileID(Loc);
auto Iter = LoadedRegions.find(FID);

if (Iter == LoadedRegions.end())
return nullptr;
return &Iter->getSecond();
}
} LoadedSafeBufferOptOutMap;

public:
/// \return true iff the given `Loc` is in a "-Wunsafe-buffer-usage" opt-out
Expand Down Expand Up @@ -2918,6 +2948,18 @@ class Preprocessor {
/// opt-out region
bool isPPInSafeBufferOptOutRegion(SourceLocation &StartLoc);

/// \return a sequence of SourceLocations representing ordered opt-out regions
/// specified by
/// `\#pragma clang unsafe_buffer_usage begin/end`s of this translation unit.
SmallVector<SourceLocation, 64> serializeSafeBufferOptOutMap() const;

/// \param SrcLocSeqs a sequence of SourceLocations deserialized from a
/// record of code `PP_UNSAFE_BUFFER_USAGE`.
/// \return true iff the `Preprocessor` has been updated; false `Preprocessor`
/// is same as itself before the call.
bool setDeserializedSafeBufferOptOutMap(
const SmallVectorImpl<SourceLocation> &SrcLocSeqs);

private:
/// Helper functions to forward lexing to the actual lexer. They all share the
/// same signature.
Expand Down
Loading