namespace Namespace

Namespaces

Records

Functions

@@ -196,14 +196,14 @@ TEST(HTMLGeneratorTest, emitRecordHTML) {

Records

Functions

diff --git a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp index 67217393444648..006fde08c5c4c8 100644 --- a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp +++ b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp @@ -47,14 +47,12 @@ TEST(MDGeneratorTest, emitNamespaceMD) { ## Namespaces -ChildNamespace - +* [ChildNamespace](../ChildNamespace/index.md) ## Records -ChildStruct - +* [ChildStruct](../ChildStruct.md) ## Functions @@ -106,7 +104,7 @@ TEST(MDGeneratorTest, emitRecordMD) { assert(!Err); std::string Expected = R"raw(# class r -*Defined at line 10 of test.cpp* +*Defined at test.cpp#10* Inherits from F, G @@ -171,7 +169,7 @@ TEST(MDGeneratorTest, emitFunctionMD) { *void f(int P)* -*Defined at line 10 of test.cpp* +*Defined at test.cpp#10* )raw"; @@ -202,7 +200,7 @@ TEST(MDGeneratorTest, emitEnumMD) { | X | -*Defined at line 10 of test.cpp* +*Defined at test.cpp#10* )raw"; @@ -331,7 +329,7 @@ TEST(MDGeneratorTest, emitCommentMD) { *void f(int I, int J)* -*Defined at line 10 of test.cpp* +*Defined at test.cpp#10* diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index dca7aa5c2cf783..f0faed7f0f8f76 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -2157,7 +2157,21 @@

Narrowing Matchers

Example 2: matches s1 = s2 (matcher = cxxOperatorCallExpr(isAssignmentOperator())) struct S { S& operator=(const S&); }; - void x() { S s1, s2; s1 = s2; }) + void x() { S s1, s2; s1 = s2; } + + + +Matcher<BinaryOperator>isComparisonOperator +
Matches comparison operators.
+
+Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
+  if (a == b)
+    a += b;
+
+Example 2: matches s1 < s2
+           (matcher = cxxOperatorCallExpr(isComparisonOperator()))
+  struct S { bool operator<(const S& other); };
+  void x(S s1, S s2) { bool b1 = s1 < s2; }
 
@@ -2616,7 +2630,21 @@

Narrowing Matchers

Example 2: matches s1 = s2 (matcher = cxxOperatorCallExpr(isAssignmentOperator())) struct S { S& operator=(const S&); }; - void x() { S s1, s2; s1 = s2; }) + void x() { S s1, s2; s1 = s2; } + + + +Matcher<CXXOperatorCallExpr>isComparisonOperator +
Matches comparison operators.
+
+Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
+  if (a == b)
+    a += b;
+
+Example 2: matches s1 < s2
+           (matcher = cxxOperatorCallExpr(isComparisonOperator()))
+  struct S { bool operator<(const S& other); };
+  void x(S s1, S s2) { bool b1 = s1 < s2; }
 
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index cea360d12e91ee..2bd68eec175ac3 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -118,6 +118,22 @@ class CXXOperatorCallExpr final : public CallExpr { } bool isAssignmentOp() const { return isAssignmentOp(getOperator()); } + static bool isComparisonOp(OverloadedOperatorKind Opc) { + switch (Opc) { + case OO_EqualEqual: + case OO_ExclaimEqual: + case OO_Greater: + case OO_GreaterEqual: + case OO_Less: + case OO_LessEqual: + case OO_Spaceship: + return true; + default: + return false; + } + } + bool isComparisonOp() const { return isComparisonOp(getOperator()); } + /// Is this written as an infix binary operator? bool isInfixBinaryOp() const; diff --git a/clang/include/clang/AST/GlobalDecl.h b/clang/include/clang/AST/GlobalDecl.h index 145e961a23a389..0945ebb56a489b 100644 --- a/clang/include/clang/AST/GlobalDecl.h +++ b/clang/include/clang/AST/GlobalDecl.h @@ -35,10 +35,18 @@ enum class DynamicInitKind : unsigned { /// GlobalDecl - represents a global declaration. This can either be a /// CXXConstructorDecl and the constructor type (Base, Complete). -/// a CXXDestructorDecl and the destructor type (Base, Complete) or +/// a CXXDestructorDecl and the destructor type (Base, Complete), +/// a FunctionDecl and the kernel reference type (Kernel, Stub), or /// a VarDecl, a FunctionDecl or a BlockDecl. +/// +/// When a new type of GlobalDecl is added, the following places should +/// be updated to convert a Decl* to a GlobalDecl: +/// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp. +/// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp +/// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp +/// class GlobalDecl { - llvm::PointerIntPair Value; + llvm::PointerIntPair Value; unsigned MultiVersionIndex = 0; void Init(const Decl *D) { @@ -55,6 +63,7 @@ class GlobalDecl { : MultiVersionIndex(MVIndex) { Init(D); } + GlobalDecl(const NamedDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } @@ -108,6 +117,8 @@ class GlobalDecl { void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } + explicit operator bool() const { return getAsOpaquePtr(); } + static GlobalDecl getFromOpaquePtr(void *P) { GlobalDecl GD; GD.Value.setFromOpaqueValue(P); diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h index 5db5c5b977da56..39e4f2335deb2b 100644 --- a/clang/include/clang/AST/Mangle.h +++ b/clang/include/clang/AST/Mangle.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_MANGLE_H #include "clang/AST/Decl.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" @@ -96,8 +97,8 @@ class MangleContext { virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0; // FIXME: consider replacing raw_ostream & with something like SmallString &. - void mangleName(const NamedDecl *D, raw_ostream &); - virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; + void mangleName(GlobalDecl GD, raw_ostream &); + virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) = 0; @@ -109,10 +110,6 @@ class MangleContext { raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; - virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - raw_ostream &) = 0; - virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - raw_ostream &) = 0; virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0; void mangleGlobalBlock(const BlockDecl *BD, diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index da7e23052b288a..31138e47750c57 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4783,7 +4783,7 @@ extern const internal::VariadicFunction< /// (matcher = cxxOperatorCallExpr(isAssignmentOperator())) /// \code /// struct S { S& operator=(const S&); }; -/// void x() { S s1, s2; s1 = s2; }) +/// void x() { S s1, s2; s1 = s2; } /// \endcode AST_POLYMORPHIC_MATCHER(isAssignmentOperator, AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, @@ -4791,6 +4791,26 @@ AST_POLYMORPHIC_MATCHER(isAssignmentOperator, return Node.isAssignmentOp(); } +/// Matches comparison operators. +/// +/// Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator())) +/// \code +/// if (a == b) +/// a += b; +/// \endcode +/// +/// Example 2: matches s1 < s2 +/// (matcher = cxxOperatorCallExpr(isComparisonOperator())) +/// \code +/// struct S { bool operator<(const S& other); }; +/// void x(S s1, S s2) { bool b1 = s1 < s2; } +/// \endcode +AST_POLYMORPHIC_MATCHER(isComparisonOperator, + AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, + CXXOperatorCallExpr)) { + return Node.isComparisonOp(); +} + /// Matches the left hand side of binary operator expressions. /// /// Example matches a (matcher = binaryOperator(hasLHS())) diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index 0574af395f7b1d..b544e3b42137bc 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -98,6 +98,19 @@ TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd1 TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_s_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_u_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_s_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_u_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_s_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_u_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_s_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_u_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_s_i32x4, "V4iV4iV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_u_i32x4, "V4iV4iV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_s_i32x4, "V4iV4iV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_u_i32x4, "V4iV4iV4i", "nc", "simd128") + TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16cV16cV16c", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8sV8sV8s", "nc", "simd128") diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 0a28edefa1e657..d435bebcdcf97d 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -164,10 +164,10 @@ class CodeGenOptions : public CodeGenOptionsBase { std::string FloatABI; /// The floating-point denormal mode to use. - llvm::DenormalMode FPDenormalMode; + llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::getIEEE(); - /// The floating-point subnormal mode to use, for float. - llvm::DenormalMode FP32DenormalMode; + /// The floating-point denormal mode to use, for float. + llvm::DenormalMode FP32DenormalMode = llvm::DenormalMode::getIEEE(); /// The float precision limit to use, if non-empty. std::string LimitFloatPrecision; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 6c79ea59173449..ae3f882dd91055 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -838,9 +838,13 @@ def IncompatibleExceptionSpec : DiagGroup<"incompatible-exception-spec">; def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">; def IntToPointerCast : DiagGroup<"int-to-pointer-cast", [IntToVoidPointerCast]>; -def VoidPointerToIntCast : DiagGroup<"void-pointer-to-int-cast">; +def VoidPointerToEnumCast : DiagGroup<"void-pointer-to-enum-cast">; +def VoidPointerToIntCast : DiagGroup<"void-pointer-to-int-cast", + [VoidPointerToEnumCast]>; +def PointerToEnumCast : DiagGroup<"pointer-to-enum-cast", + [VoidPointerToEnumCast]>; def PointerToIntCast : DiagGroup<"pointer-to-int-cast", - [VoidPointerToIntCast]>; + [PointerToEnumCast, VoidPointerToIntCast]>; def Move : DiagGroup<"move", [ PessimizingMove, diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e6155d5d0e1018..b0338c44cca96c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2424,20 +2424,19 @@ def note_for_range_invalid_iterator : Note < "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; -def warn_for_range_const_reference_copy : Warning< +def warn_for_range_const_ref_binds_temp_built_from_ref : Warning< "loop variable %0 " - "%diff{has type $ but is initialized with type $" - "|is initialized with a value of a different type}1,2 resulting in a copy">, + "%diff{of type $ binds to a temporary constructed from type $" + "|binds to a temporary constructed from a different type}1,2">, InGroup, DefaultIgnore; def note_use_type_or_non_reference : Note< - "use non-reference type %0 to keep the copy or type %1 to prevent copying">; -def warn_for_range_variable_always_copy : Warning< - "loop variable %0 is always a copy because the range of type %1 does not " - "return a reference">, + "use non-reference type %0 to make construction explicit or type %1 to prevent copying">; +def warn_for_range_ref_binds_ret_temp : Warning< + "loop variable %0 binds to a temporary value produced by a range of type %1">, InGroup, DefaultIgnore; def note_use_non_reference_type : Note<"use non-reference type %0">; def warn_for_range_copy : Warning< - "loop variable %0 of type %1 creates a copy from type %2">, + "loop variable %0 creates a copy from type %1">, InGroup, DefaultIgnore; def note_use_reference_type : Note<"use reference type %0 to prevent copying">; def err_objc_for_range_init_stmt : Error< @@ -3669,9 +3668,15 @@ def warn_int_to_void_pointer_cast : Warning< def warn_pointer_to_int_cast : Warning< "cast to smaller integer type %1 from %0">, InGroup; +def warn_pointer_to_enum_cast : Warning< + warn_pointer_to_int_cast.Text>, + InGroup; def warn_void_pointer_to_int_cast : Warning< "cast to smaller integer type %1 from %0">, InGroup; +def warn_void_pointer_to_enum_cast : Warning< + warn_void_pointer_to_int_cast.Text>, + InGroup; def ext_ms_pointer_to_int_cast : ExtWarn< "cast to smaller integer type %1 from %0 is a Microsoft extension">, InGroup; @@ -9634,7 +9639,7 @@ def err_omp_expected_var_name_member_expr : Error< def err_omp_expected_var_name_member_expr_or_array_item : Error< "expected variable name%select{|, data member of current class}0, array element or array section">; def err_omp_expected_addressable_lvalue_or_array_item : Error< - "expected addressable lvalue expression, array element or array section">; + "expected addressable lvalue expression, array element or array section%select{| of non 'omp_depend_t' type}0">; def err_omp_expected_named_var_member_or_array_expression: Error< "expected expression containing only member accesses and/or array sections based on named variables">; def err_omp_bit_fields_forbidden_in_clause : Error< diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 3cc7c384ac1066..53b87b73756894 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -230,7 +230,9 @@ LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code") LANGOPT(GPUAllowDeviceInit, 1, 0, "allowing device side global init functions for HIP") LANGOPT(GPUMaxThreadsPerBlock, 32, 256, "default max threads per block for kernel launch bounds for HIP") +LANGOPT(SYCL , 1, 0, "SYCL") LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device") +LANGOPT(SYCLVersion , 32, 0, "Version of the SYCL standard used") LANGOPT(HIPUseNewLaunchAPI, 1, 0, "Use new kernel launching API for HIP") diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index dbc0d1cec2c75b..70f962427e36c0 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -384,6 +384,7 @@ OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) OPENMP_DEPEND_KIND(inout) OPENMP_DEPEND_KIND(mutexinoutset) +OPENMP_DEPEND_KIND(depobj) OPENMP_DEPEND_KIND(source) OPENMP_DEPEND_KIND(sink) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2aaf85434214fa..0d5cba8d682aea 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3422,10 +3422,12 @@ defm underscoring : BooleanFFlag<"underscoring">, Group; defm whole_file : BooleanFFlag<"whole-file">, Group; // C++ SYCL options -def fsycl : Flag<["-"], "fsycl">, Group, +def fsycl : Flag<["-"], "fsycl">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Enable SYCL kernels compilation for device">; -def fno_sycl : Flag<["-"], "fno-sycl">, Group, +def fno_sycl : Flag<["-"], "fno-sycl">, Group, Flags<[CoreOption]>, HelpText<"Disable SYCL kernels compilation for device">; +def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group, Flags<[CC1Option, NoArgumentUnused, CoreOption]>, + HelpText<"SYCL language standard to compile for.">, Values<"2017, 121, 1.2.1, sycl-1.2.1">; include "CC1Options.td" diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 400ff9d86664bd..88ce205228fd9d 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -623,8 +623,7 @@ class ToolChain { const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType = nullptr) const { - // FIXME: This should be IEEE when default handling is fixed. - return llvm::DenormalMode::getInvalid(); + return llvm::DenormalMode::getIEEE(); } }; diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index f1a8b98e5efdcc..6944b0b5756e0c 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -908,7 +908,7 @@ class Sema; private: friend class OverloadCandidateSet; OverloadCandidate() - : IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {} + : IsSurrogate(false), IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {} }; /// OverloadCandidateSet - A set of overload candidates, used in C++ diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 79f9f42224d083..3377afccb5e6e5 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -650,12 +650,14 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { if (MC->shouldMangleDeclName(ND)) { SmallString<256> Buffer; llvm::raw_svector_ostream Out(Buffer); + GlobalDecl GD; if (const CXXConstructorDecl *CD = dyn_cast(ND)) - MC->mangleCXXCtor(CD, Ctor_Base, Out); + GD = GlobalDecl(CD, Ctor_Base); else if (const CXXDestructorDecl *DD = dyn_cast(ND)) - MC->mangleCXXDtor(DD, Dtor_Base, Out); + GD = GlobalDecl(DD, Dtor_Base); else - MC->mangleName(ND, Out); + GD = GlobalDecl(ND); + MC->mangleName(GD, Out); if (!Buffer.empty() && Buffer.front() == '\01') return std::string(Buffer.substr(1)); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 6d21869e2f1196..63e34653637ed9 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -135,7 +135,7 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext { bool shouldMangleStringLiteral(const StringLiteral *) override { return false; } - void mangleCXXName(const NamedDecl *D, raw_ostream &) override; + void mangleCXXName(GlobalDecl GD, raw_ostream &) override; void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) override; void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, @@ -150,10 +150,6 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext { void mangleCXXRTTI(QualType T, raw_ostream &) override; void mangleCXXRTTIName(QualType T, raw_ostream &) override; void mangleTypeName(QualType T, raw_ostream &) override; - void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - raw_ostream &) override; - void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - raw_ostream &) override; void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &) override; void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &) override; @@ -417,14 +413,14 @@ class CXXNameMangler { void disableDerivedAbiTags() { DisableDerivedAbiTags = true; } static bool shouldHaveAbiTags(ItaniumMangleContextImpl &C, const VarDecl *VD); - void mangle(const NamedDecl *D); + void mangle(GlobalDecl GD); void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); void mangleNumber(const llvm::APSInt &I); void mangleNumber(int64_t Number); void mangleFloat(const llvm::APFloat &F); - void mangleFunctionEncoding(const FunctionDecl *FD); + void mangleFunctionEncoding(GlobalDecl GD); void mangleSeqID(unsigned SeqID); - void mangleName(const NamedDecl *ND); + void mangleName(GlobalDecl GD); void mangleType(QualType T); void mangleNameOrStandardSubstitution(const NamedDecl *ND); void mangleLambdaSig(const CXXRecordDecl *Lambda); @@ -461,24 +457,24 @@ class CXXNameMangler { void mangleFunctionEncodingBareType(const FunctionDecl *FD); - void mangleNameWithAbiTags(const NamedDecl *ND, + void mangleNameWithAbiTags(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleModuleName(const Module *M); void mangleModuleNamePrefix(StringRef Name); void mangleTemplateName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND, + void mangleUnqualifiedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity, + mangleUnqualifiedName(GD, cast(GD.getDecl())->getDeclName(), UnknownArity, AdditionalAbiTags); } - void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, + void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name, unsigned KnownArity, const AbiTagList *AdditionalAbiTags); - void mangleUnscopedName(const NamedDecl *ND, + void mangleUnscopedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); - void mangleUnscopedTemplateName(const TemplateDecl *ND, + void mangleUnscopedTemplateName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleUnscopedTemplateName(TemplateName, const AbiTagList *AdditionalAbiTags); @@ -486,13 +482,13 @@ class CXXNameMangler { void mangleRegCallName(const IdentifierInfo *II); void mangleSourceNameWithAbiTags( const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr); - void mangleLocalName(const Decl *D, + void mangleLocalName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags); void mangleBlockForPrefix(const BlockDecl *Block); void mangleUnqualifiedBlock(const BlockDecl *Block); void mangleTemplateParamDecl(const NamedDecl *Decl); void mangleLambda(const CXXRecordDecl *Lambda); - void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, + void mangleNestedName(GlobalDecl GD, const DeclContext *DC, const AbiTagList *AdditionalAbiTags, bool NoFunction=false); void mangleNestedName(const TemplateDecl *TD, @@ -501,7 +497,7 @@ class CXXNameMangler { void manglePrefix(NestedNameSpecifier *qualifier); void manglePrefix(const DeclContext *DC, bool NoFunction=false); void manglePrefix(QualType type); - void mangleTemplatePrefix(const TemplateDecl *ND, bool NoFunction=false); + void mangleTemplatePrefix(GlobalDecl GD, bool NoFunction=false); void mangleTemplatePrefix(TemplateName Template); bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, StringRef Prefix = ""); @@ -640,34 +636,36 @@ void CXXNameMangler::mangleSourceNameWithAbiTags( writeAbiTags(ND, AdditionalAbiTags); } -void CXXNameMangler::mangle(const NamedDecl *D) { +void CXXNameMangler::mangle(GlobalDecl GD) { // ::= _Z // ::= // ::= Out << "_Z"; - if (const FunctionDecl *FD = dyn_cast(D)) - mangleFunctionEncoding(FD); - else if (const VarDecl *VD = dyn_cast(D)) + if (isa(GD.getDecl())) + mangleFunctionEncoding(GD); + else if (const VarDecl *VD = dyn_cast(GD.getDecl())) mangleName(VD); - else if (const IndirectFieldDecl *IFD = dyn_cast(D)) + else if (const IndirectFieldDecl *IFD = + dyn_cast(GD.getDecl())) mangleName(IFD->getAnonField()); else - mangleName(cast(D)); + mangleName(cast(GD.getDecl())); } -void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { +void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) { + const FunctionDecl *FD = cast(GD.getDecl()); // ::= // Don't mangle in the type if this isn't a decl we should typically mangle. if (!Context.shouldMangleDeclName(FD)) { - mangleName(FD); + mangleName(GD); return; } AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD); if (ReturnTypeAbiTags.empty()) { // There are no tags for return type, the simplest case. - mangleName(FD); + mangleName(GD); mangleFunctionEncodingBareType(FD); return; } @@ -787,13 +785,14 @@ static bool isStdNamespace(const DeclContext *DC) { return isStd(cast(DC)); } -static const TemplateDecl * -isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { +static const GlobalDecl +isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs) { + const NamedDecl *ND = cast(GD.getDecl()); // Check if we have a function template. if (const FunctionDecl *FD = dyn_cast(ND)) { if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { TemplateArgs = FD->getTemplateSpecializationArgs(); - return TD; + return GD.getWithDecl(TD); } } @@ -801,20 +800,21 @@ isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { if (const ClassTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } // Check if we have a variable template. if (const VarTemplateSpecializationDecl *Spec = dyn_cast(ND)) { TemplateArgs = &Spec->getTemplateArgs(); - return Spec->getSpecializedTemplate(); + return GD.getWithDecl(Spec->getSpecializedTemplate()); } - return nullptr; + return GlobalDecl(); } -void CXXNameMangler::mangleName(const NamedDecl *ND) { +void CXXNameMangler::mangleName(GlobalDecl GD) { + const NamedDecl *ND = cast(GD.getDecl()); if (const VarDecl *VD = dyn_cast(ND)) { // Variables should have implicit tags from its type. AbiTagList VariableTypeAbiTags = makeVariableTypeTags(VD); @@ -843,12 +843,13 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) { // Output name with implicit tags. mangleNameWithAbiTags(VD, &AdditionalAbiTags); } else { - mangleNameWithAbiTags(ND, nullptr); + mangleNameWithAbiTags(GD, nullptr); } } -void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, +void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast(GD.getDecl()); // ::= [] // ::= [] // ::= [] @@ -864,14 +865,14 @@ void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, while (!DC->isNamespace() && !DC->isTranslationUnit()) DC = getEffectiveParentContext(DC); else if (GetLocalClassDecl(ND)) { - mangleLocalName(ND, AdditionalAbiTags); + mangleLocalName(GD, AdditionalAbiTags); return; } DC = IgnoreLinkageSpecDecls(DC); if (isLocalContainerContext(DC)) { - mangleLocalName(ND, AdditionalAbiTags); + mangleLocalName(GD, AdditionalAbiTags); return; } @@ -886,17 +887,17 @@ void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, if (DC->isTranslationUnit() || isStdNamespace(DC)) { // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { mangleUnscopedTemplateName(TD, AdditionalAbiTags); mangleTemplateArgs(*TemplateArgs); return; } - mangleUnscopedName(ND, AdditionalAbiTags); + mangleUnscopedName(GD, AdditionalAbiTags); return; } - mangleNestedName(ND, DC, AdditionalAbiTags); + mangleNestedName(GD, DC, AdditionalAbiTags); } void CXXNameMangler::mangleModuleName(const Module *M) { @@ -947,19 +948,21 @@ void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD, } } -void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND, +void CXXNameMangler::mangleUnscopedName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast(GD.getDecl()); // ::= // ::= St # ::std:: if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND)))) Out << "St"; - mangleUnqualifiedName(ND, AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } void CXXNameMangler::mangleUnscopedTemplateName( - const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) { + GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const TemplateDecl *ND = cast(GD.getDecl()); // ::= // ::= if (mangleSubstitution(ND)) @@ -971,9 +974,9 @@ void CXXNameMangler::mangleUnscopedTemplateName( "template template param cannot have abi tags"); mangleTemplateParameter(TTP->getDepth(), TTP->getIndex()); } else if (isa(ND) || isa(ND)) { - mangleUnscopedName(ND, AdditionalAbiTags); + mangleUnscopedName(GD, AdditionalAbiTags); } else { - mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags); + mangleUnscopedName(GD.getWithDecl(ND->getTemplatedDecl()), AdditionalAbiTags); } addSubstitution(ND); @@ -1250,10 +1253,11 @@ void CXXNameMangler::mangleUnresolvedName( mangleTemplateArgs(TemplateArgs, NumTemplateArgs); } -void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, +void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name, unsigned KnownArity, const AbiTagList *AdditionalAbiTags) { + const NamedDecl *ND = cast_or_null(GD.getDecl()); unsigned Arity = KnownArity; // ::= // ::= @@ -1499,10 +1503,11 @@ void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) { Out << II->getLength() << II->getName(); } -void CXXNameMangler::mangleNestedName(const NamedDecl *ND, +void CXXNameMangler::mangleNestedName(GlobalDecl GD, const DeclContext *DC, const AbiTagList *AdditionalAbiTags, bool NoFunction) { + const NamedDecl *ND = cast(GD.getDecl()); // // ::= N [] [] E // ::= N [] [] @@ -1520,13 +1525,13 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND, // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) { mangleTemplatePrefix(TD, NoFunction); mangleTemplateArgs(*TemplateArgs); } else { manglePrefix(DC, NoFunction); - mangleUnqualifiedName(ND, AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } Out << 'E'; @@ -1544,8 +1549,24 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, Out << 'E'; } -void CXXNameMangler::mangleLocalName(const Decl *D, +static GlobalDecl getParentOfLocalEntity(const DeclContext *DC) { + GlobalDecl GD; + // The Itanium spec says: + // For entities in constructors and destructors, the mangling of the + // complete object constructor or destructor is used as the base function + // name, i.e. the C1 or D1 version. + if (auto *CD = dyn_cast(DC)) + GD = GlobalDecl(CD, Ctor_Complete); + else if (auto *DD = dyn_cast(DC)) + GD = GlobalDecl(DD, Dtor_Complete); + else + GD = GlobalDecl(cast(DC)); + return GD; +} + +void CXXNameMangler::mangleLocalName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags) { + const Decl *D = GD.getDecl(); // := Z E [] // := Z E s [] // := Z E d [ ] @@ -1565,7 +1586,7 @@ void CXXNameMangler::mangleLocalName(const Decl *D, else if (const BlockDecl *BD = dyn_cast(DC)) mangleBlockForPrefix(BD); else - mangleFunctionEncoding(cast(DC)); + mangleFunctionEncoding(getParentOfLocalEntity(DC)); // Implicit ABI tags (from namespace) are not available in the following // entity; reset to actually emitted tags, which are available. @@ -1608,7 +1629,7 @@ void CXXNameMangler::mangleLocalName(const Decl *D, mangleUnqualifiedBlock(BD); } else { const NamedDecl *ND = cast(D); - mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags, + mangleNestedName(GD, getEffectiveDeclContext(ND), AdditionalAbiTags, true /*NoFunction*/); } } else if (const BlockDecl *BD = dyn_cast(D)) { @@ -1629,7 +1650,7 @@ void CXXNameMangler::mangleLocalName(const Decl *D, assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); mangleUnqualifiedBlock(BD); } else { - mangleUnqualifiedName(cast(D), AdditionalAbiTags); + mangleUnqualifiedName(GD, AdditionalAbiTags); } if (const NamedDecl *ND = dyn_cast(RD ? RD : D)) { @@ -1840,7 +1861,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { // Check if we have a template. const TemplateArgumentList *TemplateArgs = nullptr; - if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { + if (GlobalDecl TD = isTemplate(ND, TemplateArgs)) { mangleTemplatePrefix(TD); mangleTemplateArgs(*TemplateArgs); } else { @@ -1863,7 +1884,7 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) { if (OverloadedTemplateStorage *Overloaded = Template.getAsOverloadedTemplate()) { - mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(), + mangleUnqualifiedName(GlobalDecl(), (*Overloaded->begin())->getDeclName(), UnknownArity, nullptr); return; } @@ -1875,8 +1896,9 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) { mangleUnscopedTemplateName(Template, /* AdditionalAbiTags */ nullptr); } -void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, +void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD, bool NoFunction) { + const TemplateDecl *ND = cast(GD.getDecl()); // ::=