aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/cmake/modules/CMakeLists.txt12
-rw-r--r--clang/docs/ReleaseNotes.rst4
-rw-r--r--clang/docs/analyzer/checkers.rst44
-rw-r--r--clang/include/clang/AST/ASTNodeTraverser.h2
-rw-r--r--clang/include/clang/AST/CanonicalType.h6
-rw-r--r--clang/include/clang/AST/DeclCXX.h2
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h2
-rw-r--r--clang/include/clang/AST/Type.h18
-rw-r--r--clang/include/clang/AST/TypeBase.h48
-rw-r--r--clang/include/clang/AST/TypeLoc.h12
-rw-r--r--clang/include/clang/AST/TypeProperties.td2
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchersInternal.h2
-rw-r--r--clang/include/clang/Basic/BuiltinsX86.td14
-rw-r--r--clang/include/clang/Basic/LangOptions.def1
-rw-r--r--clang/include/clang/Basic/LangOptions.h9
-rw-r--r--clang/include/clang/Basic/LangStandard.h7
-rw-r--r--clang/include/clang/Basic/LangStandards.def90
-rw-r--r--clang/include/clang/Driver/Options.td18
-rw-r--r--clang/include/clang/StaticAnalyzer/Checkers/Checkers.td5
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h4
-rw-r--r--clang/lib/AST/ASTContext.cpp34
-rw-r--r--clang/lib/AST/ASTDiagnostic.cpp10
-rw-r--r--clang/lib/AST/ASTImporter.cpp17
-rw-r--r--clang/lib/AST/ASTStructuralEquivalence.cpp13
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp2
-rw-r--r--clang/lib/AST/ByteCode/Interp.cpp3
-rw-r--r--clang/lib/AST/ByteCode/Interp.h6
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp35
-rw-r--r--clang/lib/AST/ByteCode/InterpState.h2
-rw-r--r--clang/lib/AST/ByteCode/Pointer.cpp2
-rw-r--r--clang/lib/AST/Decl.cpp19
-rw-r--r--clang/lib/AST/DeclCXX.cpp2
-rw-r--r--clang/lib/AST/DeclPrinter.cpp2
-rw-r--r--clang/lib/AST/DeclarationName.cpp6
-rw-r--r--clang/lib/AST/Expr.cpp4
-rw-r--r--clang/lib/AST/ExprConstant.cpp40
-rw-r--r--clang/lib/AST/InheritViz.cpp4
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp18
-rw-r--r--clang/lib/AST/JSONNodeDumper.cpp6
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp4
-rw-r--r--clang/lib/AST/ODRHash.cpp6
-rw-r--r--clang/lib/AST/ParentMapContext.cpp60
-rw-r--r--clang/lib/AST/QualTypeNames.cpp6
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp4
-rw-r--r--clang/lib/AST/TextNodeDumper.cpp6
-rw-r--r--clang/lib/AST/Type.cpp56
-rw-r--r--clang/lib/AST/TypeLoc.cpp3
-rw-r--r--clang/lib/AST/TypePrinter.cpp12
-rw-r--r--clang/lib/AST/VTableBuilder.cpp9
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp4
-rw-r--r--clang/lib/Basic/LangOptions.cpp44
-rw-r--r--clang/lib/Basic/LangStandards.cpp13
-rw-r--r--clang/lib/Basic/Targets/AVR.cpp30
-rw-r--r--clang/lib/Basic/Targets/DirectX.h5
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenBuilder.h8
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenClass.cpp5
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenDecl.cpp98
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExpr.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp12
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp58
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.h32
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp28
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp4
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypeCache.h3
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenTypes.cpp15
-rw-r--r--clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp14
-rw-r--r--clang/lib/CodeGen/ABIInfoImpl.cpp6
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp3
-rw-r--r--clang/lib/CodeGen/CGCall.cpp4
-rw-r--r--clang/lib/CodeGen/CGClass.cpp2
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp151
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp6
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp2
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.cpp4
-rw-r--r--clang/lib/CodeGen/CGNonTrivialStruct.cpp3
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenTBAA.cpp8
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp4
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp24
-rw-r--r--clang/lib/CodeGen/SwiftCallingConv.cpp7
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp2
-rw-r--r--clang/lib/CodeGen/Targets/AArch64.cpp2
-rw-r--r--clang/lib/CodeGen/Targets/ARC.cpp3
-rw-r--r--clang/lib/CodeGen/Targets/ARM.cpp2
-rw-r--r--clang/lib/CodeGen/Targets/Lanai.cpp3
-rw-r--r--clang/lib/CodeGen/Targets/LoongArch.cpp4
-rw-r--r--clang/lib/CodeGen/Targets/Mips.cpp4
-rw-r--r--clang/lib/CodeGen/Targets/RISCV.cpp4
-rw-r--r--clang/lib/CodeGen/Targets/X86.cpp14
-rw-r--r--clang/lib/CodeGen/Targets/XCore.cpp4
-rw-r--r--clang/lib/Driver/Job.cpp31
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp8
-rw-r--r--clang/lib/Driver/XRayArgs.cpp5
-rw-r--r--clang/lib/ExtractAPI/DeclarationFragments.cpp2
-rw-r--r--clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp2
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp136
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp4
-rw-r--r--clang/lib/Frontend/FrontendOptions.cpp17
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp39
-rw-r--r--clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp5
-rw-r--r--clang/lib/Headers/avx512cdintrin.h81
-rw-r--r--clang/lib/Headers/avx512vlcdintrin.h149
-rw-r--r--clang/lib/Index/IndexTypeSourceInfo.cpp2
-rw-r--r--clang/lib/Index/USRGeneration.cpp5
-rw-r--r--clang/lib/InstallAPI/HeaderFile.cpp2
-rw-r--r--clang/lib/InstallAPI/Visitor.cpp4
-rw-r--r--clang/lib/Interpreter/InterpreterValuePrinter.cpp4
-rw-r--r--clang/lib/Lex/PPDirectives.cpp113
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp10
-rw-r--r--clang/lib/Parse/Parser.cpp11
-rw-r--r--clang/lib/Sema/CheckExprLifetime.cpp16
-rw-r--r--clang/lib/Sema/SemaAvailability.cpp4
-rw-r--r--clang/lib/Sema/SemaBPF.cpp2
-rw-r--r--clang/lib/Sema/SemaCXXScopeSpec.cpp5
-rw-r--r--clang/lib/Sema/SemaCast.cpp6
-rw-r--r--clang/lib/Sema/SemaChecking.cpp9
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp2
-rw-r--r--clang/lib/Sema/SemaCoroutine.cpp7
-rw-r--r--clang/lib/Sema/SemaDecl.cpp27
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp18
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp9
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp6
-rw-r--r--clang/lib/Sema/SemaExpr.cpp18
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp5
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp3
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp4
-rw-r--r--clang/lib/Sema/SemaInit.cpp11
-rw-r--r--clang/lib/Sema/SemaLookup.cpp11
-rw-r--r--clang/lib/Sema/SemaObjC.cpp4
-rw-r--r--clang/lib/Sema/SemaOverload.cpp12
-rw-r--r--clang/lib/Sema/SemaSYCL.cpp4
-rw-r--r--clang/lib/Sema/SemaStmt.cpp12
-rw-r--r--clang/lib/Sema/SemaStmtAsm.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp30
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp8
-rw-r--r--clang/lib/Sema/SemaTemplateDeductionGuide.cpp7
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp4
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp6
-rw-r--r--clang/lib/Sema/SemaType.cpp8
-rw-r--r--clang/lib/Sema/SemaTypeTraits.cpp13
-rw-r--r--clang/lib/Sema/TreeTransform.h4
-rw-r--r--clang/lib/Serialization/ASTReader.cpp8
-rw-r--r--clang/lib/Serialization/TemplateArgumentHasher.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp28
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp143
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp8
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp39
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp14
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp7
-rw-r--r--clang/lib/StaticAnalyzer/Core/RegionStore.cpp2
-rw-r--r--clang/test/AST/ByteCode/cxx11.cpp8
-rw-r--r--clang/test/AST/ByteCode/typeid.cpp10
-rw-r--r--clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm12
-rw-r--r--clang/test/Analysis/Checkers/WebKit/mock-types.h96
-rw-r--r--clang/test/Analysis/Checkers/WebKit/objc-mock-types.h10
-rw-r--r--clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm18
-rw-r--r--clang/test/Analysis/analyzer-enabled-checkers.c1
-rw-r--r--clang/test/Analysis/null-pointer-arithm.c76
-rw-r--r--clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c1
-rw-r--r--clang/test/C/C2y/n3364.c22
-rw-r--r--clang/test/CIR/CodeGen/throws.cpp21
-rw-r--r--clang/test/CIR/CodeGen/vla.c285
-rw-r--r--clang/test/CXX/module/module.import/p6.cpp13
-rw-r--r--clang/test/CodeGen/X86/avx512cd-builtins.c28
-rw-r--r--clang/test/CodeGen/X86/avx512vlcd-builtins.c55
-rw-r--r--clang/test/CodeGen/unified-lto-module-flag.ll11
-rw-r--r--clang/test/CodeGenCXX/sizeof-unwind-exception.cpp8
-rw-r--r--clang/test/CodeGenHLSL/basic-target.c2
-rw-r--r--clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl17
-rw-r--r--clang/test/DebugInfo/CXX/versioned-language.cpp23
-rw-r--r--clang/test/DebugInfo/Generic/versioned-language.c17
-rw-r--r--clang/test/DebugInfo/ObjC/versioned-language.m9
-rw-r--r--clang/test/DebugInfo/ObjCXX/versioned-language.mm9
-rw-r--r--clang/test/Driver/gpu-libc-headers.c14
-rw-r--r--clang/test/Driver/gpu-libc.c32
-rw-r--r--clang/test/Parser/DelayedTemplateParsing.cpp13
-rw-r--r--clang/test/Preprocessor/embed___has_embed_parsing_errors.c32
-rw-r--r--clang/tools/driver/cc1as_main.cpp11
-rw-r--r--clang/tools/libclang/CIndex.cpp6
-rw-r--r--clang/tools/libclang/CIndexCodeCompletion.cpp4
-rw-r--r--clang/tools/libclang/CXCursor.cpp2
-rw-r--r--clang/tools/libclang/CXIndexDataConsumer.cpp2
-rw-r--r--clang/tools/libclang/CXType.cpp8
-rw-r--r--clang/unittests/AST/ASTContextParentMapTest.cpp3
-rw-r--r--clang/unittests/AST/ASTImporterTest.cpp4
-rw-r--r--clang/unittests/AST/StructuralEquivalenceTest.cpp12
-rw-r--r--clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp1004
-rw-r--r--clang/unittests/Basic/CMakeLists.txt1
-rw-r--r--clang/unittests/Basic/LangOptionsTest.cpp56
-rw-r--r--clang/unittests/Format/FormatTest.cpp68
-rw-r--r--clang/unittests/StaticAnalyzer/SValTest.cpp8
-rw-r--r--clang/unittests/Tooling/LookupTest.cpp12
-rw-r--r--clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp2
-rw-r--r--clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp2
202 files changed, 3403 insertions, 1170 deletions
diff --git a/clang/cmake/modules/CMakeLists.txt b/clang/cmake/modules/CMakeLists.txt
index d2d6812..9ad2f98 100644
--- a/clang/cmake/modules/CMakeLists.txt
+++ b/clang/cmake/modules/CMakeLists.txt
@@ -8,15 +8,19 @@ include(FindPrefixFromConfig)
# the usual CMake convention seems to be ${Project}Targets.cmake.
set(CLANG_INSTALL_PACKAGE_DIR "${CMAKE_INSTALL_PACKAGEDIR}/clang" CACHE STRING
"Path for CMake subdirectory for Clang (defaults to '${CMAKE_INSTALL_PACKAGEDIR}/clang')")
-# CMAKE_INSTALL_PACKAGEDIR might be absolute, so don't reuse below.
-set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/clang")
# Keep this in sync with llvm/cmake/CMakeLists.txt!
set(LLVM_INSTALL_PACKAGE_DIR "${CMAKE_INSTALL_PACKAGEDIR}/llvm" CACHE STRING
"Path for CMake subdirectory for LLVM (defaults to '${CMAKE_INSTALL_PACKAGEDIR}/llvm')")
# CMAKE_INSTALL_PACKAGEDIR might be absolute, so don't reuse below.
-string(REPLACE "${CMAKE_CFG_INTDIR}" "." llvm_cmake_builddir "${LLVM_LIBRARY_DIR}")
-set(llvm_cmake_builddir "${llvm_cmake_builddir}/cmake/llvm")
+string(REPLACE "${CMAKE_CFG_INTDIR}" "." llvm_builddir "${LLVM_LIBRARY_DIR}")
+set(llvm_cmake_builddir "${llvm_builddir}/cmake/llvm")
+if(CLANG_BUILT_STANDALONE)
+ # CMAKE_INSTALL_PACKAGEDIR might be absolute, so don't reuse below.
+ set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/clang")
+else()
+ set(clang_cmake_builddir "${llvm_builddir}/cmake/clang")
+endif()
get_property(CLANG_EXPORTS GLOBAL PROPERTY CLANG_EXPORTS)
export(TARGETS ${CLANG_EXPORTS} FILE ${clang_cmake_builddir}/ClangTargets.cmake)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dea6f22..afe3d46 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -413,6 +413,7 @@ Bug Fixes in This Version
(#GH159080)
- Fixed a failed assertion with empty filename arguments in ``__has_embed``. (#GH159898)
- Fixed a failed assertion with empty filename in ``#embed`` directive. (#GH162951)
+- Fixed a crash triggered by unterminated ``__has_embed``. (#GH162953)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -426,7 +427,8 @@ Bug Fixes to Attribute Support
(#GH141504) and on types returned from indirect calls (#GH142453).
- Fixes some late parsed attributes, when applied to function definitions, not being parsed
in function try blocks, and some situations where parsing of the function body
- is skipped, such as error recovery and code completion. (#GH153551)
+ is skipped, such as error recovery, code completion, and msvc-compatible delayed
+ template parsing. (#GH153551)
- Using ``[[gnu::cleanup(some_func)]]`` where some_func is annotated with
``[[gnu::error("some error")]]`` now correctly triggers an error. (#GH146520)
- Fix a crash when the function name is empty in the `swift_name` attribute. (#GH157075)
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index d942578..dcfa4e3 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -205,6 +205,50 @@ pointers with a specified address space. If the option is set to false, then
reports from the specific x86 address spaces 256, 257 and 258 are still
suppressed, but null dereferences from other address spaces are reported.
+.. _core-NullPointerArithm:
+
+core.NullPointerArithm (C, C++)
+"""""""""""""""""""""""""""""""
+Check for undefined arithmetic operations with null pointers.
+
+The checker can detect the following cases:
+
+ - ``p + x`` and ``x + p`` where ``p`` is a null pointer and ``x`` is a nonzero
+ integer value.
+ - ``p - x`` where ``p`` is a null pointer and ``x`` is a nonzero integer
+ value.
+ - ``p1 - p2`` where one of ``p1`` and ``p2`` is null and the other a
+ non-null pointer.
+
+Result of these operations is undefined according to the standard.
+In the above listed cases, the checker will warn even if the expression
+described to be "nonzero" or "non-null" has unknown value, because it is likely
+that it can have non-zero value during the program execution.
+
+.. code-block:: c
+
+ void test1(int *p, int offset) {
+ if (p)
+ return;
+
+ int *p1 = p + offset; // warn: 'p' is null, 'offset' is unknown but likely non-zero
+ }
+
+ void test2(int *p, int offset) {
+ if (p) { } // this indicates that it is possible for 'p' to be null
+ if (offset == 0)
+ return;
+
+ int *p1 = p - offset; // warn: 'p' is null, 'offset' is known to be non-zero
+ }
+
+ void test3(char *p1, char *p2) {
+ if (p1)
+ return;
+
+ int a = p1 - p2; // warn: 'p1' is null, 'p2' can be likely non-null
+ }
+
.. _core-StackAddressEscape:
core.StackAddressEscape (C)
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index 0921604..e74bb72 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -770,7 +770,7 @@ public:
// it will not be in the parent context:
if (auto *TT = D->getFriendType()->getType()->getAs<TagType>())
if (TT->isTagOwned())
- Visit(TT->getOriginalDecl());
+ Visit(TT->getDecl());
} else {
Visit(D->getFriendDecl());
}
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index b5a4e94e13..87bbd7b 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -551,18 +551,18 @@ struct CanProxyAdaptor<UnaryTransformType>
template<>
struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getOriginalDecl)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
};
template<>
struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getOriginalDecl)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
};
template<>
struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getOriginalDecl)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
};
template<>
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 898487b..dfa3bef 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3832,7 +3832,7 @@ public:
public:
EnumDecl *getEnumDecl() const {
- return EnumType->getType()->castAs<clang::EnumType>()->getOriginalDecl();
+ return EnumType->getType()->castAs<clang::EnumType>()->getDecl();
}
static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index c246c4a..32b2b6b 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1710,7 +1710,7 @@ DEF_TRAVERSE_DECL(FriendDecl, {
// it will not be in the parent context:
if (auto *TT = D->getFriendType()->getType()->getAs<TagType>();
TT && TT->isTagOwned())
- TRY_TO(TraverseDecl(TT->getOriginalDecl()));
+ TRY_TO(TraverseDecl(TT->getDecl()));
} else {
TRY_TO(TraverseDecl(D->getFriendDecl()));
}
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index df106d5..7bd2441 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -27,7 +27,7 @@ inline CXXRecordDecl *Type::getAsCXXRecordDecl() const {
const auto *TT = dyn_cast<TagType>(CanonicalType);
if (!isa_and_present<RecordType, InjectedClassNameType>(TT))
return nullptr;
- auto *TD = TT->getOriginalDecl();
+ auto *TD = TT->getDecl();
if (isa<RecordType>(TT) && !isa<CXXRecordDecl>(TD))
return nullptr;
return cast<CXXRecordDecl>(TD)->getDefinitionOrSelf();
@@ -35,41 +35,39 @@ inline CXXRecordDecl *Type::getAsCXXRecordDecl() const {
inline CXXRecordDecl *Type::castAsCXXRecordDecl() const {
const auto *TT = cast<TagType>(CanonicalType);
- return cast<CXXRecordDecl>(TT->getOriginalDecl())->getDefinitionOrSelf();
+ return cast<CXXRecordDecl>(TT->getDecl())->getDefinitionOrSelf();
}
inline RecordDecl *Type::getAsRecordDecl() const {
const auto *TT = dyn_cast<TagType>(CanonicalType);
if (!isa_and_present<RecordType, InjectedClassNameType>(TT))
return nullptr;
- return cast<RecordDecl>(TT->getOriginalDecl())->getDefinitionOrSelf();
+ return cast<RecordDecl>(TT->getDecl())->getDefinitionOrSelf();
}
inline RecordDecl *Type::castAsRecordDecl() const {
const auto *TT = cast<TagType>(CanonicalType);
- return cast<RecordDecl>(TT->getOriginalDecl())->getDefinitionOrSelf();
+ return cast<RecordDecl>(TT->getDecl())->getDefinitionOrSelf();
}
inline EnumDecl *Type::getAsEnumDecl() const {
if (const auto *TT = dyn_cast<EnumType>(CanonicalType))
- return TT->getOriginalDecl()->getDefinitionOrSelf();
+ return TT->getDecl()->getDefinitionOrSelf();
return nullptr;
}
inline EnumDecl *Type::castAsEnumDecl() const {
- return cast<EnumType>(CanonicalType)
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
+ return cast<EnumType>(CanonicalType)->getDecl()->getDefinitionOrSelf();
}
inline TagDecl *Type::getAsTagDecl() const {
if (const auto *TT = dyn_cast<TagType>(CanonicalType))
- return TT->getOriginalDecl()->getDefinitionOrSelf();
+ return TT->getDecl()->getDefinitionOrSelf();
return nullptr;
}
inline TagDecl *Type::castAsTagDecl() const {
- return cast<TagType>(CanonicalType)->getOriginalDecl()->getDefinitionOrSelf();
+ return cast<TagType>(CanonicalType)->getDecl()->getDefinitionOrSelf();
}
inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const {
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index 625cc77..5892566 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -6419,10 +6419,10 @@ protected:
bool IsInjected, const Type *CanonicalType);
public:
- // FIXME: Temporarily renamed from `getDecl` in order to facilitate
- // rebasing, due to change in behaviour. This should be renamed back
- // to `getDecl` once the change is settled.
- TagDecl *getOriginalDecl() const { return decl; }
+ TagDecl *getDecl() const { return decl; }
+ [[deprecated("Use getDecl instead")]] TagDecl *getOriginalDecl() const {
+ return decl;
+ }
NestedNameSpecifier getQualifier() const;
@@ -6463,7 +6463,7 @@ struct TagTypeFoldingSetPlaceholder : public llvm::FoldingSetNode {
void Profile(llvm::FoldingSetNodeID &ID) const {
const TagType *T = getTagType();
- Profile(ID, T->getKeyword(), T->getQualifier(), T->getOriginalDecl(),
+ Profile(ID, T->getKeyword(), T->getQualifier(), T->getDecl(),
T->isTagOwned(), T->isInjected());
}
@@ -6487,11 +6487,11 @@ class RecordType final : public TagType {
using TagType::TagType;
public:
- // FIXME: Temporarily renamed from `getDecl` in order to facilitate
- // rebasing, due to change in behaviour. This should be renamed back
- // to `getDecl` once the change is settled.
- RecordDecl *getOriginalDecl() const {
- return reinterpret_cast<RecordDecl *>(TagType::getOriginalDecl());
+ RecordDecl *getDecl() const {
+ return reinterpret_cast<RecordDecl *>(TagType::getDecl());
+ }
+ [[deprecated("Use getDecl instead")]] RecordDecl *getOriginalDecl() const {
+ return getDecl();
}
/// Recursively check all fields in the record for const-ness. If any field
@@ -6507,11 +6507,11 @@ class EnumType final : public TagType {
using TagType::TagType;
public:
- // FIXME: Temporarily renamed from `getDecl` in order to facilitate
- // rebasing, due to change in behaviour. This should be renamed back
- // to `getDecl` once the change is settled.
- EnumDecl *getOriginalDecl() const {
- return reinterpret_cast<EnumDecl *>(TagType::getOriginalDecl());
+ EnumDecl *getDecl() const {
+ return reinterpret_cast<EnumDecl *>(TagType::getDecl());
+ }
+ [[deprecated("Use getDecl instead")]] EnumDecl *getOriginalDecl() const {
+ return getDecl();
}
static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
@@ -6542,11 +6542,11 @@ class InjectedClassNameType final : public TagType {
bool IsInjected, const Type *CanonicalType);
public:
- // FIXME: Temporarily renamed from `getDecl` in order to facilitate
- // rebasing, due to change in behaviour. This should be renamed back
- // to `getDecl` once the change is settled.
- CXXRecordDecl *getOriginalDecl() const {
- return reinterpret_cast<CXXRecordDecl *>(TagType::getOriginalDecl());
+ CXXRecordDecl *getDecl() const {
+ return reinterpret_cast<CXXRecordDecl *>(TagType::getDecl());
+ }
+ [[deprecated("Use getDecl instead")]] CXXRecordDecl *getOriginalDecl() const {
+ return getDecl();
}
static bool classof(const Type *T) {
@@ -8930,8 +8930,8 @@ inline bool Type::isIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
- return IsEnumDeclComplete(ET->getOriginalDecl()) &&
- !IsEnumDeclScoped(ET->getOriginalDecl());
+ return IsEnumDeclComplete(ET->getDecl()) &&
+ !IsEnumDeclScoped(ET->getDecl());
}
return isBitIntType();
}
@@ -8989,7 +8989,7 @@ inline bool Type::isScalarType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
// Enums are scalar types, but only if they are defined. Incomplete enums
// are not treated as scalar types.
- return IsEnumDeclComplete(ET->getOriginalDecl());
+ return IsEnumDeclComplete(ET->getDecl());
return isa<PointerType>(CanonicalType) ||
isa<BlockPointerType>(CanonicalType) ||
isa<MemberPointerType>(CanonicalType) ||
@@ -9005,7 +9005,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
// Check for a complete enum type; incomplete enum types are not properly an
// enumeration type in the sense required here.
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
- return IsEnumDeclComplete(ET->getOriginalDecl());
+ return IsEnumDeclComplete(ET->getDecl());
return isBitIntType();
}
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 3f14ee8..2cefaa9 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -793,7 +793,7 @@ struct TagTypeLocInfo {
class TagTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, TagTypeLoc, TagType,
TagTypeLocInfo> {
public:
- TagDecl *getOriginalDecl() const { return getTypePtr()->getOriginalDecl(); }
+ TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
/// True if the tag was defined in this type specifier.
bool isDefinition() const;
@@ -854,9 +854,7 @@ class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
RecordTypeLoc,
RecordType> {
public:
- RecordDecl *getOriginalDecl() const {
- return getTypePtr()->getOriginalDecl();
- }
+ RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// Wrapper for source info for enum types.
@@ -864,7 +862,7 @@ class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
EnumTypeLoc,
EnumType> {
public:
- EnumDecl *getOriginalDecl() const { return getTypePtr()->getOriginalDecl(); }
+ EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// Wrapper for source info for injected class names of class
@@ -873,9 +871,7 @@ class InjectedClassNameTypeLoc
: public InheritingConcreteTypeLoc<TagTypeLoc, InjectedClassNameTypeLoc,
InjectedClassNameType> {
public:
- CXXRecordDecl *getOriginalDecl() const {
- return getTypePtr()->getOriginalDecl();
- }
+ CXXRecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// Wrapper for template type parameters.
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 9dc85fb..03613d5 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -575,7 +575,7 @@ let Class = TagType in {
let Conditional = [{ !IsCanonical }];
let Read = [{ node->getQualifier() }];
}
- def : Property<"TD", TagDeclRef> { let Read = [{ node->getOriginalDecl() }]; }
+ def : Property<"TD", TagDeclRef> { let Read = [{ node->getDecl() }]; }
}
let Class = EnumType in {
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 1ab6f11..c050fb7 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1017,7 +1017,7 @@ private:
// First, for any types that have a declaration, extract the declaration and
// match on it.
if (const auto *S = dyn_cast<TagType>(&Node)) {
- return matchesDecl(S->getOriginalDecl(), Finder, Builder);
+ return matchesDecl(S->getDecl(), Finder, Builder);
}
if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td
index 279c0c7..62c70fba 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -1359,23 +1359,17 @@ let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVect
def pshufb512 : X86Builtin<"_Vector<64, char>(_Vector<64, char>, _Vector<64, char>)">;
}
-let Features = "avx512cd,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
+let Features = "avx512cd,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
def vpconflictdi_128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>)">;
-}
-
-let Features = "avx512cd,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
- def vpconflictdi_256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>)">;
-}
-
-let Features = "avx512cd,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
def vpconflictsi_128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>)">;
}
-let Features = "avx512cd,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
+let Features = "avx512cd,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
+ def vpconflictdi_256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>)">;
def vpconflictsi_256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>)">;
}
-let Features = "avx512cd", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
+let Features = "avx512cd", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
def vpconflictdi_512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>)">;
def vpconflictsi_512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>)">;
}
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 9e85008..5f70b51 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -243,6 +243,7 @@ ENUM_LANGOPT(HLSLVersion, HLSLLangStd, 16, HLSL_Unset, NotCompatible, "HLSL Vers
LANGOPT(HLSLStrictAvailability, 1, 0, NotCompatible,
"Strict availability diagnostic mode for HLSL built-in functions.")
LANGOPT(HLSLSpvUseUnknownImageFormat, 1, 0, NotCompatible, "For storage images and texel buffers, sets the default format to 'Unknown' when not specified via the `vk::image_format` attribute. If this option is not used, the format is inferred from the resource's data type.")
+LANGOPT(HLSLSpvEnableMaximalReconvergence, 1, 0, NotCompatible, "Enables the MaximallyReconvergesKHR execution mode for this module. This ensures that control flow reconverges at well-defined merge points as defined by the Vulkan spec.")
LANGOPT(CUDAIsDevice , 1, 0, NotCompatible, "compiling for CUDA device")
LANGOPT(CUDAHostDeviceConstexpr, 1, 1, NotCompatible, "treating unattributed constexpr functions as __host__ __device__")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 41595ec..260a753 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -756,6 +756,15 @@ public:
bool isTargetDevice() const {
return OpenMPIsTargetDevice || CUDAIsDevice || SYCLIsDevice;
}
+
+ /// Returns the most applicable C standard-compliant language version code.
+ /// If none could be determined, returns \ref std::nullopt.
+ std::optional<uint32_t> getCLangStd() const;
+
+ /// Returns the most applicable C++ standard-compliant language
+ /// version code.
+ /// If none could be determined, returns \ref std::nullopt.
+ std::optional<uint32_t> getCPlusPlusLangStd() const;
};
/// Floating point control options
diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h
index 4941223..64645fe 100644
--- a/clang/include/clang/Basic/LangStandard.h
+++ b/clang/include/clang/Basic/LangStandard.h
@@ -70,8 +70,7 @@ enum LangFeatures {
/// standard.
struct LangStandard {
enum Kind {
-#define LANGSTANDARD(id, name, lang, desc, features) \
- lang_##id,
+#define LANGSTANDARD(id, name, lang, desc, features, version) lang_##id,
#include "clang/Basic/LangStandards.def"
lang_unspecified
};
@@ -80,6 +79,7 @@ struct LangStandard {
const char *Description;
unsigned Flags;
clang::Language Language;
+ std::optional<uint32_t> Version;
public:
/// getName - Get the name of this standard.
@@ -91,6 +91,9 @@ public:
/// Get the language that this standard describes.
clang::Language getLanguage() const { return Language; }
+ /// Get the version code for this language standard.
+ std::optional<uint32_t> getVersion() const { return Version; }
+
/// Language supports '//' comments.
bool hasLineComments() const { return Flags & LineComment; }
diff --git a/clang/include/clang/Basic/LangStandards.def b/clang/include/clang/Basic/LangStandards.def
index 244692a..4edc935 100644
--- a/clang/include/clang/Basic/LangStandards.def
+++ b/clang/include/clang/Basic/LangStandards.def
@@ -10,7 +10,7 @@
#error "LANGSTANDARD must be defined before including this file"
#endif
-/// LANGSTANDARD(IDENT, NAME, LANG, DESC, FEATURES)
+/// LANGSTANDARD(IDENT, NAME, LANG, DESC, FEATURES, VERSION)
///
/// \param IDENT - The name of the standard as a C++ identifier.
/// \param NAME - The name of the standard.
@@ -18,6 +18,8 @@
/// \param DESC - A short description of the standard.
/// \param FEATURES - The standard features as flags, these are enums from the
/// clang::frontend namespace, which is assumed to be available.
+/// \param VERSION - The official version code for this standard.
+/// Has value 'std::nullopt' if no official version exists.
/// LANGSTANDARD_ALIAS(IDENT, ALIAS)
/// \param IDENT - The name of the standard as a C++ identifier.
@@ -36,186 +38,188 @@
// C89-ish modes.
LANGSTANDARD(c89, "c89",
- C, "ISO C 1990", 0)
+ C, "ISO C 1990", 0, std::nullopt)
LANGSTANDARD_ALIAS(c89, "c90")
LANGSTANDARD_ALIAS(c89, "iso9899:1990")
LANGSTANDARD(c94, "iso9899:199409",
C, "ISO C 1990 with amendment 1",
- Digraphs)
+ Digraphs, 199409)
LANGSTANDARD(gnu89, "gnu89",
C, "ISO C 1990 with GNU extensions",
- LineComment | Digraphs | GNUMode)
+ LineComment | Digraphs | GNUMode, std::nullopt)
LANGSTANDARD_ALIAS(gnu89, "gnu90")
// C99-ish modes
LANGSTANDARD(c99, "c99",
C, "ISO C 1999",
- LineComment | C99 | Digraphs | HexFloat)
+ LineComment | C99 | Digraphs | HexFloat, 199901)
LANGSTANDARD_ALIAS(c99, "iso9899:1999")
LANGSTANDARD_ALIAS_DEPR(c99, "c9x")
LANGSTANDARD_ALIAS_DEPR(c99, "iso9899:199x")
LANGSTANDARD(gnu99, "gnu99",
C, "ISO C 1999 with GNU extensions",
- LineComment | C99 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | Digraphs | GNUMode | HexFloat, 199901)
LANGSTANDARD_ALIAS_DEPR(gnu99, "gnu9x")
// C11 modes
LANGSTANDARD(c11, "c11",
C, "ISO C 2011",
- LineComment | C99 | C11 | Digraphs | HexFloat)
+ LineComment | C99 | C11 | Digraphs | HexFloat, 201112)
LANGSTANDARD_ALIAS(c11, "iso9899:2011")
LANGSTANDARD_ALIAS_DEPR(c11, "c1x")
LANGSTANDARD_ALIAS_DEPR(c11, "iso9899:201x")
LANGSTANDARD(gnu11, "gnu11",
C, "ISO C 2011 with GNU extensions",
- LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat, 201112)
LANGSTANDARD_ALIAS_DEPR(gnu11, "gnu1x")
// C17 modes
LANGSTANDARD(c17, "c17",
C, "ISO C 2017",
- LineComment | C99 | C11 | C17 | Digraphs | HexFloat)
+ LineComment | C99 | C11 | C17 | Digraphs | HexFloat, 201710)
LANGSTANDARD_ALIAS(c17, "iso9899:2017")
LANGSTANDARD_ALIAS(c17, "c18")
LANGSTANDARD_ALIAS(c17, "iso9899:2018")
LANGSTANDARD(gnu17, "gnu17",
C, "ISO C 2017 with GNU extensions",
- LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat, 201710)
LANGSTANDARD_ALIAS(gnu17, "gnu18")
// C23 modes
LANGSTANDARD(c23, "c23",
C, "ISO C 2023",
- LineComment | C99 | C11 | C17 | C23 | Digraphs | HexFloat)
+ LineComment | C99 | C11 | C17 | C23 | Digraphs | HexFloat, 202311)
LANGSTANDARD_ALIAS(c23, "iso9899:2024")
LANGSTANDARD_ALIAS_DEPR(c23, "c2x")
LANGSTANDARD(gnu23, "gnu23",
C, "ISO C 2023 with GNU extensions",
- LineComment | C99 | C11 | C17 | C23 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | C11 | C17 | C23 | Digraphs | GNUMode | HexFloat, 202311)
LANGSTANDARD_ALIAS_DEPR(gnu23, "gnu2x")
// C2y modes
+// FIXME: Use correct version code for C2y once published.
LANGSTANDARD(c2y, "c2y",
C, "Working Draft for ISO C2y",
- LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | HexFloat)
+ LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | HexFloat, 202400)
LANGSTANDARD(gnu2y, "gnu2y",
C, "Working Draft for ISO C2y with GNU extensions",
- LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | GNUMode | HexFloat, 202400)
// TODO: Add the iso9899:202y alias once ISO publishes the standard.
// C++ modes
LANGSTANDARD(cxx98, "c++98",
CXX, "ISO C++ 1998 with amendments",
- LineComment | CPlusPlus | Digraphs)
+ LineComment | CPlusPlus | Digraphs, 199711)
LANGSTANDARD_ALIAS(cxx98, "c++03")
LANGSTANDARD(gnucxx98, "gnu++98",
CXX, "ISO C++ 1998 with amendments and GNU extensions",
- LineComment | CPlusPlus | Digraphs | GNUMode)
+ LineComment | CPlusPlus | Digraphs | GNUMode, 199711)
LANGSTANDARD_ALIAS(gnucxx98, "gnu++03")
LANGSTANDARD(cxx11, "c++11",
CXX, "ISO C++ 2011 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs, 201103)
LANGSTANDARD_ALIAS_DEPR(cxx11, "c++0x")
LANGSTANDARD(gnucxx11, "gnu++11", CXX,
"ISO C++ 2011 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode, 201103)
LANGSTANDARD_ALIAS_DEPR(gnucxx11, "gnu++0x")
LANGSTANDARD(cxx14, "c++14",
CXX, "ISO C++ 2014 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs, 201402)
LANGSTANDARD_ALIAS_DEPR(cxx14, "c++1y")
LANGSTANDARD(gnucxx14, "gnu++14",
CXX, "ISO C++ 2014 with amendments and GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs |
- GNUMode)
+ GNUMode, 201402)
LANGSTANDARD_ALIAS_DEPR(gnucxx14, "gnu++1y")
LANGSTANDARD(cxx17, "c++17",
CXX, "ISO C++ 2017 with amendments",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat)
+ Digraphs | HexFloat, 201703)
LANGSTANDARD_ALIAS_DEPR(cxx17, "c++1z")
LANGSTANDARD(gnucxx17, "gnu++17",
CXX, "ISO C++ 2017 with amendments and GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat | GNUMode)
+ Digraphs | HexFloat | GNUMode, 201703)
LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z")
LANGSTANDARD(cxx20, "c++20",
CXX, "ISO C++ 2020 DIS",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | Digraphs | HexFloat)
+ CPlusPlus20 | Digraphs | HexFloat, 202002)
LANGSTANDARD_ALIAS_DEPR(cxx20, "c++2a")
LANGSTANDARD(gnucxx20, "gnu++20",
CXX, "ISO C++ 2020 DIS with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | Digraphs | HexFloat | GNUMode)
+ CPlusPlus20 | Digraphs | HexFloat | GNUMode, 202002)
LANGSTANDARD_ALIAS_DEPR(gnucxx20, "gnu++2a")
LANGSTANDARD(cxx23, "c++23",
CXX, "ISO C++ 2023 DIS",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat)
+ CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat, 202302)
LANGSTANDARD_ALIAS_DEPR(cxx23, "c++2b")
LANGSTANDARD(gnucxx23, "gnu++23",
CXX, "ISO C++ 2023 DIS with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat | GNUMode)
+ CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat | GNUMode, 202302)
LANGSTANDARD_ALIAS_DEPR(gnucxx23, "gnu++2b")
+// FIXME: Use correct version code for C++26 once published.
LANGSTANDARD(cxx26, "c++2c",
CXX, "Working draft for C++2c",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat)
+ CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat, 202400)
LANGSTANDARD_ALIAS(cxx26, "c++26")
LANGSTANDARD(gnucxx26, "gnu++2c",
CXX, "Working draft for C++2c with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat | GNUMode)
+ CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat | GNUMode, 202400)
LANGSTANDARD_ALIAS(gnucxx26, "gnu++26")
// OpenCL
LANGSTANDARD(opencl10, "cl1.0",
OpenCL, "OpenCL 1.0",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD_ALIAS_DEPR(opencl10, "cl")
LANGSTANDARD(opencl11, "cl1.1",
OpenCL, "OpenCL 1.1",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(opencl12, "cl1.2",
OpenCL, "OpenCL 1.2",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(opencl20, "cl2.0",
OpenCL, "OpenCL 2.0",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(opencl30, "cl3.0",
OpenCL, "OpenCL 3.0",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(openclcpp10, "clc++1.0",
OpenCL, "C++ for OpenCL 1.0",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat | OpenCL)
+ Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD_ALIAS(openclcpp10, "clc++")
LANGSTANDARD(openclcpp2021, "clc++2021",
OpenCL, "C++ for OpenCL 2021",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat | OpenCL)
+ Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD_ALIAS_DEPR(opencl10, "CL")
LANGSTANDARD_ALIAS_DEPR(opencl11, "CL1.1")
@@ -229,35 +233,35 @@ LANGSTANDARD_ALIAS_DEPR(openclcpp2021, "CLC++2021")
// HLSL
LANGSTANDARD(hlsl, "hlsl",
HLSL, "High Level Shader Language",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2015, "hlsl2015",
HLSL, "High Level Shader Language 2015",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2016, "hlsl2016",
HLSL, "High Level Shader Language 2016",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2017, "hlsl2017",
HLSL, "High Level Shader Language 2017",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2018, "hlsl2018",
HLSL, "High Level Shader Language 2018",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2021, "hlsl2021",
HLSL, "High Level Shader Language 2021",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl202x, "hlsl202x",
HLSL, "High Level Shader Language 202x",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl202y, "hlsl202y",
HLSL, "High Level Shader Language 202y",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
#undef LANGSTANDARD
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index ee8ac99..7ae153d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6211,11 +6211,12 @@ def static : Flag<["-", "--"], "static">, Group<Link_Group>,
Flags<[NoArgumentUnused]>;
def std_default_EQ : Joined<["-"], "std-default=">;
def std_EQ : Joined<["-", "--"], "std=">,
- Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
- Group<CompileOnly_Group>, HelpText<"Language standard to compile for">,
- ValuesCode<[{
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ Group<CompileOnly_Group>,
+ HelpText<"Language standard to compile for">,
+ ValuesCode<[{
static constexpr const char VALUES_CODE [] =
- #define LANGSTANDARD(id, name, lang, desc, features) name ","
+ #define LANGSTANDARD(id, name, lang, desc, features, version) name ","
#define LANGSTANDARD_ALIAS(id, alias) alias ","
#include "clang/Basic/LangStandards.def"
;
@@ -9600,6 +9601,15 @@ def fhlsl_spv_use_unknown_image_format
"from the resource's data type.">,
MarshallingInfoFlag<LangOpts<"HLSLSpvUseUnknownImageFormat">>;
+def fhlsl_spv_enable_maximal_reconvergence
+ : Flag<["-"], "fspv-enable-maximal-reconvergence">,
+ Group<dxc_Group>,
+ Visibility<[CC1Option, DXCOption]>,
+ HelpText<"Enables the MaximallyReconvergesKHR execution mode for this "
+ "module. This ensures that control flow reconverges at "
+ "well-defined merge points as defined by the Vulkan spec.">,
+ MarshallingInfoFlag<LangOpts<"HLSLSpvEnableMaximalReconvergence">>;
+
def no_wasm_opt : Flag<["--"], "no-wasm-opt">,
Group<m_Group>,
HelpText<"Disable the wasm-opt optimizer">,
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 4473c54..b83bbcd 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -195,6 +195,11 @@ def NullDereferenceChecker
HelpText<"Check for dereferences of null pointers">,
Documentation<HasDocumentation>;
+def NullPointerArithmChecker
+ : Checker<"NullPointerArithm">,
+ HelpText<"Check for undefined arithmetic operations on null pointers">,
+ Documentation<HasDocumentation>;
+
def NonNullParamChecker : Checker<"NonNullParamChecker">,
HelpText<"Check for null pointers passed as arguments to a function whose "
"arguments are references or marked with the 'nonnull' attribute">,
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index e3cf1ba..1e87b47 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -140,8 +140,8 @@ public:
// It might be great to reuse FrontendOptions::getInputKindForExtension()
// but for now it doesn't discriminate between code and header files.
return llvm::StringSwitch<bool>(SM.getFilename(SL).rsplit('.').second)
- .Cases("c", "m", "mm", "C", "cc", "cp", true)
- .Cases("cpp", "CPP", "c++", "cxx", "cppm", true)
+ .Cases({"c", "m", "mm", "C", "cc", "cp"}, true)
+ .Cases({"cpp", "CPP", "c++", "cxx", "cppm"}, true)
.Default(false);
}
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 3603e9cd..e403b3e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -563,8 +563,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
// does not have one of its own.
QualType QT = TD->getUnderlyingType();
if (const auto *TT = QT->getAs<TagType>())
- if (comments::FullComment *FC =
- getCommentForDecl(TT->getOriginalDecl(), PP))
+ if (comments::FullComment *FC = getCommentForDecl(TT->getDecl(), PP))
return cloneFullComment(FC, D);
}
else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
@@ -2387,7 +2386,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Record:
case Type::Enum: {
const auto *TT = cast<TagType>(T);
- const TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf();
+ const TagDecl *TD = TT->getDecl()->getDefinitionOrSelf();
if (TD->isInvalidDecl()) {
Width = 8;
@@ -2531,7 +2530,7 @@ unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {
unsigned UnadjustedAlign;
if (const auto *RT = T->getAsCanonical<RecordType>()) {
- const ASTRecordLayout &Layout = getASTRecordLayout(RT->getOriginalDecl());
+ const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl());
UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
} else if (const auto *ObjCI = T->getAsCanonical<ObjCInterfaceType>()) {
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -3469,7 +3468,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
llvm_unreachable("should never get here");
}
case Type::Record: {
- const RecordDecl *RD = T->castAsCanonical<RecordType>()->getOriginalDecl();
+ const RecordDecl *RD = T->castAsCanonical<RecordType>()->getDecl();
const IdentifierInfo *II = RD->getIdentifier();
// In C++, an immediate typedef of an anonymous struct or union
@@ -5377,7 +5376,7 @@ TagType *ASTContext::getTagTypeInternal(ElaboratedTypeKeyword Keyword,
}();
assert(T->getKeyword() == Keyword);
assert(T->getQualifier() == Qualifier);
- assert(T->getOriginalDecl() == TD);
+ assert(T->getDecl() == TD);
assert(T->isInjected() == IsInjected);
assert(T->isTagOwned() == OwnsTag);
assert((T->isCanonicalUnqualified()
@@ -8271,7 +8270,7 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
static const Type *getIntegerTypeForEnum(const EnumType *ET) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
- const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ const EnumDecl *ED = ET->getDecl()->getDefinitionOrSelf();
if (ED->isComplete() && !ED->isScoped())
return ED->getIntegerType().getTypePtr();
return nullptr;
@@ -9189,7 +9188,7 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
S += llvm::utostr(Offset);
if (const auto *ET = T->getAsCanonical<EnumType>())
- S += ObjCEncodingForEnumDecl(Ctx, ET->getOriginalDecl());
+ S += ObjCEncodingForEnumDecl(Ctx, ET->getDecl());
else {
const auto *BT = T->castAs<BuiltinType>();
S += getObjCEncodingForPrimitiveType(Ctx, BT);
@@ -9246,7 +9245,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
if (const auto *BT = dyn_cast<BuiltinType>(CT))
S += getObjCEncodingForPrimitiveType(this, BT);
else
- S += ObjCEncodingForEnumDecl(this, cast<EnumType>(CT)->getOriginalDecl());
+ S += ObjCEncodingForEnumDecl(this, cast<EnumType>(CT)->getDecl());
return;
case Type::Complex:
@@ -9314,7 +9313,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
return;
}
} else if (const auto *RTy = PointeeTy->getAsCanonical<RecordType>()) {
- const IdentifierInfo *II = RTy->getOriginalDecl()->getIdentifier();
+ const IdentifierInfo *II = RTy->getDecl()->getIdentifier();
// GCC binary compat: Need to convert "struct objc_class *" to "#".
if (II == &Idents.get("objc_class")) {
S += '#';
@@ -9386,7 +9385,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
return;
case Type::Record: {
- RecordDecl *RDecl = cast<RecordType>(CT)->getOriginalDecl();
+ RecordDecl *RDecl = cast<RecordType>(CT)->getDecl();
S += RDecl->isUnion() ? '(' : '{';
// Anonymous structures print as '?'
if (const IdentifierInfo *II = RDecl->getIdentifier()) {
@@ -11290,7 +11289,7 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
bool OfBlockPointer,
bool Unqualified) {
if (const RecordType *UT = T->getAsUnionType()) {
- RecordDecl *UD = UT->getOriginalDecl()->getMostRecentDecl();
+ RecordDecl *UD = UT->getDecl()->getMostRecentDecl();
if (UD->hasAttr<TransparentUnionAttr>()) {
for (const auto *I : UD->fields()) {
QualType ET = I->getType().getUnqualifiedType();
@@ -11560,7 +11559,7 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET,
// Compatibility is based on the underlying type, not the promotion
// type.
QualType underlyingType =
- ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
+ ET->getDecl()->getDefinitionOrSelf()->getIntegerType();
if (underlyingType.isNull())
return {};
if (Context.hasSameType(underlyingType, other))
@@ -14160,11 +14159,10 @@ static QualType getCommonNonSugarTypeNode(const ASTContext &Ctx, const Type *X,
case Type::Record:
case Type::InjectedClassName: {
const auto *TX = cast<TagType>(X), *TY = cast<TagType>(Y);
- return Ctx.getTagType(
- ::getCommonTypeKeyword(TX, TY, /*IsSame=*/false),
- ::getCommonQualifier(Ctx, TX, TY, /*IsSame=*/false),
- ::getCommonDeclChecked(TX->getOriginalDecl(), TY->getOriginalDecl()),
- /*OwnedTag=*/false);
+ return Ctx.getTagType(::getCommonTypeKeyword(TX, TY, /*IsSame=*/false),
+ ::getCommonQualifier(Ctx, TX, TY, /*IsSame=*/false),
+ ::getCommonDeclChecked(TX->getDecl(), TY->getDecl()),
+ /*OwnedTag=*/false);
}
case Type::TemplateSpecialization: {
const auto *TX = cast<TemplateSpecializationType>(X),
diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp
index d7fd411..b8023cb 100644
--- a/clang/lib/AST/ASTDiagnostic.cpp
+++ b/clang/lib/AST/ASTDiagnostic.cpp
@@ -196,8 +196,7 @@ break; \
// Don't desugar through the primary typedef of an anonymous type.
if (const TagType *UTT = Underlying->getAs<TagType>())
if (const TypedefType *QTT = dyn_cast<TypedefType>(QT))
- if (UTT->getOriginalDecl()->getTypedefNameForAnonDecl() ==
- QTT->getDecl())
+ if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
break;
// Record that we actually looked through an opaque type here.
@@ -1147,14 +1146,11 @@ class TemplateDiff {
if (const auto* SubstType = Ty->getAs<SubstTemplateTypeParmType>())
Ty = SubstType->getReplacementType();
- const RecordType *RT = Ty->getAs<RecordType>();
-
+ const auto *RT = Ty->getAs<RecordType>();
if (!RT)
return nullptr;
- const ClassTemplateSpecializationDecl *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
-
+ const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
if (!CTSD)
return nullptr;
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index f43fa8c..bf51c3e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1740,7 +1740,7 @@ ExpectedType ASTNodeImporter::VisitDeducedTemplateSpecializationType(
}
ExpectedType ASTNodeImporter::VisitTagType(const TagType *T) {
- TagDecl *DeclForType = T->getOriginalDecl();
+ TagDecl *DeclForType = T->getDecl();
Expected<TagDecl *> ToDeclOrErr = import(DeclForType);
if (!ToDeclOrErr)
return ToDeclOrErr.takeError();
@@ -2155,7 +2155,7 @@ Error ASTNodeImporter::ImportDeclParts(
const Type *LeafT =
getLeafPointeeType(P->getType().getCanonicalType().getTypePtr());
auto *RT = dyn_cast<RecordType>(LeafT);
- if (RT && RT->getOriginalDecl() == D) {
+ if (RT && RT->getDecl() == D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
@@ -2408,8 +2408,8 @@ Error ASTNodeImporter::ImportFieldDeclDefinition(const FieldDecl *From,
const RecordType *RecordTo = ToType->getAs<RecordType>();
if (RecordFrom && RecordTo) {
- FromRecordDecl = RecordFrom->getOriginalDecl();
- ToRecordDecl = RecordTo->getOriginalDecl();
+ FromRecordDecl = RecordFrom->getDecl();
+ ToRecordDecl = RecordTo->getDecl();
}
}
@@ -3205,7 +3205,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
if (auto *Typedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
- FoundDecl = Tag->getOriginalDecl();
+ FoundDecl = Tag->getDecl();
}
if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
@@ -3336,7 +3336,7 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Decl *Found = FoundDecl;
if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
- Found = Tag->getOriginalDecl();
+ Found = Tag->getDecl();
}
if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) {
@@ -3757,12 +3757,11 @@ public:
}
std::optional<bool> VisitTagType(const TagType *T) {
- if (auto *Spec =
- dyn_cast<ClassTemplateSpecializationDecl>(T->getOriginalDecl()))
+ if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
for (const auto &Arg : Spec->getTemplateArgs().asArray())
if (checkTemplateArgument(Arg))
return true;
- return isAncestorDeclContextOf(ParentDC, T->getOriginalDecl());
+ return isAncestorDeclContextOf(ParentDC, T->getDecl());
}
std::optional<bool> VisitPointerType(const PointerType *T) {
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index b17cd6f..da64c92 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -878,10 +878,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// Treat the enumeration as its underlying type and use the builtin type
// class comparison.
if (T1->getTypeClass() == Type::Enum) {
- T1 = cast<EnumType>(T1)->getOriginalDecl()->getIntegerType();
+ T1 = cast<EnumType>(T1)->getDecl()->getIntegerType();
assert(T2->isBuiltinType() && !T1.isNull()); // Sanity check
} else if (T2->getTypeClass() == Type::Enum) {
- T2 = cast<EnumType>(T2)->getOriginalDecl()->getIntegerType();
+ T2 = cast<EnumType>(T2)->getDecl()->getIntegerType();
assert(T1->isBuiltinType() && !T2.isNull()); // Sanity check
}
TC = Type::Builtin;
@@ -1300,8 +1300,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, TT1->getQualifier(),
TT2->getQualifier()))
return false;
- if (!IsStructurallyEquivalent(Context, TT1->getOriginalDecl(),
- TT2->getOriginalDecl()))
+ if (!IsStructurallyEquivalent(Context, TT1->getDecl(), TT2->getDecl()))
return false;
break;
}
@@ -1531,8 +1530,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// types
if (Field1->isAnonymousStructOrUnion() &&
Field2->isAnonymousStructOrUnion()) {
- RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getOriginalDecl();
- RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getOriginalDecl();
+ RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
return IsStructurallyEquivalent(Context, D1, D2);
}
@@ -2587,7 +2586,7 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
// struct { ... } A;
QualType FieldType = F->getType();
if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
- const RecordDecl *RecDecl = RecType->getOriginalDecl();
+ const RecordDecl *RecDecl = RecType->getDecl();
if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) {
if (Context.hasSameType(FieldType, AnonTy))
break;
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index c71fd22..74cae03 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4660,7 +4660,7 @@ const RecordType *Compiler<Emitter>::getRecordTy(QualType Ty) {
template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
if (const auto *RecordTy = getRecordTy(Ty))
- return getRecord(RecordTy->getOriginalDecl()->getDefinitionOrSelf());
+ return getRecord(RecordTy->getDecl()->getDefinitionOrSelf());
return nullptr;
}
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 8904396..a72282c 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1358,9 +1358,6 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED,
const APSInt &Value) {
- if (S.EvaluatingDecl && !S.EvaluatingDecl->isConstexpr())
- return;
-
llvm::APInt Min;
llvm::APInt Max;
ED->getValueRange(Max, Min);
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 57cc705..812d25f 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3096,7 +3096,8 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
}
if (Offset.isZero()) {
- if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) {
+ if (const Descriptor *Desc = Ptr.getFieldDesc();
+ Desc && Desc->isArray() && Ptr.getIndex() == 0) {
S.Stk.push<Pointer>(Ptr.atIndex(0).narrow());
return true;
}
@@ -3126,7 +3127,8 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
}
if (Offset.isZero()) {
- if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) {
+ if (const Descriptor *Desc = Ptr.getFieldDesc();
+ Desc && Desc->isArray() && Ptr.getIndex() == 0) {
S.Stk.push<Pointer>(Ptr.atIndex(0).narrow());
return true;
}
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index b69f360..a0d2c76 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3101,6 +3101,33 @@ static bool interp__builtin_vec_set(InterpState &S, CodePtr OpPC,
return true;
}
+static bool interp__builtin_ia32_vpconflict(InterpState &S, CodePtr OpPC,
+ const CallExpr *Call) {
+ assert(Call->getNumArgs() == 1);
+
+ QualType Arg0Type = Call->getArg(0)->getType();
+ const auto *VecT = Arg0Type->castAs<VectorType>();
+ PrimType ElemT = *S.getContext().classify(VecT->getElementType());
+ unsigned NumElems = VecT->getNumElements();
+ bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
+ const Pointer &Src = S.Stk.pop<Pointer>();
+ const Pointer &Dst = S.Stk.peek<Pointer>();
+
+ for (unsigned I = 0; I != NumElems; ++I) {
+ INT_TYPE_SWITCH_NO_BOOL(ElemT, {
+ APSInt ElemI = Src.elem<T>(I).toAPSInt();
+ APInt ConflictMask(ElemI.getBitWidth(), 0);
+ for (unsigned J = 0; J != I; ++J) {
+ APSInt ElemJ = Src.elem<T>(J).toAPSInt();
+ ConflictMask.setBitVal(J, ElemI == ElemJ);
+ }
+ Dst.elem<T>(I) = static_cast<T>(APSInt(ConflictMask, DestUnsigned));
+ });
+ }
+ Dst.initializeAllElements();
+ return true;
+}
+
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
uint32_t BuiltinID) {
if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
@@ -3891,7 +3918,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
[](const APSInt &Lo, const APSInt &Hi, const APSInt &Amt) {
return llvm::APIntOps::fshr(Hi, Lo, Amt);
});
-
+ case X86::BI__builtin_ia32_vpconflictsi_128:
+ case X86::BI__builtin_ia32_vpconflictsi_256:
+ case X86::BI__builtin_ia32_vpconflictsi_512:
+ case X86::BI__builtin_ia32_vpconflictdi_128:
+ case X86::BI__builtin_ia32_vpconflictdi_256:
+ case X86::BI__builtin_ia32_vpconflictdi_512:
+ return interp__builtin_ia32_vpconflict(S, OpPC, Call);
case clang::X86::BI__builtin_ia32_blendpd:
case clang::X86::BI__builtin_ia32_blendpd256:
case clang::X86::BI__builtin_ia32_blendps:
diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h
index a13244b..e2e4d5c 100644
--- a/clang/lib/AST/ByteCode/InterpState.h
+++ b/clang/lib/AST/ByteCode/InterpState.h
@@ -114,7 +114,7 @@ public:
Alloc = std::make_unique<DynamicAllocator>();
}
- return *Alloc.get();
+ return *Alloc;
}
/// Diagnose any dynamic allocations that haven't been freed yet.
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 663134c..e417bdf 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -751,7 +751,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
assert(Record && "Missing record descriptor");
bool Ok = true;
- if (RT->getOriginalDecl()->isUnion()) {
+ if (RT->getDecl()->isUnion()) {
const FieldDecl *ActiveField = nullptr;
APValue Value;
for (const auto &F : Record->fields()) {
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 69cbf6e..f048076 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2989,10 +2989,7 @@ bool ParmVarDecl::isDestroyedInCallee() const {
// FIXME: isParamDestroyedInCallee() should probably imply
// isDestructedType()
const auto *RT = getType()->getAsCanonical<RecordType>();
- if (RT &&
- RT->getOriginalDecl()
- ->getDefinitionOrSelf()
- ->isParamDestroyedInCallee() &&
+ if (RT && RT->getDecl()->getDefinitionOrSelf()->isParamDestroyedInCallee() &&
getType().isDestructedType())
return true;
@@ -3507,7 +3504,7 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation(
while (const auto *TD = T->getAs<TypedefType>())
T = TD->getDecl()->getUnderlyingType();
const IdentifierInfo *II =
- T->castAsCanonical<EnumType>()->getOriginalDecl()->getIdentifier();
+ T->castAsCanonical<EnumType>()->getDecl()->getIdentifier();
if (II && II->isStr("__hot_cold_t"))
Consume();
}
@@ -4709,7 +4706,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const {
return false;
if (const auto *Record = getType()->getAsCanonical<RecordType>())
- return Record->getOriginalDecl()->isAnonymousStructOrUnion();
+ return Record->getDecl()->isAnonymousStructOrUnion();
return false;
}
@@ -4769,7 +4766,7 @@ bool FieldDecl::isZeroSize(const ASTContext &Ctx) const {
const auto *RT = getType()->getAsCanonical<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
+ const RecordDecl *RD = RT->getDecl()->getDefinition();
if (!RD) {
assert(isInvalidDecl() && "valid field has incomplete type");
return false;
@@ -5194,7 +5191,7 @@ bool RecordDecl::isOrContainsUnion() const {
if (const RecordDecl *Def = getDefinition()) {
for (const FieldDecl *FD : Def->fields()) {
const RecordType *RT = FD->getType()->getAsCanonical<RecordType>();
- if (RT && RT->getOriginalDecl()->isOrContainsUnion())
+ if (RT && RT->getDecl()->isOrContainsUnion())
return true;
}
}
@@ -5692,14 +5689,14 @@ void TypedefNameDecl::anchor() {}
TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const {
if (auto *TT = getTypeSourceInfo()->getType()->getAs<TagType>()) {
- auto *OwningTypedef = TT->getOriginalDecl()->getTypedefNameForAnonDecl();
+ auto *OwningTypedef = TT->getDecl()->getTypedefNameForAnonDecl();
auto *ThisTypedef = this;
if (AnyRedecl && OwningTypedef) {
OwningTypedef = OwningTypedef->getCanonicalDecl();
ThisTypedef = ThisTypedef->getCanonicalDecl();
}
if (OwningTypedef == ThisTypedef)
- return TT->getOriginalDecl()->getDefinitionOrSelf();
+ return TT->getDecl()->getDefinitionOrSelf();
}
return nullptr;
@@ -5708,7 +5705,7 @@ TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const {
bool TypedefNameDecl::isTransparentTagSlow() const {
auto determineIsTransparent = [&]() {
if (auto *TT = getUnderlyingType()->getAs<TagType>()) {
- if (auto *TD = TT->getOriginalDecl()) {
+ if (auto *TD = TT->getDecl()) {
if (TD->getName() != getName())
return false;
SourceLocation TTLoc = getLocation();
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 43264f8..24e4f18 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2314,7 +2314,7 @@ bool CXXRecordDecl::mayBeAbstract() const {
for (const auto &B : bases()) {
const auto *BaseDecl = cast<CXXRecordDecl>(
- B.getType()->castAsCanonical<RecordType>()->getOriginalDecl());
+ B.getType()->castAsCanonical<RecordType>()->getDecl());
if (BaseDecl->isAbstract())
return true;
}
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 7f3dcca..47ae613 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -485,7 +485,7 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
QualType BaseType = GetBaseType(CurDeclType);
if (const auto *TT = dyn_cast_or_null<TagType>(BaseType);
TT && TT->isTagOwned()) {
- if (TT->getOriginalDecl() == Decls[0]) {
+ if (TT->getDecl() == Decls[0]) {
Decls.push_back(*D);
continue;
}
diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp
index 55f5a99..9a89a66 100644
--- a/clang/lib/AST/DeclarationName.cpp
+++ b/clang/lib/AST/DeclarationName.cpp
@@ -116,12 +116,12 @@ static void printCXXConstructorDestructorName(QualType ClassType,
Policy.SuppressScope = true;
if (const RecordType *ClassRec = ClassType->getAsCanonical<RecordType>()) {
- ClassRec->getOriginalDecl()->printName(OS, Policy);
+ ClassRec->getDecl()->printName(OS, Policy);
return;
}
if (Policy.SuppressTemplateArgsInCXXConstructors) {
if (auto *InjTy = ClassType->getAsCanonical<InjectedClassNameType>()) {
- InjTy->getOriginalDecl()->printName(OS, Policy);
+ InjTy->getDecl()->printName(OS, Policy);
return;
}
}
@@ -185,7 +185,7 @@ void DeclarationName::print(raw_ostream &OS,
OS << "operator ";
QualType Type = getCXXNameType();
if (const RecordType *Rec = Type->getAs<RecordType>()) {
- OS << *Rec->getOriginalDecl();
+ OS << *Rec->getDecl();
return;
}
// We know we're printing C++ here, ensure we print 'bool' properly.
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 597cbd8..340bb4b 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -4126,9 +4126,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
if (const RecordType *UT = getType()->getAsUnionType())
if (!Ctx.getLangOpts().CPlusPlus11 && UT &&
- UT->getOriginalDecl()
- ->getMostRecentDecl()
- ->hasAttr<TransparentUnionAttr>())
+ UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>())
if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){
const Expr *InitExpr = CLE->getInitializer();
if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 149b7d7..16141b2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4074,8 +4074,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
}
// Next subobject is a class, struct or union field.
- RecordDecl *RD =
- ObjType->castAsCanonical<RecordType>()->getOriginalDecl();
+ RecordDecl *RD = ObjType->castAsCanonical<RecordType>()->getDecl();
if (RD->isUnion()) {
const FieldDecl *UnionField = O->getUnionField();
if (!UnionField ||
@@ -7810,7 +7809,7 @@ class BufferToAPValueConverter {
std::optional<APValue> visit(const EnumType *Ty, CharUnits Offset) {
QualType RepresentationType =
- Ty->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
+ Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
assert(!RepresentationType.isNull() &&
"enum forward decl should be caught by Sema");
const auto *AsBuiltin =
@@ -8607,7 +8606,7 @@ public:
const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
if (!FD) return Error(E);
assert(!FD->getType()->isReferenceType() && "prvalue reference?");
- assert(BaseTy->castAsCanonical<RecordType>()->getOriginalDecl() ==
+ assert(BaseTy->castAsCanonical<RecordType>()->getDecl() ==
FD->getParent()->getCanonicalDecl() &&
"record / field mismatch");
@@ -8836,7 +8835,7 @@ public:
const ValueDecl *MD = E->getMemberDecl();
if (const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) {
- assert(BaseTy->castAsCanonical<RecordType>()->getOriginalDecl() ==
+ assert(BaseTy->castAsCanonical<RecordType>()->getDecl() ==
FD->getParent()->getCanonicalDecl() &&
"record / field mismatch");
(void)BaseTy;
@@ -12180,6 +12179,37 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
+ case X86::BI__builtin_ia32_vpconflictsi_128:
+ case X86::BI__builtin_ia32_vpconflictsi_256:
+ case X86::BI__builtin_ia32_vpconflictsi_512:
+ case X86::BI__builtin_ia32_vpconflictdi_128:
+ case X86::BI__builtin_ia32_vpconflictdi_256:
+ case X86::BI__builtin_ia32_vpconflictdi_512: {
+ APValue Source;
+
+ if (!EvaluateAsRValue(Info, E->getArg(0), Source))
+ return false;
+
+ unsigned SourceLen = Source.getVectorLength();
+ SmallVector<APValue, 32> ResultElements;
+ ResultElements.reserve(SourceLen);
+
+ const auto *VecT = E->getType()->castAs<VectorType>();
+ bool DestUnsigned =
+ VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
+
+ for (unsigned I = 0; I != SourceLen; ++I) {
+ const APValue &EltI = Source.getVectorElt(I);
+
+ APInt ConflictMask(EltI.getInt().getBitWidth(), 0);
+ for (unsigned J = 0; J != I; ++J) {
+ const APValue &EltJ = Source.getVectorElt(J);
+ ConflictMask.setBitVal(J, EltI.getInt() == EltJ.getInt());
+ }
+ ResultElements.push_back(APValue(APSInt(ConflictMask, DestUnsigned)));
+ }
+ return Success(APValue(ResultElements.data(), ResultElements.size()), E);
+ }
case X86::BI__builtin_ia32_blendpd:
case X86::BI__builtin_ia32_blendpd256:
case X86::BI__builtin_ia32_blendps:
diff --git a/clang/lib/AST/InheritViz.cpp b/clang/lib/AST/InheritViz.cpp
index 3c4a5a8..c5f4c2b 100644
--- a/clang/lib/AST/InheritViz.cpp
+++ b/clang/lib/AST/InheritViz.cpp
@@ -89,8 +89,8 @@ void InheritanceHierarchyWriter::WriteNode(QualType Type, bool FromVirtual) {
Out << " \"];\n";
// Display the base classes.
- const auto *Decl = cast<CXXRecordDecl>(
- Type->castAsCanonical<RecordType>()->getOriginalDecl());
+ const auto *Decl =
+ cast<CXXRecordDecl>(Type->castAsCanonical<RecordType>()->getDecl());
for (const auto &Base : Decl->bases()) {
QualType CanonBaseType = Context.getCanonicalType(Base.getType());
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 844db79..5572e0a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2491,7 +2491,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::Enum:
case Type::Record:
mangleSourceNameWithAbiTags(
- cast<TagType>(Ty)->getOriginalDecl()->getDefinitionOrSelf());
+ cast<TagType>(Ty)->getDecl()->getDefinitionOrSelf());
break;
case Type::TemplateSpecialization: {
@@ -2556,9 +2556,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
}
case Type::InjectedClassName:
- mangleSourceNameWithAbiTags(cast<InjectedClassNameType>(Ty)
- ->getOriginalDecl()
- ->getDefinitionOrSelf());
+ mangleSourceNameWithAbiTags(
+ cast<InjectedClassNameType>(Ty)->getDecl()->getDefinitionOrSelf());
break;
case Type::DependentName:
@@ -3795,7 +3794,7 @@ void CXXNameMangler::mangleType(const RecordType *T) {
mangleType(static_cast<const TagType*>(T));
}
void CXXNameMangler::mangleType(const TagType *T) {
- mangleName(T->getOriginalDecl()->getDefinitionOrSelf());
+ mangleName(T->getDecl()->getDefinitionOrSelf());
}
// <type> ::= <array-type>
@@ -4430,8 +4429,8 @@ void CXXNameMangler::mangleType(const InjectedClassNameType *T) {
// Mangle injected class name types as if the user had written the
// specialization out fully. It may not actually be possible to see
// this mangling, though.
- mangleType(T->getOriginalDecl()->getCanonicalTemplateSpecializationType(
- getASTContext()));
+ mangleType(
+ T->getDecl()->getCanonicalTemplateSpecializationType(getASTContext()));
}
void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
@@ -4692,7 +4691,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T,
void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) {
// Ignore member expressions involving anonymous unions.
while (const auto *RT = Base->getType()->getAsCanonical<RecordType>()) {
- if (!RT->getOriginalDecl()->isAnonymousStructOrUnion())
+ if (!RT->getDecl()->isAnonymousStructOrUnion())
break;
const auto *ME = dyn_cast<MemberExpr>(Base);
if (!ME)
@@ -7010,8 +7009,7 @@ bool CXXNameMangler::isSpecializedAs(QualType S, llvm::StringRef Name,
if (!RT)
return false;
- const ClassTemplateSpecializationDecl *SD =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
+ const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
if (!SD || !SD->getIdentifier()->isStr(Name))
return false;
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index 0ef6328..9f4dba9 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -396,7 +396,7 @@ llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {
for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) {
const CXXBaseSpecifier *Base = *I;
const auto *RD = cast<CXXRecordDecl>(
- Base->getType()->castAsCanonical<RecordType>()->getOriginalDecl());
+ Base->getType()->castAsCanonical<RecordType>()->getDecl());
llvm::json::Object Val{{"name", RD->getName()}};
if (Base->isVirtual())
@@ -764,7 +764,7 @@ void JSONNodeDumper::VisitTagType(const TagType *TT) {
Qualifier.print(OS, PrintPolicy, /*ResolveTemplateArguments=*/true);
JOS.attribute("qualifier", Str);
}
- JOS.attribute("decl", createBareDeclRef(TT->getOriginalDecl()));
+ JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
if (TT->isTagOwned())
JOS.attribute("isTagOwned", true);
}
@@ -816,7 +816,7 @@ void JSONNodeDumper::VisitTemplateSpecializationType(
void JSONNodeDumper::VisitInjectedClassNameType(
const InjectedClassNameType *ICNT) {
- JOS.attribute("decl", createBareDeclRef(ICNT->getOriginalDecl()));
+ JOS.attribute("decl", createBareDeclRef(ICNT->getDecl()));
}
void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 8cbc72b..f1baf9f 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -3248,11 +3248,11 @@ void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
}
void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
SourceRange) {
- mangleType(cast<TagType>(T)->getOriginalDecl());
+ mangleType(cast<TagType>(T)->getDecl());
}
void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,
SourceRange) {
- mangleType(cast<TagType>(T)->getOriginalDecl());
+ mangleType(cast<TagType>(T)->getDecl());
}
void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
// MSVC chooses the tag kind of the definition if it exists, otherwise it
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 6842038..46a4e25 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -913,7 +913,7 @@ public:
return false;
if (TypedefT->getDecl()->getIdentifier() !=
- TagT->getOriginalDecl()->getIdentifier())
+ TagT->getDecl()->getIdentifier())
return false;
ID.AddInteger(TagT->getTypeClass());
@@ -1059,7 +1059,7 @@ public:
}
void VisitInjectedClassNameType(const InjectedClassNameType *T) {
- AddDecl(T->getOriginalDecl()->getDefinitionOrSelf());
+ AddDecl(T->getDecl()->getDefinitionOrSelf());
VisitType(T);
}
@@ -1164,7 +1164,7 @@ public:
AddNestedNameSpecifier(ElaboratedOverride
? ElaboratedOverride->getQualifier()
: T->getQualifier());
- AddDecl(T->getOriginalDecl()->getDefinitionOrSelf());
+ AddDecl(T->getDecl()->getDefinitionOrSelf());
VisitType(T);
}
diff --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp
index acc011c..7138dff 100644
--- a/clang/lib/AST/ParentMapContext.cpp
+++ b/clang/lib/AST/ParentMapContext.cpp
@@ -20,36 +20,6 @@
using namespace clang;
-ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}
-
-ParentMapContext::~ParentMapContext() = default;
-
-void ParentMapContext::clear() { Parents.reset(); }
-
-const Expr *ParentMapContext::traverseIgnored(const Expr *E) const {
- return traverseIgnored(const_cast<Expr *>(E));
-}
-
-Expr *ParentMapContext::traverseIgnored(Expr *E) const {
- if (!E)
- return nullptr;
-
- switch (Traversal) {
- case TK_AsIs:
- return E;
- case TK_IgnoreUnlessSpelledInSource:
- return E->IgnoreUnlessSpelledInSource();
- }
- llvm_unreachable("Invalid Traversal type!");
-}
-
-DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const {
- if (const auto *E = N.get<Expr>()) {
- return DynTypedNode::create(*traverseIgnored(E));
- }
- return N;
-}
-
template <typename T, typename... U>
static std::tuple<bool, DynTypedNodeList, const T *, const U *...>
matchParents(const DynTypedNodeList &NodeList,
@@ -334,6 +304,36 @@ matchParents(const DynTypedNodeList &NodeList,
return MatchParents<T, U...>::match(NodeList, ParentMap);
}
+ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}
+
+ParentMapContext::~ParentMapContext() = default;
+
+void ParentMapContext::clear() { Parents.reset(); }
+
+const Expr *ParentMapContext::traverseIgnored(const Expr *E) const {
+ return traverseIgnored(const_cast<Expr *>(E));
+}
+
+Expr *ParentMapContext::traverseIgnored(Expr *E) const {
+ if (!E)
+ return nullptr;
+
+ switch (Traversal) {
+ case TK_AsIs:
+ return E;
+ case TK_IgnoreUnlessSpelledInSource:
+ return E->IgnoreUnlessSpelledInSource();
+ }
+ llvm_unreachable("Invalid Traversal type!");
+}
+
+DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const {
+ if (const auto *E = N.get<Expr>()) {
+ return DynTypedNode::create(*traverseIgnored(E));
+ }
+ return N;
+}
+
/// Template specializations to abstract away from pointers and TypeLocs.
/// @{
template <typename T> static DynTypedNode createDynTypedNode(const T &Node) {
diff --git a/clang/lib/AST/QualTypeNames.cpp b/clang/lib/AST/QualTypeNames.cpp
index a2f9309..1918416 100644
--- a/clang/lib/AST/QualTypeNames.cpp
+++ b/clang/lib/AST/QualTypeNames.cpp
@@ -125,7 +125,7 @@ static const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx,
// which can point to a template instantiation with no sugar in any of
// its template argument, however we still need to fully qualify them.
- const auto *TD = TSTRecord->getOriginalDecl();
+ const auto *TD = TSTRecord->getDecl();
const auto *TSTDecl = dyn_cast<ClassTemplateSpecializationDecl>(TD);
if (!TSTDecl)
return Ctx.getTagType(Keyword, Qualifier, TD, /*OwnsTag=*/false)
@@ -232,7 +232,7 @@ static NestedNameSpecifier getFullyQualifiedNestedNameSpecifier(
// Find decl context.
const TypeDecl *TD;
if (const TagType *TagDeclType = Type->getAs<TagType>())
- TD = TagDeclType->getOriginalDecl();
+ TD = TagDeclType->getDecl();
else if (const auto *D = dyn_cast<TypedefType>(Type))
TD = D->getDecl();
else
@@ -316,7 +316,7 @@ createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Type *TypePtr,
if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
Decl = TDT->getDecl();
} else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
- Decl = TagDeclType->getOriginalDecl();
+ Decl = TagDeclType->getDecl();
} else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
Decl = TST->getTemplateName().getAsTemplateDecl();
} else {
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 00b938b..ac18d4d 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2009,7 +2009,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
} else if (const BuiltinType *BTy = BaseTy->getAs<BuiltinType>()) {
performBuiltinTypeAlignmentUpgrade(BTy);
} else if (const RecordType *RT = BaseTy->getAsCanonical<RecordType>()) {
- const RecordDecl *RD = RT->getOriginalDecl();
+ const RecordDecl *RD = RT->getDecl();
const ASTRecordLayout &FieldRecord = Context.getASTRecordLayout(RD);
PreferredAlign = FieldRecord.getPreferredAlignment();
}
@@ -2710,7 +2710,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
if (const auto *RT = FD->getType()
->getBaseElementTypeUnsafe()
->getAsCanonical<RecordType>()) {
- auto const &Layout = Context.getASTRecordLayout(RT->getOriginalDecl());
+ auto const &Layout = Context.getASTRecordLayout(RT->getDecl());
EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject();
FieldRequiredAlignment = std::max(FieldRequiredAlignment,
Layout.getRequiredAlignment());
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index cf5e914..41aebdb 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1401,7 +1401,7 @@ static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
OS << " -> ";
const auto *RD = cast<CXXRecordDecl>(
- Base->getType()->castAsCanonical<RecordType>()->getOriginalDecl());
+ Base->getType()->castAsCanonical<RecordType>()->getDecl());
if (Base->isVirtual())
OS << "virtual ";
@@ -2180,7 +2180,7 @@ void TextNodeDumper::VisitTagType(const TagType *T) {
K != ElaboratedTypeKeyword::None)
OS << ' ' << TypeWithKeyword::getKeywordName(K);
dumpNestedNameSpecifier(T->getQualifier());
- dumpDeclRef(T->getOriginalDecl());
+ dumpDeclRef(T->getDecl());
}
void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
@@ -2232,7 +2232,7 @@ void TextNodeDumper::VisitTemplateSpecializationType(
void TextNodeDumper::VisitInjectedClassNameType(
const InjectedClassNameType *T) {
- dumpDeclRef(T->getOriginalDecl());
+ dumpDeclRef(T->getDecl());
}
void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index ee7a68e..4548af1 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -114,7 +114,7 @@ const IdentifierInfo *QualType::getBaseTypeIdentifier() const {
if (ty->isPointerOrReferenceType())
return ty->getPointeeType().getBaseTypeIdentifier();
if (const auto *TT = ty->getAs<TagType>())
- ND = TT->getOriginalDecl();
+ ND = TT->getDecl();
else if (ty->getTypeClass() == Type::Typedef)
ND = ty->castAs<TypedefType>()->getDecl();
else if (ty->isArrayType())
@@ -671,13 +671,13 @@ const Type *Type::getUnqualifiedDesugaredType() const {
bool Type::isClassType() const {
if (const auto *RT = getAsCanonical<RecordType>())
- return RT->getOriginalDecl()->isClass();
+ return RT->getDecl()->isClass();
return false;
}
bool Type::isStructureType() const {
if (const auto *RT = getAsCanonical<RecordType>())
- return RT->getOriginalDecl()->isStruct();
+ return RT->getDecl()->isStruct();
return false;
}
@@ -685,7 +685,7 @@ bool Type::isStructureTypeWithFlexibleArrayMember() const {
const auto *RT = getAsCanonical<RecordType>();
if (!RT)
return false;
- const auto *Decl = RT->getOriginalDecl();
+ const auto *Decl = RT->getDecl();
if (!Decl->isStruct())
return false;
return Decl->getDefinitionOrSelf()->hasFlexibleArrayMember();
@@ -699,13 +699,13 @@ bool Type::isObjCBoxableRecordType() const {
bool Type::isInterfaceType() const {
if (const auto *RT = getAsCanonical<RecordType>())
- return RT->getOriginalDecl()->isInterface();
+ return RT->getDecl()->isInterface();
return false;
}
bool Type::isStructureOrClassType() const {
if (const auto *RT = getAsCanonical<RecordType>())
- return RT->getOriginalDecl()->isStructureOrClass();
+ return RT->getDecl()->isStructureOrClass();
return false;
}
@@ -717,7 +717,7 @@ bool Type::isVoidPointerType() const {
bool Type::isUnionType() const {
if (const auto *RT = getAsCanonical<RecordType>())
- return RT->getOriginalDecl()->isUnion();
+ return RT->getDecl()->isUnion();
return false;
}
@@ -734,7 +734,7 @@ bool Type::isComplexIntegerType() const {
bool Type::isScopedEnumeralType() const {
if (const auto *ET = getAsCanonical<EnumType>())
- return ET->getOriginalDecl()->isScoped();
+ return ET->getDecl()->isScoped();
return false;
}
@@ -768,13 +768,13 @@ QualType Type::getPointeeType() const {
const RecordType *Type::getAsStructureType() const {
// If this is directly a structure type, return it.
if (const auto *RT = dyn_cast<RecordType>(this)) {
- if (RT->getOriginalDecl()->isStruct())
+ if (RT->getDecl()->isStruct())
return RT;
}
// If the canonical form of this type isn't the right kind, reject it.
if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) {
- if (!RT->getOriginalDecl()->isStruct())
+ if (!RT->getDecl()->isStruct())
return nullptr;
// If this is a typedef for a structure type, strip the typedef off without
@@ -787,13 +787,13 @@ const RecordType *Type::getAsStructureType() const {
const RecordType *Type::getAsUnionType() const {
// If this is directly a union type, return it.
if (const auto *RT = dyn_cast<RecordType>(this)) {
- if (RT->getOriginalDecl()->isUnion())
+ if (RT->getDecl()->isUnion())
return RT;
}
// If the canonical form of this type isn't the right kind, reject it.
if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) {
- if (!RT->getOriginalDecl()->isUnion())
+ if (!RT->getDecl()->isUnion())
return nullptr;
// If this is a typedef for a union type, strip the typedef off without
@@ -2107,7 +2107,7 @@ bool Type::isIntegralType(const ASTContext &Ctx) const {
// Complete enum types are integral in C.
if (!Ctx.getLangOpts().CPlusPlus)
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
- return IsEnumDeclComplete(ET->getOriginalDecl());
+ return IsEnumDeclComplete(ET->getDecl());
return isBitIntType();
}
@@ -2124,7 +2124,7 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
bool Type::isUnscopedEnumerationType() const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
- return !ET->getOriginalDecl()->isScoped();
+ return !ET->getDecl()->isScoped();
return false;
}
@@ -2328,7 +2328,7 @@ bool Type::isRealType() const {
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Ibm128;
if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
- const auto *ED = ET->getOriginalDecl();
+ const auto *ED = ET->getDecl();
return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete();
}
return isBitIntType();
@@ -2345,7 +2345,7 @@ bool Type::isArithmeticType() const {
// C++0x: Enumerations are not arithmetic types. For now, just return
// false for scoped enumerations since that will disable any
// unwanted implicit conversions.
- const auto *ED = ET->getOriginalDecl();
+ const auto *ED = ET->getDecl();
return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete();
}
return isa<ComplexType>(CanonicalType) || isBitIntType();
@@ -2410,8 +2410,7 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
/// includes union types.
bool Type::isAggregateType() const {
if (const auto *Record = dyn_cast<RecordType>(CanonicalType)) {
- if (const auto *ClassDecl =
- dyn_cast<CXXRecordDecl>(Record->getOriginalDecl()))
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl()))
return ClassDecl->isAggregate();
return true;
@@ -2746,8 +2745,8 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
return true;
case Type::Record:
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(
- cast<RecordType>(CanonicalType)->getOriginalDecl()))
+ if (const auto *ClassDecl =
+ dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl()))
return ClassDecl->isPOD();
// C struct/union is POD.
@@ -3179,7 +3178,7 @@ bool Type::isNothrowT() const {
bool Type::isAlignValT() const {
if (const auto *ET = getAsCanonical<EnumType>()) {
- const auto *ED = ET->getOriginalDecl();
+ const auto *ED = ET->getDecl();
IdentifierInfo *II = ED->getIdentifier();
if (II && II->isStr("align_val_t") && ED->isInStdNamespace())
return true;
@@ -3189,7 +3188,7 @@ bool Type::isAlignValT() const {
bool Type::isStdByteType() const {
if (const auto *ET = getAsCanonical<EnumType>()) {
- const auto *ED = ET->getOriginalDecl();
+ const auto *ED = ET->getDecl();
IdentifierInfo *II = ED->getIdentifier();
if (II && II->isStr("byte") && ED->isInStdNamespace())
return true;
@@ -4321,7 +4320,7 @@ bool RecordType::hasConstFields() const {
while (RecordTypeList.size() > NextToCheckIndex) {
for (FieldDecl *FD : RecordTypeList[NextToCheckIndex]
- ->getOriginalDecl()
+ ->getDecl()
->getDefinitionOrSelf()
->fields()) {
QualType FieldTy = FD->getType();
@@ -4815,8 +4814,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
case Type::Record:
case Type::Enum: {
- const TagDecl *Tag =
- cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf();
+ const auto *Tag = cast<TagType>(T)->getDecl()->getDefinitionOrSelf();
// C++ [basic.link]p8:
// - it is a class or enumeration type that is named (or has a name
@@ -4926,7 +4924,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
case Type::Record:
case Type::Enum:
return getDeclLinkageAndVisibility(
- cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf());
+ cast<TagType>(T)->getDecl()->getDefinitionOrSelf());
case Type::Complex:
return computeTypeLinkageInfo(cast<ComplexType>(T)->getElementType());
@@ -5129,7 +5127,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
llvm_unreachable("unknown builtin type");
case Type::Record: {
- const RecordDecl *RD = cast<RecordType>(type)->getOriginalDecl();
+ const auto *RD = cast<RecordType>(type)->getDecl();
// For template specializations, look only at primary template attributes.
// This is a consistent regardless of whether the instantiation is known.
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
@@ -5327,7 +5325,7 @@ bool Type::isCARCBridgableType() const {
/// Check if the specified type is the CUDA device builtin surface type.
bool Type::isCUDADeviceBuiltinSurfaceType() const {
if (const auto *RT = getAsCanonical<RecordType>())
- return RT->getOriginalDecl()
+ return RT->getDecl()
->getMostRecentDecl()
->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>();
return false;
@@ -5336,7 +5334,7 @@ bool Type::isCUDADeviceBuiltinSurfaceType() const {
/// Check if the specified type is the CUDA device builtin texture type.
bool Type::isCUDADeviceBuiltinTextureType() const {
if (const auto *RT = getAsCanonical<RecordType>())
- return RT->getOriginalDecl()
+ return RT->getDecl()
->getMostRecentDecl()
->hasAttr<CUDADeviceBuiltinTextureTypeAttr>();
return false;
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index e952e82..f54ccf0 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -303,8 +303,7 @@ bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
}
bool TagTypeLoc::isDefinition() const {
- return getTypePtr()->isTagOwned() &&
- getOriginalDecl()->isCompleteDefinition();
+ return getTypePtr()->isTagOwned() && getDecl()->isCompleteDefinition();
}
// Reimplemented to account for GNU/C++ extension
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 66a1b68..2da7789 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1421,7 +1421,7 @@ void TypePrinter::printDeducedTemplateSpecializationBefore(
} else {
// Should only get here for canonical types.
const auto *CD = cast<ClassTemplateSpecializationDecl>(
- cast<RecordType>(T->getDeducedType())->getOriginalDecl());
+ cast<RecordType>(T->getDeducedType())->getDecl());
DeducedTD = CD->getSpecializedTemplate();
Args = CD->getTemplateArgs().asArray();
}
@@ -1565,7 +1565,7 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
}
void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
- TagDecl *D = T->getOriginalDecl();
+ TagDecl *D = T->getDecl();
if (Policy.IncludeTagDefinition && T->isTagOwned()) {
D->print(OS, Policy, Indentation);
@@ -1669,11 +1669,11 @@ void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
// Print the preferred name if we have one for this type.
if (Policy.UsePreferredNames) {
- for (const auto *PNA : T->getOriginalDecl()
+ for (const auto *PNA : T->getDecl()
->getMostRecentDecl()
->specific_attrs<PreferredNameAttr>()) {
if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
- T->getOriginalDecl()))
+ T->getDecl()))
continue;
// Find the outermost typedef or alias template.
QualType T = PNA->getTypedefType();
@@ -1700,11 +1700,11 @@ void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
raw_ostream &OS) {
- const ASTContext &Ctx = T->getOriginalDecl()->getASTContext();
+ const ASTContext &Ctx = T->getDecl()->getASTContext();
IncludeStrongLifetimeRAII Strong(Policy);
T->getTemplateName(Ctx).print(OS, Policy);
if (Policy.PrintInjectedClassNameWithArguments) {
- auto *Decl = T->getOriginalDecl();
+ auto *Decl = T->getDecl();
// FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
// arguments.
if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index 6cec526..3ded3a5 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -312,13 +312,12 @@ ComputeReturnAdjustmentBaseOffset(ASTContext &Context,
return BaseOffset();
}
- const CXXRecordDecl *DerivedRD =
- cast<CXXRecordDecl>(
- cast<RecordType>(CanDerivedReturnType)->getOriginalDecl())
+ const auto *DerivedRD =
+ cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl())
->getDefinitionOrSelf();
- const CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(
- cast<RecordType>(CanBaseReturnType)->getOriginalDecl());
+ const auto *BaseRD =
+ cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl());
return ComputeBaseOffset(Context, BaseRD, DerivedRD);
}
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index a56fdb1..77750cf 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -2032,9 +2032,7 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
assert(inserted.second && "Are we visiting the same expression again?");
if (isa<CXXConstructExpr>(Exp))
Self = Placeholder;
- if (TagT->getOriginalDecl()
- ->getMostRecentDecl()
- ->hasAttr<ScopedLockableAttr>())
+ if (TagT->getDecl()->getMostRecentDecl()->hasAttr<ScopedLockableAttr>())
Scp = CapabilityExpr(Placeholder, Exp->getType(), /*Neg=*/false);
}
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index f034514..641a3db 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/LangStandard.h"
#include "llvm/Support/Path.h"
using namespace clang;
@@ -243,3 +244,46 @@ LLVM_DUMP_METHOD void FPOptionsOverride::dump() {
#include "clang/Basic/FPOptions.def"
llvm::errs() << "\n";
}
+
+std::optional<uint32_t> LangOptions::getCPlusPlusLangStd() const {
+ if (!CPlusPlus)
+ return std::nullopt;
+
+ LangStandard::Kind Std;
+ if (CPlusPlus26)
+ Std = LangStandard::lang_cxx26;
+ else if (CPlusPlus23)
+ Std = LangStandard::lang_cxx23;
+ else if (CPlusPlus20)
+ Std = LangStandard::lang_cxx20;
+ else if (CPlusPlus17)
+ Std = LangStandard::lang_cxx17;
+ else if (CPlusPlus14)
+ Std = LangStandard::lang_cxx14;
+ else if (CPlusPlus11)
+ Std = LangStandard::lang_cxx11;
+ else
+ Std = LangStandard::lang_cxx98;
+
+ return LangStandard::getLangStandardForKind(Std).getVersion();
+}
+
+std::optional<uint32_t> LangOptions::getCLangStd() const {
+ LangStandard::Kind Std;
+ if (C2y)
+ Std = LangStandard::lang_c2y;
+ else if (C23)
+ Std = LangStandard::lang_c23;
+ else if (C17)
+ Std = LangStandard::lang_c17;
+ else if (C11)
+ Std = LangStandard::lang_c11;
+ else if (C99)
+ Std = LangStandard::lang_c99;
+ else if (!GNUMode && Digraphs)
+ Std = LangStandard::lang_c94;
+ else
+ return std::nullopt;
+
+ return LangStandard::getLangStandardForKind(Std).getVersion();
+}
diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp
index c49d095..01c524b 100644
--- a/clang/lib/Basic/LangStandards.cpp
+++ b/clang/lib/Basic/LangStandards.cpp
@@ -46,16 +46,18 @@ StringRef clang::languageToString(Language L) {
llvm_unreachable("unhandled language kind");
}
-#define LANGSTANDARD(id, name, lang, desc, features) \
- static const LangStandard Lang_##id = {name, desc, features, Language::lang};
+#define LANGSTANDARD(id, name, lang, desc, features, version) \
+ static const LangStandard Lang_##id = {name, desc, features, Language::lang, \
+ version};
#include "clang/Basic/LangStandards.def"
const LangStandard &LangStandard::getLangStandardForKind(Kind K) {
switch (K) {
case lang_unspecified:
llvm::report_fatal_error("getLangStandardForKind() on unspecified kind");
-#define LANGSTANDARD(id, name, lang, desc, features) \
- case lang_##id: return Lang_##id;
+#define LANGSTANDARD(id, name, lang, desc, features, version) \
+ case lang_##id: \
+ return Lang_##id;
#include "clang/Basic/LangStandards.def"
}
llvm_unreachable("Invalid language kind!");
@@ -63,7 +65,8 @@ const LangStandard &LangStandard::getLangStandardForKind(Kind K) {
LangStandard::Kind LangStandard::getLangKind(StringRef Name) {
return llvm::StringSwitch<Kind>(Name)
-#define LANGSTANDARD(id, name, lang, desc, features) .Case(name, lang_##id)
+#define LANGSTANDARD(id, name, lang, desc, features, version) \
+ .Case(name, lang_##id)
#define LANGSTANDARD_ALIAS(id, alias) .Case(alias, lang_##id)
#include "clang/Basic/LangStandards.def"
.Default(lang_unspecified);
diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp
index bbe7b01..2673669 100644
--- a/clang/lib/Basic/Targets/AVR.cpp
+++ b/clang/lib/Basic/Targets/AVR.cpp
@@ -420,23 +420,23 @@ static MCUInfo AVRMcus[] = {
static bool ArchHasELPM(StringRef Arch) {
return llvm::StringSwitch<bool>(Arch)
- .Cases("31", "51", "6", true)
- .Cases("102", "104", "105", "106", "107", true)
- .Default(false);
+ .Cases({"31", "51", "6"}, true)
+ .Cases({"102", "104", "105", "106", "107"}, true)
+ .Default(false);
}
static bool ArchHasELPMX(StringRef Arch) {
return llvm::StringSwitch<bool>(Arch)
- .Cases("51", "6", true)
- .Cases("102", "104", "105", "106", "107", true)
- .Default(false);
+ .Cases({"51", "6"}, true)
+ .Cases({"102", "104", "105", "106", "107"}, true)
+ .Default(false);
}
static bool ArchHasMOVW(StringRef Arch) {
return llvm::StringSwitch<bool>(Arch)
- .Cases("25", "35", "4", "5", "51", "6", true)
- .Cases("102", "103", "104", "105", "106", "107", true)
- .Default(false);
+ .Cases({"25", "35", "4", "5", "51", "6"}, true)
+ .Cases({"102", "103", "104", "105", "106", "107"}, true)
+ .Default(false);
}
static bool ArchHasLPMX(StringRef Arch) {
@@ -445,16 +445,16 @@ static bool ArchHasLPMX(StringRef Arch) {
static bool ArchHasMUL(StringRef Arch) {
return llvm::StringSwitch<bool>(Arch)
- .Cases("4", "5", "51", "6", true)
- .Cases("102", "103", "104", "105", "106", "107", true)
- .Default(false);
+ .Cases({"4", "5", "51", "6"}, true)
+ .Cases({"102", "103", "104", "105", "106", "107"}, true)
+ .Default(false);
}
static bool ArchHasJMPCALL(StringRef Arch) {
return llvm::StringSwitch<bool>(Arch)
- .Cases("3", "31", "35", "5", "51", "6", true)
- .Cases("102", "103", "104", "105", "106", "107", true)
- .Default(false);
+ .Cases({"3", "31", "35", "5", "51", "6"}, true)
+ .Cases({"102", "103", "104", "105", "106", "107"}, true)
+ .Default(false);
}
static bool ArchHas3BytePC(StringRef Arch) {
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index bd13c9e..a21a593 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -64,8 +64,11 @@ public:
NoAsmVariants = true;
PlatformMinVersion = Triple.getOSVersion();
PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
+ // TODO: We need to align vectors on the element size generally, but for now
+ // we hard code this for 3-element 32- and 64-bit vectors as a workaround.
+ // See https://github.com/llvm/llvm-project/issues/123968
resetDataLayout("e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:"
- "32-f64:64-n8:16:32:64");
+ "32-f64:64-n8:16:32:64-v48:16:16-v96:32:32-v192:64:64");
TheCXXABI.set(TargetCXXABI::GenericItanium);
}
bool useFP16ConversionIntrinsics() const override { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index a6f10e6..84acc74 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -519,6 +519,14 @@ public:
return createGlobal(module, loc, uniqueName, type, isConstant, linkage);
}
+ cir::StackSaveOp createStackSave(mlir::Location loc, mlir::Type ty) {
+ return cir::StackSaveOp::create(*this, loc, ty);
+ }
+
+ cir::StackRestoreOp createStackRestore(mlir::Location loc, mlir::Value v) {
+ return cir::StackRestoreOp::create(*this, loc, v);
+ }
+
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType,
Address dstAddr, mlir::Type storageType,
mlir::Value src, const CIRGenBitFieldInfo &info,
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index dd357ce..89f4926 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -478,8 +478,7 @@ void CIRGenFunction::getVTablePointers(BaseSubobject base,
for (const auto &nextBase : rd->bases()) {
const auto *baseDecl =
- cast<CXXRecordDecl>(
- nextBase.getType()->castAs<RecordType>()->getOriginalDecl())
+ cast<CXXRecordDecl>(nextBase.getType()->castAs<RecordType>()->getDecl())
->getDefinitionOrSelf();
// Ignore classes without a vtable.
@@ -1025,7 +1024,7 @@ void CIRGenFunction::enterDtorCleanups(const CXXDestructorDecl *dd,
// Anonymous union members do not have their destructors called.
const RecordType *rt = type->getAsUnionType();
- if (rt && rt->getOriginalDecl()->isAnonymousStructOrUnion())
+ if (rt && rt->getDecl()->isAnonymousStructOrUnion())
continue;
CleanupKind cleanupKind = getCleanupKind(dtorKind);
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 039d290..4a19d91 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -44,38 +44,70 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
// If the type is variably-modified, emit all the VLA sizes for it.
if (ty->isVariablyModifiedType())
- cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: variably modified type");
+ emitVariablyModifiedType(ty);
assert(!cir::MissingFeatures::openMP());
Address address = Address::invalid();
- if (!ty->isConstantSizeType())
- cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: non-constant size type");
-
- // A normal fixed sized variable becomes an alloca in the entry block,
- // unless:
- // - it's an NRVO variable.
- // - we are compiling OpenMP and it's an OpenMP local variable.
- if (nrvo) {
- // The named return value optimization: allocate this variable in the
- // return slot, so that we can elide the copy when returning this
- // variable (C++0x [class.copy]p34).
- address = returnValue;
-
- if (const RecordDecl *rd = ty->getAsRecordDecl()) {
- if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);
- (cxxrd && !cxxrd->hasTrivialDestructor()) ||
- rd->isNonTrivialToPrimitiveDestroy())
- cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: set NRVO flag");
+ if (ty->isConstantSizeType()) {
+ // A normal fixed sized variable becomes an alloca in the entry block,
+ // unless:
+ // - it's an NRVO variable.
+ // - we are compiling OpenMP and it's an OpenMP local variable.
+ if (nrvo) {
+ // The named return value optimization: allocate this variable in the
+ // return slot, so that we can elide the copy when returning this
+ // variable (C++0x [class.copy]p34).
+ address = returnValue;
+
+ if (const RecordDecl *rd = ty->getAsRecordDecl()) {
+ if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);
+ (cxxrd && !cxxrd->hasTrivialDestructor()) ||
+ rd->isNonTrivialToPrimitiveDestroy())
+ cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: set NRVO flag");
+ }
+ } else {
+ // A normal fixed sized variable becomes an alloca in the entry block,
+ mlir::Type allocaTy = convertTypeForMem(ty);
+ // Create the temp alloca and declare variable using it.
+ address = createTempAlloca(allocaTy, alignment, loc, d.getName(),
+ /*arraySize=*/nullptr, /*alloca=*/nullptr, ip);
+ declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()),
+ alignment);
}
} else {
- // A normal fixed sized variable becomes an alloca in the entry block,
- mlir::Type allocaTy = convertTypeForMem(ty);
- // Create the temp alloca and declare variable using it.
- address = createTempAlloca(allocaTy, alignment, loc, d.getName(),
- /*arraySize=*/nullptr, /*alloca=*/nullptr, ip);
- declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()),
- alignment);
+ // Non-constant size type
+ assert(!cir::MissingFeatures::openMP());
+ if (!didCallStackSave) {
+ // Save the stack.
+ cir::PointerType defaultTy = AllocaInt8PtrTy;
+ CharUnits align = CharUnits::fromQuantity(
+ cgm.getDataLayout().getAlignment(defaultTy, false));
+ Address stack = createTempAlloca(defaultTy, align, loc, "saved_stack");
+
+ mlir::Value v = builder.createStackSave(loc, defaultTy);
+ assert(v.getType() == AllocaInt8PtrTy);
+ builder.createStore(loc, v, stack);
+
+ didCallStackSave = true;
+
+ // Push a cleanup block and restore the stack there.
+ // FIXME: in general circumstances, this should be an EH cleanup.
+ pushStackRestore(NormalCleanup, stack);
+ }
+
+ VlaSizePair vlaSize = getVLASize(ty);
+ mlir::Type memTy = convertTypeForMem(vlaSize.type);
+
+ // Allocate memory for the array.
+ address =
+ createTempAlloca(memTy, alignment, loc, d.getName(), vlaSize.numElts,
+ /*alloca=*/nullptr, builder.saveInsertionPoint());
+
+ // If we have debug info enabled, properly describe the VLA dimensions for
+ // this type by registering the vla size expression for each of the
+ // dimensions.
+ assert(!cir::MissingFeatures::generateDebugInfo());
}
emission.addr = address;
@@ -696,6 +728,16 @@ struct DestroyObject final : EHScopeStack::Cleanup {
cgf.emitDestroy(addr, type, destroyer);
}
};
+
+struct CallStackRestore final : EHScopeStack::Cleanup {
+ Address stack;
+ CallStackRestore(Address stack) : stack(stack) {}
+ void emit(CIRGenFunction &cgf) override {
+ mlir::Location loc = stack.getPointer().getLoc();
+ mlir::Value v = cgf.getBuilder().createLoad(loc, stack);
+ cgf.getBuilder().createStackRestore(loc, v);
+ }
+};
} // namespace
void CIRGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr,
@@ -805,6 +847,10 @@ CIRGenFunction::getDestroyer(QualType::DestructionKind kind) {
llvm_unreachable("Unknown DestructionKind");
}
+void CIRGenFunction::pushStackRestore(CleanupKind kind, Address spMem) {
+ ehStack.pushCleanup<CallStackRestore>(kind, spMem);
+}
+
/// Enter a destroy cleanup for the given local variable.
void CIRGenFunction::emitAutoVarTypeCleanup(
const CIRGenFunction::AutoVarEmission &emission,
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index f416571..4897c29 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2068,7 +2068,7 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
mlir::OpBuilder::InsertionGuard guard(builder);
builder.restoreInsertionPoint(ip);
addr = builder.createAlloca(loc, /*addr type*/ localVarPtrTy,
- /*var type*/ ty, name, alignIntAttr);
+ /*var type*/ ty, name, alignIntAttr, arraySize);
assert(!cir::MissingFeatures::astVarDeclInterface());
}
return addr;
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 89e9ec4..81e5fe2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -614,7 +614,7 @@ bool ConstRecordBuilder::applyZeroInitPadding(const ASTRecordLayout &layout,
bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) {
RecordDecl *rd = ile->getType()
->castAs<clang::RecordType>()
- ->getOriginalDecl()
+ ->getDecl()
->getDefinitionOrSelf();
const ASTRecordLayout &layout = cgm.getASTContext().getASTRecordLayout(rd);
@@ -817,9 +817,8 @@ bool ConstRecordBuilder::build(const APValue &val, const RecordDecl *rd,
mlir::Attribute ConstRecordBuilder::finalize(QualType type) {
type = type.getNonReferenceType();
- RecordDecl *rd = type->castAs<clang::RecordType>()
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
+ RecordDecl *rd =
+ type->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();
mlir::Type valTy = cgm.convertType(type);
return builder.build(valTy, rd->hasFlexibleArrayMember());
}
@@ -842,9 +841,8 @@ mlir::Attribute ConstRecordBuilder::buildRecord(ConstantEmitter &emitter,
ConstantAggregateBuilder constant(emitter.cgm);
ConstRecordBuilder builder(emitter, constant, CharUnits::Zero());
- const RecordDecl *rd = valTy->castAs<clang::RecordType>()
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
+ const RecordDecl *rd =
+ valTy->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf();
const CXXRecordDecl *cd = dyn_cast<CXXRecordDecl>(rd);
if (!builder.build(val, rd, false, cd, CharUnits::Zero()))
return nullptr;
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 01a43a99..ba36cbe 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -410,6 +410,8 @@ void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType,
curFn = fn;
const Decl *d = gd.getDecl();
+
+ didCallStackSave = false;
curCodeDecl = d;
const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
curFuncDecl = d->getNonClosureContext();
@@ -1006,6 +1008,41 @@ mlir::Value CIRGenFunction::emitAlignmentAssumption(
offsetValue);
}
+CIRGenFunction::VlaSizePair CIRGenFunction::getVLASize(QualType type) {
+ const VariableArrayType *vla =
+ cgm.getASTContext().getAsVariableArrayType(type);
+ assert(vla && "type was not a variable array type!");
+ return getVLASize(vla);
+}
+
+CIRGenFunction::VlaSizePair
+CIRGenFunction::getVLASize(const VariableArrayType *type) {
+ // The number of elements so far; always size_t.
+ mlir::Value numElements;
+
+ QualType elementType;
+ do {
+ elementType = type->getElementType();
+ mlir::Value vlaSize = vlaSizeMap[type->getSizeExpr()];
+ assert(vlaSize && "no size for VLA!");
+ assert(vlaSize.getType() == SizeTy);
+
+ if (!numElements) {
+ numElements = vlaSize;
+ } else {
+ // It's undefined behavior if this wraps around, so mark it that way.
+ // FIXME: Teach -fsanitize=undefined to trap this.
+
+ numElements =
+ builder.createMul(numElements.getLoc(), numElements, vlaSize,
+ cir::OverflowBehavior::NoUnsignedWrap);
+ }
+ } while ((type = getContext().getAsVariableArrayType(elementType)));
+
+ assert(numElements && "Undefined elements number");
+ return {numElements, elementType};
+}
+
// TODO(cir): Most of this function can be shared between CIRGen
// and traditional LLVM codegen
void CIRGenFunction::emitVariablyModifiedType(QualType type) {
@@ -1086,7 +1123,26 @@ void CIRGenFunction::emitVariablyModifiedType(QualType type) {
break;
case Type::VariableArray: {
- cgm.errorNYI("CIRGenFunction::emitVariablyModifiedType VLA");
+ // Losing element qualification here is fine.
+ const VariableArrayType *vat = cast<clang::VariableArrayType>(ty);
+
+ // Unknown size indication requires no size computation.
+ // Otherwise, evaluate and record it.
+ if (const Expr *sizeExpr = vat->getSizeExpr()) {
+ // It's possible that we might have emitted this already,
+ // e.g. with a typedef and a pointer to it.
+ mlir::Value &entry = vlaSizeMap[sizeExpr];
+ if (!entry) {
+ mlir::Value size = emitScalarExpr(sizeExpr);
+ assert(!cir::MissingFeatures::sanitizers());
+
+ // Always zexting here would be wrong if it weren't
+ // undefined behavior to have a negative bound.
+ // FIXME: What about when size's type is larger than size_t?
+ entry = builder.createIntCast(size, SizeTy);
+ }
+ }
+ type = vat->getElementType();
break;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index d71de2f..0d64c31 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -149,6 +149,10 @@ public:
using SymTableTy = llvm::ScopedHashTable<const clang::Decl *, mlir::Value>;
SymTableTy symbolTable;
+ /// Whether a cir.stacksave operation has been added. Used to avoid
+ /// inserting cir.stacksave for multiple VLAs in the same scope.
+ bool didCallStackSave = false;
+
/// Whether or not a Microsoft-style asm block has been processed within
/// this fuction. These can potentially set the return value.
bool sawAsmBlock = false;
@@ -188,6 +192,14 @@ public:
llvm::DenseMap<const OpaqueValueExpr *, LValue> opaqueLValues;
llvm::DenseMap<const OpaqueValueExpr *, RValue> opaqueRValues;
+ // This keeps track of the associated size for each VLA type.
+ // We track this by the size expression rather than the type itself because
+ // in certain situations, like a const qualifier applied to an VLA typedef,
+ // multiple VLA types can share the same size expression.
+ // FIXME: Maybe this could be a stack of maps that is pushed/popped as we
+ // enter/leave scopes.
+ llvm::DenseMap<const Expr *, mlir::Value> vlaSizeMap;
+
public:
/// A non-RAII class containing all the information about a bound
/// opaque value. OpaqueValueMapping, below, is a RAII wrapper for
@@ -436,6 +448,20 @@ public:
}
};
+ struct VlaSizePair {
+ mlir::Value numElts;
+ QualType type;
+
+ VlaSizePair(mlir::Value num, QualType ty) : numElts(num), type(ty) {}
+ };
+
+ /// Returns an MLIR::Value+QualType pair that corresponds to the size,
+ /// in non-variably-sized elements, of a variable length array type,
+ /// plus that largest non-variably-sized element type. Assumes that
+ /// the type has already been emitted with emitVariablyModifiedType.
+ VlaSizePair getVLASize(const VariableArrayType *type);
+ VlaSizePair getVLASize(QualType type);
+
void finishFunction(SourceLocation endLoc);
/// Determine whether the given initializer is trivial in the sense
@@ -583,6 +609,8 @@ public:
return needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup;
}
+ void pushStackRestore(CleanupKind kind, Address spMem);
+
/// Set the address of a local variable.
void setAddrOfLocalVar(const clang::VarDecl *vd, Address addr) {
assert(!localDeclMap.count(vd) && "Decl already exists in LocalDeclMap!");
@@ -854,6 +882,7 @@ public:
protected:
bool performCleanup;
+ bool oldDidCallStackSave;
private:
RunCleanupsScope(const RunCleanupsScope &) = delete;
@@ -867,6 +896,8 @@ public:
explicit RunCleanupsScope(CIRGenFunction &cgf)
: performCleanup(true), cgf(cgf) {
cleanupStackDepth = cgf.ehStack.stable_begin();
+ oldDidCallStackSave = cgf.didCallStackSave;
+ cgf.didCallStackSave = false;
oldCleanupStackDepth = cgf.currentCleanupStackDepth;
cgf.currentCleanupStackDepth = cleanupStackDepth;
}
@@ -883,6 +914,7 @@ public:
assert(performCleanup && "Already forced cleanup");
{
mlir::OpBuilder::InsertionGuard guard(cgf.getBuilder());
+ cgf.didCallStackSave = oldDidCallStackSave;
cgf.popCleanupBlocks(cleanupStackDepth);
performCleanup = false;
cgf.currentCleanupStackDepth = oldCleanupStackDepth;
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index d30c975..1b85a53 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -744,8 +744,8 @@ static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
return false;
if (const auto *recordTy = dyn_cast<RecordType>(ty)) {
- const CXXRecordDecl *rd =
- cast<CXXRecordDecl>(recordTy->getOriginalDecl())->getDefinitionOrSelf();
+ const auto *rd =
+ cast<CXXRecordDecl>(recordTy->getDecl())->getDefinitionOrSelf();
if (!rd->hasDefinition())
return false;
@@ -859,9 +859,7 @@ static bool canUseSingleInheritance(const CXXRecordDecl *rd) {
/// IsIncompleteClassType - Returns whether the given record type is incomplete.
static bool isIncompleteClassType(const RecordType *recordTy) {
- return !recordTy->getOriginalDecl()
- ->getDefinitionOrSelf()
- ->isCompleteDefinition();
+ return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
}
/// Returns whether the given type contains an
@@ -939,8 +937,7 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
case Type::Atomic:
// FIXME: GCC treats block pointers as fundamental types?!
case Type::BlockPointer:
- cgm.errorNYI("VTableClassNameForType: __fundamental_type_info");
- break;
+ return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
@@ -957,9 +954,8 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
break;
case Type::Record: {
- const CXXRecordDecl *rd =
- cast<CXXRecordDecl>(cast<RecordType>(ty)->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *rd = cast<CXXRecordDecl>(cast<RecordType>(ty)->getDecl())
+ ->getDefinitionOrSelf();
if (!rd->hasDefinition() || !rd->getNumBases()) {
return classTypeInfo;
@@ -1031,8 +1027,8 @@ static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm,
return cir::GlobalLinkageKind::LinkOnceODRLinkage;
if (const RecordType *record = dyn_cast<RecordType>(ty)) {
- const CXXRecordDecl *rd =
- cast<CXXRecordDecl>(record->getOriginalDecl())->getDefinitionOrSelf();
+ const auto *rd =
+ cast<CXXRecordDecl>(record->getDecl())->getDefinitionOrSelf();
if (rd->hasAttr<WeakAttr>())
return cir::GlobalLinkageKind::WeakODRLinkage;
@@ -1382,9 +1378,8 @@ mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
break;
case Type::Record: {
- const auto *rd =
- cast<CXXRecordDecl>(cast<RecordType>(ty)->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *rd = cast<CXXRecordDecl>(cast<RecordType>(ty)->getDecl())
+ ->getDefinitionOrSelf();
if (!rd->hasDefinition() || !rd->getNumBases()) {
// We don't need to emit any fields.
break;
@@ -1651,8 +1646,7 @@ void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
// Lowering pass to skip passing the trivial function.
//
if (const RecordType *recordTy = clangThrowType->getAs<RecordType>()) {
- CXXRecordDecl *rec =
- cast<CXXRecordDecl>(recordTy->getOriginalDecl()->getDefinition());
+ auto *rec = cast<CXXRecordDecl>(recordTy->getDecl()->getDefinition());
assert(!cir::MissingFeatures::isTrivialCtorOrDtor());
if (!rec->hasTrivialDestructor()) {
cgm.errorNYI("emitThrow: non-trivial destructor");
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 82b1051..57c7a44 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -88,6 +88,8 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
FP80Ty = cir::FP80Type::get(&getMLIRContext());
FP128Ty = cir::FP128Type::get(&getMLIRContext());
+ AllocaInt8PtrTy = cir::PointerType::get(UInt8Ty, cirAllocaAddressSpace);
+
PointerAlignInBytes =
astContext
.toCharUnitsFromBits(
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp
index ce14aa8..f638d39 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp
@@ -398,6 +398,7 @@ void OpenACCRecipeBuilderBase::createRecipeDestroySection(
emitDestroy(block->getArgument(1), elementTy);
}
+ ls.forceCleanup();
mlir::acc::YieldOp::create(builder, locEnd);
}
void OpenACCRecipeBuilderBase::makeBoundsInit(
@@ -480,6 +481,7 @@ void OpenACCRecipeBuilderBase::createInitRecipe(
/*isInitSection=*/true);
}
+ ls.forceCleanup();
mlir::acc::YieldOp::create(builder, locEnd);
}
@@ -518,6 +520,7 @@ void OpenACCRecipeBuilderBase::createFirstprivateRecipeCopy(
cgf.emitAutoVarInit(tempDeclEmission);
builder.setInsertionPointToEnd(&copyRegion.back());
+ ls.forceCleanup();
mlir::acc::YieldOp::create(builder, locEnd);
}
@@ -662,6 +665,7 @@ void OpenACCRecipeBuilderBase::createReductionRecipeCombiner(
}
builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back());
+ ls.forceCleanup();
mlir::acc::YieldOp::create(builder, locEnd, block->getArgument(0));
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
index 273ec7f..b5612d9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
+++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
@@ -65,6 +65,9 @@ struct CIRGenTypeCache {
cir::PointerType VoidPtrTy;
cir::PointerType UInt8PtrTy;
+ /// void* in alloca address space
+ cir::PointerType AllocaInt8PtrTy;
+
/// The size and alignment of a pointer into the generic address space.
union {
unsigned char PointerAlignInBytes;
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 2ab1ea0c..d1b91d0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -159,7 +159,7 @@ isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt,
for (const clang::CXXBaseSpecifier &i : crd->bases())
if (!isSafeToConvert(i.getType()
->castAs<RecordType>()
- ->getOriginalDecl()
+ ->getDecl()
->getDefinitionOrSelf(),
cgt, alreadyChecked))
return false;
@@ -279,8 +279,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
// Process record types before the type cache lookup.
if (const auto *recordType = dyn_cast<RecordType>(type))
- return convertRecordDeclType(
- recordType->getOriginalDecl()->getDefinitionOrSelf());
+ return convertRecordDeclType(recordType->getDecl()->getDefinitionOrSelf());
// Has the type already been processed?
TypeCacheTy::iterator tci = typeCache.find(ty);
@@ -421,6 +420,16 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
break;
}
+ case Type::VariableArray: {
+ const VariableArrayType *a = cast<VariableArrayType>(ty);
+ if (a->getIndexTypeCVRQualifiers() != 0)
+ cgm.errorNYI(SourceLocation(), "non trivial array types", type);
+ // VLAs resolve to the innermost element type; this matches
+ // the return of alloca, and there isn't any obviously better choice.
+ resultType = convertTypeForMem(a->getElementType());
+ break;
+ }
+
case Type::IncompleteArray: {
const IncompleteArrayType *arrTy = cast<IncompleteArrayType>(ty);
if (arrTy->getIndexTypeCVRQualifiers() != 0)
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 3abba3d..e61b65f 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1793,12 +1793,20 @@ CIRToLLVMGlobalOpLowering::getComdatAttr(cir::GlobalOp &op,
if (!comdatOp) {
builder.setInsertionPointToStart(module.getBody());
comdatOp =
- builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName);
+ mlir::LLVM::ComdatOp::create(builder, module.getLoc(), comdatName);
+ }
+
+ if (auto comdatSelector = comdatOp.lookupSymbol<mlir::LLVM::ComdatSelectorOp>(
+ op.getSymName())) {
+ return mlir::SymbolRefAttr::get(
+ builder.getContext(), comdatName,
+ mlir::FlatSymbolRefAttr::get(comdatSelector.getSymNameAttr()));
}
builder.setInsertionPointToStart(&comdatOp.getBody().back());
- auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>(
- comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any);
+ auto selectorOp = mlir::LLVM::ComdatSelectorOp::create(
+ builder, comdatOp.getLoc(), op.getSymName(),
+ mlir::LLVM::comdat::Comdat::Any);
return mlir::SymbolRefAttr::get(
builder.getContext(), comdatName,
mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr()));
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index 13c837a..1e3ac2e 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -105,7 +105,7 @@ llvm::Type *CodeGen::getVAListElementType(CodeGenFunction &CGF) {
CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(const RecordType *RT,
CGCXXABI &CXXABI) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
return CXXABI.getRecordArgABI(CXXRD);
if (!RD->canPassInRegisters())
@@ -136,7 +136,7 @@ bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI,
QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) {
if (const RecordType *UT = Ty->getAsUnionType()) {
- const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf();
if (UD->hasAttr<TransparentUnionAttr>()) {
assert(!UD->field_empty() && "sema created an empty transparent union");
return UD->field_begin()->getType();
@@ -274,7 +274,7 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
// according to the Itanium ABI. The exception applies only to records,
// not arrays of records, so we must also check whether we stripped off an
// array type above.
- if (isa<CXXRecordDecl>(RT->getOriginalDecl()) &&
+ if (isa<CXXRecordDecl>(RT->getDecl()) &&
(WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr<NoUniqueAddressAttr>())))
return false;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index f8e8086..6020684 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1200,7 +1200,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
}
}
- if (shouldEmitUnifiedLTOModueFlag())
+ if (shouldEmitUnifiedLTOModueFlag() &&
+ !TheModule->getModuleFlag("UnifiedLTO"))
TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
}
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index df28641..741fa44 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1896,7 +1896,7 @@ bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context,
// complex destructor or a non-trivially copyable type.
if (const RecordType *RT =
ReturnType.getCanonicalType()->getAsCanonical<RecordType>()) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
return ClassDecl->hasTrivialDestructor();
}
return ReturnType.isTriviallyCopyableType(Context);
@@ -3853,7 +3853,7 @@ static void setUsedBits(CodeGenModule &CGM, const RecordType *RTy, int Offset,
SmallVectorImpl<uint64_t> &Bits) {
ASTContext &Context = CGM.getContext();
int CharWidth = Context.getCharWidth();
- const RecordDecl *RD = RTy->getOriginalDecl()->getDefinition();
+ const RecordDecl *RD = RTy->getDecl()->getDefinition();
const ASTRecordLayout &ASTLayout = Context.getASTRecordLayout(RD);
const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD);
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index f31f0a2..f782b0c 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2026,7 +2026,7 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
// Anonymous union members do not have their destructors called.
const RecordType *RT = type->getAsUnionType();
- if (RT && RT->getOriginalDecl()->isAnonymousStructOrUnion())
+ if (RT && RT->getDecl()->isAnonymousStructOrUnion())
continue;
CleanupKind cleanupKind = getCleanupKind(dtorKind);
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 9fe9a13..12e2813ef 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -647,6 +647,68 @@ StringRef CGDebugInfo::getCurrentDirname() {
return CGM.getCodeGenOpts().DebugCompilationDir;
}
+static llvm::dwarf::SourceLanguage GetSourceLanguage(const CodeGenModule &CGM) {
+ const CodeGenOptions &CGO = CGM.getCodeGenOpts();
+ const LangOptions &LO = CGM.getLangOpts();
+
+ assert(CGO.DwarfVersion <= 5);
+
+ llvm::dwarf::SourceLanguage LangTag;
+ if (LO.CPlusPlus) {
+ if (LO.ObjC)
+ LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
+ else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
+ else if (LO.CPlusPlus14)
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
+ else if (LO.CPlusPlus11)
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
+ else
+ LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
+ } else if (LO.ObjC) {
+ LangTag = llvm::dwarf::DW_LANG_ObjC;
+ } else if (LO.OpenCL && (!CGO.DebugStrictDwarf || CGO.DwarfVersion >= 5)) {
+ LangTag = llvm::dwarf::DW_LANG_OpenCL;
+ } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
+ LangTag = llvm::dwarf::DW_LANG_C11;
+ } else if (LO.C99) {
+ LangTag = llvm::dwarf::DW_LANG_C99;
+ } else {
+ LangTag = llvm::dwarf::DW_LANG_C89;
+ }
+
+ return LangTag;
+}
+
+static llvm::DISourceLanguageName
+GetDISourceLanguageName(const CodeGenModule &CGM) {
+ // Emit pre-DWARFv6 language codes.
+ if (CGM.getCodeGenOpts().DwarfVersion < 6)
+ return llvm::DISourceLanguageName(GetSourceLanguage(CGM));
+
+ const LangOptions &LO = CGM.getLangOpts();
+
+ uint32_t LangVersion = 0;
+ llvm::dwarf::SourceLanguageName LangTag;
+ if (LO.CPlusPlus) {
+ if (LO.ObjC) {
+ LangTag = llvm::dwarf::DW_LNAME_ObjC_plus_plus;
+ } else {
+ LangTag = llvm::dwarf::DW_LNAME_C_plus_plus;
+ LangVersion = LO.getCPlusPlusLangStd().value_or(0);
+ }
+ } else if (LO.ObjC) {
+ LangTag = llvm::dwarf::DW_LNAME_ObjC;
+ } else if (LO.OpenCL) {
+ LangTag = llvm::dwarf::DW_LNAME_OpenCL_C;
+ } else {
+ LangTag = llvm::dwarf::DW_LNAME_C;
+ LangVersion = LO.getCLangStd().value_or(0);
+ }
+
+ return llvm::DISourceLanguageName(LangTag, LangVersion);
+}
+
void CGDebugInfo::CreateCompileUnit() {
SmallString<64> Checksum;
std::optional<llvm::DIFile::ChecksumKind> CSKind;
@@ -702,31 +764,6 @@ void CGDebugInfo::CreateCompileUnit() {
}
}
- llvm::dwarf::SourceLanguage LangTag;
- if (LO.CPlusPlus) {
- if (LO.ObjC)
- LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
- else if (CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
- else if (LO.CPlusPlus14)
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus_14;
- else if (LO.CPlusPlus11)
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus_11;
- else
- LangTag = llvm::dwarf::DW_LANG_C_plus_plus;
- } else if (LO.ObjC) {
- LangTag = llvm::dwarf::DW_LANG_ObjC;
- } else if (LO.OpenCL && (!CGM.getCodeGenOpts().DebugStrictDwarf ||
- CGM.getCodeGenOpts().DwarfVersion >= 5)) {
- LangTag = llvm::dwarf::DW_LANG_OpenCL;
- } else if (LO.C11 && !(CGO.DebugStrictDwarf && CGO.DwarfVersion < 5)) {
- LangTag = llvm::dwarf::DW_LANG_C11;
- } else if (LO.C99) {
- LangTag = llvm::dwarf::DW_LANG_C99;
- } else {
- LangTag = llvm::dwarf::DW_LANG_C89;
- }
-
std::string Producer = getClangFullVersion();
// Figure out which version of the ObjC runtime we have.
@@ -787,7 +824,7 @@ void CGDebugInfo::CreateCompileUnit() {
// Create new compile unit.
TheCU = DBuilder.createCompileUnit(
- llvm::DISourceLanguageName(LangTag), CUFile,
+ GetDISourceLanguageName(CGM), CUFile,
CGOpts.EmitVersionIdentMetadata ? Producer : "",
CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
CGOpts.PrepareForThinLTO,
@@ -1234,20 +1271,46 @@ llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,
Ty->getPointeeType(), Unit);
}
-/// \return whether a C++ mangling exists for the type defined by TD.
-static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) {
- switch (TheCU->getSourceLanguage().getUnversionedName()) {
+static bool hasCXXMangling(llvm::dwarf::SourceLanguage Lang, bool IsTagDecl) {
+ switch (Lang) {
case llvm::dwarf::DW_LANG_C_plus_plus:
case llvm::dwarf::DW_LANG_C_plus_plus_11:
case llvm::dwarf::DW_LANG_C_plus_plus_14:
return true;
case llvm::dwarf::DW_LANG_ObjC_plus_plus:
- return isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
+ return IsTagDecl;
+ default:
+ return false;
+ }
+}
+
+static bool hasCXXMangling(llvm::dwarf::SourceLanguageName Lang,
+ bool IsTagDecl) {
+ switch (Lang) {
+ case llvm::dwarf::DW_LNAME_C_plus_plus:
+ return true;
+ case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
+ return IsTagDecl;
default:
return false;
}
}
+/// \return whether a C++ mangling exists for the type defined by TD.
+static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) {
+ const bool IsTagDecl = isa<CXXRecordDecl>(TD) || isa<EnumDecl>(TD);
+
+ if (llvm::DISourceLanguageName SourceLang = TheCU->getSourceLanguage();
+ SourceLang.hasVersionedName())
+ return hasCXXMangling(
+ static_cast<llvm::dwarf::SourceLanguageName>(SourceLang.getName()),
+ IsTagDecl);
+ else
+ return hasCXXMangling(
+ static_cast<llvm::dwarf::SourceLanguage>(SourceLang.getName()),
+ IsTagDecl);
+}
+
// Determines if the debug info for this tag declaration needs a type
// identifier. The purpose of the unique identifier is to deduplicate type
// information for identical types across TUs. Because of the C++ one definition
@@ -1290,7 +1353,7 @@ static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM,
static SmallString<256> getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM,
llvm::DICompileUnit *TheCU) {
SmallString<256> Identifier;
- const TagDecl *TD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ const TagDecl *TD = Ty->getDecl()->getDefinitionOrSelf();
if (!needsTypeIdentifier(TD, CGM, TheCU))
return Identifier;
@@ -1326,7 +1389,7 @@ static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) {
llvm::DICompositeType *
CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,
llvm::DIScope *Ctx) {
- const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
return cast<llvm::DICompositeType>(T);
llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
@@ -2402,7 +2465,7 @@ void CGDebugInfo::CollectCXXBasesAux(
for (const auto &BI : Bases) {
const auto *Base =
cast<CXXRecordDecl>(
- BI.getType()->castAsCanonical<RecordType>()->getOriginalDecl())
+ BI.getType()->castAsCanonical<RecordType>()->getDecl())
->getDefinition();
if (!SeenTypes.insert(Base).second)
continue;
@@ -3077,7 +3140,7 @@ void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
}
llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) {
- RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(QualType(Ty, 0)));
if (T || shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD,
CGM.getLangOpts())) {
@@ -3105,7 +3168,7 @@ llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD,
std::pair<llvm::DIType *, llvm::DIType *>
CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
- RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
// Get overall information about the record type for the debug info.
llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
@@ -3748,7 +3811,7 @@ llvm::DIType *CGDebugInfo::CreateType(const HLSLInlineSpirvType *Ty,
static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU,
const EnumType *Ty) {
- const EnumDecl *ED = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ const EnumDecl *ED = Ty->getDecl()->getDefinitionOrSelf();
uint64_t Size = 0;
uint32_t Align = 0;
@@ -4151,7 +4214,7 @@ CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty) {
// TODO: Currently used for context chains when limiting debug info.
llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
- RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
// Get overall information about the record type for the debug info.
StringRef RDName = getClassName(RD);
@@ -4238,8 +4301,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
break;
}
- if (auto *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(Ty->getOriginalDecl())) {
+ if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) {
CXXRecordDecl *TemplateDecl =
CTSD->getSpecializedTemplate()->getTemplatedDecl();
RegionMap[TemplateDecl].reset(RealDecl);
@@ -5141,7 +5203,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
} else if (const auto *RT = dyn_cast<RecordType>(VD->getType())) {
// If VD is an anonymous union then Storage represents value for
// all union fields.
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
if (RD->isUnion() && RD->isAnonymousStructOrUnion()) {
// GDB has trouble finding local variables in anonymous unions, so we emit
// artificial local variables for each of the members.
@@ -5691,9 +5753,8 @@ llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
// Ignore unnamed fields, but recurse into anonymous records.
if (FieldName.empty()) {
if (const auto *RT = dyn_cast<RecordType>(Field->getType()))
- GVE =
- CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
- Unit, LineNo, LinkageName, Var, DContext);
+ GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit,
+ LineNo, LinkageName, Var, DContext);
continue;
}
// Use VarDecl's Tag, Scope and Line number.
@@ -5712,7 +5773,7 @@ static bool ReferencesAnonymousEntity(RecordType *RT) {
// But so long as it's not one of those, it doesn't matter if some sub-type
// of the record (a template parameter) can't be reconstituted - because the
// un-reconstitutable type itself will carry its own name.
- const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
+ const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
if (!RD)
return false;
if (!RD->getIdentifier())
@@ -5774,7 +5835,7 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
bool TraverseEnumType(EnumType *ET, bool = false) {
// Unnamed enums can't be reconstituted due to a lack of column info we
// produce in the DWARF, so we can't get Clang's full name back.
- if (const auto *ED = dyn_cast<EnumDecl>(ET->getOriginalDecl())) {
+ if (const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
if (!ED->getIdentifier()) {
Reconstitutable = false;
return false;
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e8255b0..8439ec7 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2011,7 +2011,7 @@ static bool isConstantEmittableObjectType(QualType type) {
// Otherwise, all object types satisfy this except C++ classes with
// mutable subobjects or non-trivial copy/destroy behavior.
if (const auto *RT = dyn_cast<RecordType>(type))
- if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
RD = RD->getDefinitionOrSelf();
if (RD->hasMutableFields() || !RD->isTrivial())
return false;
@@ -4564,7 +4564,7 @@ static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) {
const auto *PointeeT = PtrT->getPointeeType()
->getUnqualifiedDesugaredType();
if (const auto *RecT = dyn_cast<RecordType>(PointeeT))
- return RecT->getOriginalDecl()
+ return RecT->getDecl()
->getMostRecentDecl()
->hasAttr<BPFPreserveAccessIndexAttr>();
return false;
@@ -7008,7 +7008,7 @@ void CodeGenFunction::FlattenAccessAndTypeLValue(
WorkList.emplace_back(LVal, CAT->getElementType(), IdxListCopy);
}
} else if (const auto *RT = dyn_cast<RecordType>(T)) {
- const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *Record = RT->getDecl()->getDefinitionOrSelf();
assert(!Record->isUnion() && "Union types not supported in flat cast.");
const CXXRecordDecl *CXXD = dyn_cast<CXXRecordDecl>(Record);
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 07b9aeb..eee397f 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -2080,7 +2080,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
// referencee. InitListExprs for unions and arrays can't have references.
if (const RecordType *RT = E->getType()->getAsCanonical<RecordType>()) {
if (!RT->isUnionType()) {
- RecordDecl *SD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *SD = RT->getDecl()->getDefinitionOrSelf();
CharUnits NumNonZeroBytes = CharUnits::Zero();
unsigned ILEElement = 0;
@@ -2133,7 +2133,7 @@ static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E,
if (const RecordType *RT = CGF.getContext()
.getBaseElementType(E->getType())
->getAsCanonical<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getOriginalDecl());
+ const auto *RD = cast<CXXRecordDecl>(RT->getDecl());
if (RD->hasUserDeclaredConstructor())
return;
}
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 31ac266..14d8db3 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1236,8 +1236,8 @@ void CodeGenFunction::EmitNewArrayInitializer(
if (auto *ILE = dyn_cast<InitListExpr>(Init)) {
if (const RecordType *RType =
ILE->getType()->getAsCanonical<RecordType>()) {
- if (RType->getOriginalDecl()->isStruct()) {
- const RecordDecl *RD = RType->getOriginalDecl()->getDefinitionOrSelf();
+ if (RType->getDecl()->isStruct()) {
+ const RecordDecl *RD = RType->getDecl()->getDefinitionOrSelf();
unsigned NumElements = 0;
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
NumElements = CXXRD->getNumBases();
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 715160d..714192d 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3583,7 +3583,7 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
}
const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(
- CurrentType->castAsCanonical<RecordType>()->getOriginalDecl());
+ CurrentType->castAsCanonical<RecordType>()->getDecl());
// Save the element type.
CurrentType = ON.getBase()->getType();
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 603cef9..ecab933 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -519,6 +519,10 @@ void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes(
if (CGM.getCodeGenOpts().OptimizationLevel == 0)
Fn->addFnAttr(llvm::Attribute::OptimizeNone);
Fn->addFnAttr(llvm::Attribute::NoInline);
+
+ if (CGM.getLangOpts().HLSLSpvEnableMaximalReconvergence) {
+ Fn->addFnAttr("enable-maximal-reconvergence", "true");
+ }
}
static Value *buildVectorInput(IRBuilder<> &B, Function *F, llvm::Type *Ty) {
diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
index 2d70e4c..0a383c8 100644
--- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -464,8 +464,7 @@ template <class Derived> struct GenFuncBase {
if (WrongType) {
std::string FuncName = std::string(F->getName());
- SourceLocation Loc =
- QT->castAs<RecordType>()->getOriginalDecl()->getLocation();
+ SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
CGM.Error(Loc, "special function " + FuncName +
" for non-trivial C struct has incorrect type");
return nullptr;
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index dbcce9b..c571821a 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -2495,7 +2495,7 @@ void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
CharUnits BytePos,
bool &HasUnion,
bool ByrefLayout) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
SmallVector<const FieldDecl *, 16> Fields(RD->fields());
llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
const llvm::StructLayout *RecLayout =
@@ -5184,7 +5184,7 @@ CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
}
void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
// If this is a union, remember that we had one, because it might mess
// up the ordering of layout entries.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8d019d4..c5eb14e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2348,7 +2348,7 @@ static QualType GeneralizeTransparentUnion(QualType Ty) {
const RecordType *UT = Ty->getAsUnionType();
if (!UT)
return Ty;
- const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf();
if (!UD->hasAttr<TransparentUnionAttr>())
return Ty;
for (const auto *it : UD->fields()) {
@@ -4230,7 +4230,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
static bool HasNonDllImportDtor(QualType T) {
if (const auto *RT =
T->getBaseElementTypeUnsafe()->getAsCanonical<RecordType>())
- if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
+ if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
RD = RD->getDefinitionOrSelf();
if (RD->getDestructor() && !RD->getDestructor()->hasAttr<DLLImportAttr>())
return true;
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index f8c7d64..4e29d8a 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -310,7 +310,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
// This also covers anonymous structs and unions, which have a different
// compatibility rule, but it doesn't matter because you can never have a
// pointer to an anonymous struct or union.
- if (!RT->getOriginalDecl()->getDeclName())
+ if (!RT->getDecl()->getDeclName())
return getAnyPtr(PtrDepth);
// For non-builtin types use the mangled name of the canonical type.
@@ -332,7 +332,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
// Enum types are distinct types. In C++ they have "underlying types",
// however they aren't related for TBAA.
if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
- const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
+ const EnumDecl *ED = ETy->getDecl()->getDefinitionOrSelf();
if (!Features.CPlusPlus)
return getTypeInfo(ED->getIntegerType());
@@ -433,7 +433,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag));
return true;
}
- const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition();
+ const RecordDecl *RD = TTy->getDecl()->getDefinition();
if (RD->hasFlexibleArrayMember())
return false;
@@ -514,7 +514,7 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) {
llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
if (auto *TTy = dyn_cast<RecordType>(Ty)) {
- const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition();
+ const RecordDecl *RD = TTy->getDecl()->getDefinition();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
using TBAAStructField = llvm::MDBuilder::TBAAStructField;
SmallVector<TBAAStructField, 4> Fields;
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 3ffe999..ea31195 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -373,8 +373,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
}
// RecordTypes are cached and processed specially.
- if (const RecordType *RT = dyn_cast<RecordType>(Ty))
- return ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf());
+ if (const auto *RT = dyn_cast<RecordType>(Ty))
+ return ConvertRecordDeclType(RT->getDecl()->getDefinitionOrSelf());
llvm::Type *CachedType = nullptr;
auto TCI = TypeCache.find(Ty);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 7dc2eaf..9e195a9 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3816,7 +3816,7 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(RecordTy->getOriginalDecl())->getDefinitionOrSelf();
+ cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf();
if (!RD->hasDefinition())
return false;
@@ -3850,9 +3850,7 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
/// IsIncompleteClassType - Returns whether the given record type is incomplete.
static bool IsIncompleteClassType(const RecordType *RecordTy) {
- return !RecordTy->getOriginalDecl()
- ->getDefinitionOrSelf()
- ->isCompleteDefinition();
+ return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
}
/// ContainsIncompleteClassType - Returns whether the given type contains an
@@ -3985,9 +3983,8 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty,
break;
case Type::Record: {
- const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl())
+ ->getDefinitionOrSelf();
if (!RD->hasDefinition() || !RD->getNumBases()) {
VTableName = ClassTypeInfo;
@@ -4109,8 +4106,8 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
return llvm::GlobalValue::LinkOnceODRLinkage;
if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
- const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(Record->getOriginalDecl())->getDefinitionOrSelf();
+ const auto *RD =
+ cast<CXXRecordDecl>(Record->getDecl())->getDefinitionOrSelf();
if (RD->hasAttr<WeakAttr>())
return llvm::GlobalValue::WeakODRLinkage;
if (CGM.getTriple().isWindowsItaniumEnvironment())
@@ -4273,9 +4270,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
break;
case Type::Record: {
- const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl())
+ ->getDefinitionOrSelf();
if (!RD->hasDefinition() || !RD->getNumBases()) {
// We don't need to emit any fields.
break;
@@ -4322,8 +4318,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
if (CGM.getTarget().hasPS4DLLImportExport() &&
GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *RD =
+ cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf();
if (RD->hasAttr<DLLExportAttr>() ||
CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp
index 4d894fd..20965430 100644
--- a/clang/lib/CodeGen/SwiftCallingConv.cpp
+++ b/clang/lib/CodeGen/SwiftCallingConv.cpp
@@ -66,7 +66,7 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) {
// Record types.
if (auto recType = type->getAsCanonical<RecordType>()) {
- addTypedData(recType->getOriginalDecl(), begin);
+ addTypedData(recType->getDecl(), begin);
// Array types.
} else if (type->isArrayType()) {
@@ -814,7 +814,7 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type,
bool forReturn) {
unsigned IndirectAS = CGM.getDataLayout().getAllocaAddrSpace();
if (auto recordType = dyn_cast<RecordType>(type)) {
- auto record = recordType->getOriginalDecl();
+ auto record = recordType->getDecl();
auto &layout = CGM.getContext().getASTRecordLayout(record);
if (mustPassRecordIndirectly(CGM, record))
@@ -822,8 +822,7 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type,
/*AddrSpace=*/IndirectAS, /*byval=*/false);
SwiftAggLowering lowering(CGM);
- lowering.addTypedData(recordType->getOriginalDecl(), CharUnits::Zero(),
- layout);
+ lowering.addTypedData(recordType->getDecl(), CharUnits::Zero(), layout);
lowering.finish();
return classifyExpandedType(lowering, forReturn, layout.getAlignment(),
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 1e58c3f..342a3af 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -82,6 +82,8 @@ TargetCodeGenInfo::~TargetCodeGenInfo() = default;
// If someone can figure out a general rule for this, that would be great.
// It's probably just doomed to be platform-dependent, though.
unsigned TargetCodeGenInfo::getSizeOfUnwindException() const {
+ if (getABIInfo().getCodeGenOpts().hasSEHExceptions())
+ return getABIInfo().getDataLayout().getPointerSizeInBits() > 32 ? 64 : 48;
// Verified for:
// x86-64 FreeBSD, Linux, Darwin
// x86-32 FreeBSD, Linux, Darwin
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index d7deece..bb41a14 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -743,7 +743,7 @@ bool AArch64ABIInfo::passAsPureScalableType(
return false;
// Pure scalable types are never unions and never contain unions.
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
if (RD->isUnion())
return false;
diff --git a/clang/lib/CodeGen/Targets/ARC.cpp b/clang/lib/CodeGen/Targets/ARC.cpp
index 6727587..6c9444d 100644
--- a/clang/lib/CodeGen/Targets/ARC.cpp
+++ b/clang/lib/CodeGen/Targets/ARC.cpp
@@ -112,8 +112,7 @@ ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty,
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
- if (RT &&
- RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+ if (RT && RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getIndirectByValue(Ty);
// Ignore empty structs/unions.
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index c84c9f2..4d05217 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -516,7 +516,7 @@ static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
if (!RT) return false;
// Ignore records with flexible arrays.
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return false;
diff --git a/clang/lib/CodeGen/Targets/Lanai.cpp b/clang/lib/CodeGen/Targets/Lanai.cpp
index e76431a..871a135 100644
--- a/clang/lib/CodeGen/Targets/Lanai.cpp
+++ b/clang/lib/CodeGen/Targets/Lanai.cpp
@@ -102,8 +102,7 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty,
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
- if (RT &&
- RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+ if (RT && RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getIndirectResult(Ty, /*ByVal=*/true, State);
// Ignore empty structs/unions.
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 1f344d6..878723d 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -150,7 +150,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
// Non-zero-length arrays of empty records make the struct ineligible to be
// passed via FARs in C++.
if (const auto *RTy = EltTy->getAsCanonical<RecordType>()) {
- if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getOriginalDecl()) &&
+ if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
isEmptyRecord(getContext(), EltTy, true, true))
return false;
}
@@ -169,7 +169,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
// copy constructor are not eligible for the FP calling convention.
if (getRecordArgABI(Ty, CGT.getCXXABI()))
return false;
- const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RTy->getDecl()->getDefinitionOrSelf();
if (isEmptyRecord(getContext(), Ty, true, true) &&
(!RD->isUnion() || !isa<CXXRecordDecl>(RD)))
return true;
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index f26ab97..22fdcd9 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -161,7 +161,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {
return llvm::StructType::get(getVMContext(), ArgList);
}
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
assert(!(TySize % 8) && "Size of structure must be multiple of 8.");
@@ -265,7 +265,7 @@ MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
SmallVector<llvm::Type*, 8> RTList;
if (RT && RT->isStructureOrClassType()) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
unsigned FieldCnt = Layout.getFieldCount();
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index 0d0941e..d134589 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -234,7 +234,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
// Non-zero-length arrays of empty records make the struct ineligible for
// the FP calling convention in C++.
if (const auto *RTy = EltTy->getAsCanonical<RecordType>()) {
- if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getOriginalDecl()) &&
+ if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
isEmptyRecord(getContext(), EltTy, true, true))
return false;
}
@@ -256,7 +256,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
return false;
if (isEmptyRecord(getContext(), Ty, true, true))
return true;
- const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RTy->getDecl()->getDefinitionOrSelf();
// Unions aren't eligible unless they're empty (which is caught above).
if (RD->isUnion())
return false;
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index fb78948..8daf8eb 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -795,8 +795,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
// FIXME: This should not be byval!
- if (RT &&
- RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+ if (RT && RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getIndirectResult(Ty, true, State);
// Ignore empty structs/unions on non-Windows.
@@ -831,7 +830,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
unsigned AlignInBits = 0;
if (RT) {
const ASTRecordLayout &Layout =
- getContext().getASTRecordLayout(RT->getOriginalDecl());
+ getContext().getASTRecordLayout(RT->getDecl());
AlignInBits = getContext().toBits(Layout.getRequiredAlignment());
} else if (TI.isAlignRequired()) {
AlignInBits = TI.Align;
@@ -2042,7 +2041,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
if (getRecordArgABI(RT, getCXXABI()))
return;
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
// Assume variable sized types are passed in memory.
if (RD->hasFlexibleArrayMember())
@@ -2851,9 +2850,8 @@ ABIArgInfo
X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
unsigned &NeededSSE,
unsigned &MaxVectorWidth) const {
- auto *RD = cast<RecordType>(Ty.getCanonicalType())
- ->getOriginalDecl()
- ->getDefinitionOrSelf();
+ auto *RD =
+ cast<RecordType>(Ty.getCanonicalType())->getDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return getIndirectReturnResult(Ty);
@@ -3313,7 +3311,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs,
RAA == CGCXXABI::RAA_DirectInMemory);
}
- if (RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
+ if (RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
/*ByVal=*/false);
}
diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp
index ab01154..f9726ec 100644
--- a/clang/lib/CodeGen/Targets/XCore.cpp
+++ b/clang/lib/CodeGen/Targets/XCore.cpp
@@ -380,7 +380,7 @@ static bool appendRecordType(SmallStringEnc &Enc, const RecordType *RT,
// We collect all encoded fields and order as necessary.
bool IsRecursive = false;
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
+ const RecordDecl *RD = RT->getDecl()->getDefinition();
if (RD && !RD->field_empty()) {
// An incomplete TypeString stub is placed in the cache for this RecordType
// so that recursive calls to this RecordType will use it whilst building a
@@ -429,7 +429,7 @@ static bool appendEnumType(SmallStringEnc &Enc, const EnumType *ET,
Enc += "){";
// We collect all encoded enumerations and order them alphanumerically.
- if (const EnumDecl *ED = ET->getOriginalDecl()->getDefinition()) {
+ if (const EnumDecl *ED = ET->getDecl()->getDefinition()) {
SmallVector<FieldEncoding, 16> FE;
for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E;
++I) {
diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp
index 880e9e3..715429b 100644
--- a/clang/lib/Driver/Job.cpp
+++ b/clang/lib/Driver/Job.cpp
@@ -57,24 +57,25 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,
SkipNum = 2;
// These flags are all of the form -Flag <Arg> and are treated as two
// arguments. Therefore, we need to skip the flag and the next argument.
- bool ShouldSkip = llvm::StringSwitch<bool>(Flag)
- .Cases("-MF", "-MT", "-MQ", "-serialize-diagnostic-file", true)
- .Cases("-o", "-dependency-file", true)
- .Cases("-fdebug-compilation-dir", "-diagnostic-log-file", true)
- .Cases("-dwarf-debug-flags", "-ivfsoverlay", true)
- .Default(false);
+ bool ShouldSkip =
+ llvm::StringSwitch<bool>(Flag)
+ .Cases({"-MF", "-MT", "-MQ", "-serialize-diagnostic-file"}, true)
+ .Cases({"-o", "-dependency-file"}, true)
+ .Cases({"-fdebug-compilation-dir", "-diagnostic-log-file"}, true)
+ .Cases({"-dwarf-debug-flags", "-ivfsoverlay"}, true)
+ .Default(false);
if (ShouldSkip)
return true;
// Some include flags shouldn't be skipped if we have a crash VFS
IsInclude =
llvm::StringSwitch<bool>(Flag)
- .Cases("-include", "-header-include-file", true)
- .Cases("-idirafter", "-internal-isystem", "-iwithprefix", true)
- .Cases("-internal-externc-isystem", "-iprefix", true)
- .Cases("-iwithprefixbefore", "-isystem", "-iquote", true)
- .Cases("-isysroot", "-I", "-F", "-resource-dir", true)
- .Cases("-internal-iframework", "-iframework", "-include-pch", true)
+ .Cases({"-include", "-header-include-file"}, true)
+ .Cases({"-idirafter", "-internal-isystem", "-iwithprefix"}, true)
+ .Cases({"-internal-externc-isystem", "-iprefix"}, true)
+ .Cases({"-iwithprefixbefore", "-isystem", "-iquote"}, true)
+ .Cases({"-isysroot", "-I", "-F", "-resource-dir"}, true)
+ .Cases({"-internal-iframework", "-iframework", "-include-pch"}, true)
.Default(false);
if (IsInclude)
return !HaveCrashVFS;
@@ -83,9 +84,9 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,
// These flags are all of the form -Flag and have no second argument.
ShouldSkip = llvm::StringSwitch<bool>(Flag)
- .Cases("-M", "-MM", "-MG", "-MP", "-MD", true)
- .Case("-MMD", true)
- .Default(false);
+ .Cases({"-M", "-MM", "-MG", "-MP", "-MD"}, true)
+ .Case("-MMD", true)
+ .Default(false);
// Match found.
SkipNum = 1;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index bf75573..a7310ba 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3755,7 +3755,8 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
options::OPT_hlsl_entrypoint,
options::OPT_fdx_rootsignature_define,
options::OPT_fdx_rootsignature_version,
- options::OPT_fhlsl_spv_use_unknown_image_format};
+ options::OPT_fhlsl_spv_use_unknown_image_format,
+ options::OPT_fhlsl_spv_enable_maximal_reconvergence};
if (!types::isHLSL(InputType))
return;
for (const auto &Arg : ForwardedArguments)
@@ -9214,8 +9215,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_nogpulibc)) {
forAllAssociatedToolChains(C, JA, getToolChain(), [&](const ToolChain &TC) {
// The device C library is only available for NVPTX and AMDGPU targets
- // currently.
- if (!TC.getTriple().isNVPTX() && !TC.getTriple().isAMDGPU())
+ // and we only link it by default for OpenMP currently.
+ if ((!TC.getTriple().isNVPTX() && !TC.getTriple().isAMDGPU()) ||
+ !JA.isHostOffloading(Action::OFK_OpenMP))
return;
bool HasLibC = TC.getStdlibIncludePath().has_value();
if (HasLibC) {
diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp
index ceed7cb..0325296 100644
--- a/clang/lib/Driver/XRayArgs.cpp
+++ b/clang/lib/Driver/XRayArgs.cpp
@@ -105,8 +105,9 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
for (const auto &P : BundleParts) {
// TODO: Automate the generation of the string case table.
auto Valid = llvm::StringSwitch<bool>(P)
- .Cases("none", "all", "function", "function-entry",
- "function-exit", "custom", true)
+ .Cases({"none", "all", "function", "function-entry",
+ "function-exit", "custom"},
+ true)
.Default(false);
if (!Valid) {
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 541af6d..e5eda46 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -422,7 +422,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
Fragments.append(getFragmentsForNNS(TagTy->getQualifier(), Context, After));
- const TagDecl *Decl = TagTy->getOriginalDecl();
+ const TagDecl *Decl = TagTy->getDecl();
// Anonymous decl, skip this fragment.
if (Decl->getName().empty())
return Fragments.append("{ ... }",
diff --git a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp
index 5adbbc6..41e4e0c 100644
--- a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp
+++ b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp
@@ -26,7 +26,7 @@ TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const {
if (TypedefTy)
TypeDecl = TypedefTy->getDecl();
if (const TagType *TagTy = Type->getAs<TagType>()) {
- TypeDecl = TagTy->getOriginalDecl();
+ TypeDecl = TagTy->getDecl();
} else if (const ObjCInterfaceType *ObjCITy =
Type->getAs<ObjCInterfaceType>()) {
TypeDecl = ObjCITy->getDecl();
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index 54f366f..7348a3a 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -289,17 +289,20 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
SmallVector<WhitespaceManager::Change, 16> &Changes) {
int Shift = 0;
- // ScopeStack keeps track of the current scope depth. It contains indices of
- // the first token on each scope.
+ // ScopeStack keeps track of the current scope depth. It contains the levels
+ // of at most 2 scopes. The first one is the one that the matched token is
+ // in. The second one is the one that should not be moved by this procedure.
// The "Matches" indices should only have tokens from the outer-most scope.
// However, we do need to pay special attention to one class of tokens
- // that are not in the outer-most scope, and that is function parameters
- // which are split across multiple lines, as illustrated by this example:
+ // that are not in the outer-most scope, and that is the continuations of an
+ // unwrapped line whose positions are derived from a token to the right of the
+ // aligned token, as illustrated by this example:
// double a(int x);
// int b(int y,
// double z);
// In the above example, we need to take special care to ensure that
- // 'double z' is indented along with it's owning function 'b'.
+ // 'double z' is indented along with its owning function 'b', because its
+ // position is derived from the '(' token to the right of the 'b' token.
// The same holds for calling a function:
// double a = foo(x);
// int b = bar(foo(y),
@@ -309,32 +312,28 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
// auto s = "Hello"
// "World";
// Special handling is required for 'nested' ternary operators.
- SmallVector<unsigned, 16> ScopeStack;
+ SmallVector<std::tuple<unsigned, unsigned, unsigned>, 2> ScopeStack;
for (unsigned i = Start; i != End; ++i) {
auto &CurrentChange = Changes[i];
if (!Matches.empty() && Matches[0] < i)
Matches.consume_front();
assert(Matches.empty() || Matches[0] >= i);
- if (!ScopeStack.empty() &&
- CurrentChange.indentAndNestingLevel() <
- Changes[ScopeStack.back()].indentAndNestingLevel()) {
+ while (!ScopeStack.empty() &&
+ CurrentChange.indentAndNestingLevel() < ScopeStack.back()) {
ScopeStack.pop_back();
}
- // Compare current token to previous non-comment token to ensure whether
- // it is in a deeper scope or not.
- unsigned PreviousNonComment = i - 1;
- while (PreviousNonComment > Start &&
- Changes[PreviousNonComment].Tok->is(tok::comment)) {
- --PreviousNonComment;
- }
- if (i != Start && CurrentChange.indentAndNestingLevel() >
- Changes[PreviousNonComment].indentAndNestingLevel()) {
- ScopeStack.push_back(i);
+ // Keep track of the level that should not move with the aligned token.
+ if (ScopeStack.size() == 1u && CurrentChange.NewlinesBefore != 0u &&
+ CurrentChange.indentAndNestingLevel() > ScopeStack[0] &&
+ !CurrentChange.IsAligned) {
+ ScopeStack.push_back(CurrentChange.indentAndNestingLevel());
}
- bool InsideNestedScope = !ScopeStack.empty();
+ bool InsideNestedScope =
+ !ScopeStack.empty() &&
+ CurrentChange.indentAndNestingLevel() > ScopeStack[0];
bool ContinuedStringLiteral = i > Start &&
CurrentChange.Tok->is(tok::string_literal) &&
Changes[i - 1].Tok->is(tok::string_literal);
@@ -349,103 +348,20 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
if (!Matches.empty() && Matches[0] == i) {
Shift = Column - (RightJustify ? CurrentChange.TokenLength : 0) -
CurrentChange.StartOfTokenColumn;
+ ScopeStack = {CurrentChange.indentAndNestingLevel()};
CurrentChange.Spaces += Shift;
}
if (Shift == 0)
continue;
- // This is for function parameters that are split across multiple lines,
- // as mentioned in the ScopeStack comment.
- if (InsideNestedScope && CurrentChange.NewlinesBefore > 0) {
- unsigned ScopeStart = ScopeStack.back();
- auto ShouldShiftBeAdded = [&] {
- // Function declaration
- if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
- return true;
-
- // Lambda.
- if (Changes[ScopeStart - 1].Tok->is(TT_LambdaLBrace))
- return false;
-
- // Continued function declaration
- if (ScopeStart > Start + 1 &&
- Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) {
- return true;
- }
-
- // Continued (template) function call.
- if (ScopeStart > Start + 1 &&
- Changes[ScopeStart - 2].Tok->isOneOf(tok::identifier,
- TT_TemplateCloser) &&
- Changes[ScopeStart - 1].Tok->is(tok::l_paren) &&
- Changes[ScopeStart].Tok->isNot(TT_LambdaLSquare)) {
- if (CurrentChange.Tok->MatchingParen &&
- CurrentChange.Tok->MatchingParen->is(TT_LambdaLBrace)) {
- return false;
- }
- if (Changes[ScopeStart].NewlinesBefore > 0)
- return false;
- if (CurrentChange.Tok->is(tok::l_brace) &&
- CurrentChange.Tok->is(BK_BracedInit)) {
- return true;
- }
- return Style.BinPackArguments;
- }
-
- // Ternary operator
- if (CurrentChange.Tok->is(TT_ConditionalExpr))
- return true;
-
- // Period Initializer .XXX = 1.
- if (CurrentChange.Tok->is(TT_DesignatedInitializerPeriod))
- return true;
-
- // Continued ternary operator
- if (CurrentChange.Tok->Previous &&
- CurrentChange.Tok->Previous->is(TT_ConditionalExpr)) {
- return true;
- }
-
- // Continued direct-list-initialization using braced list.
- if (ScopeStart > Start + 1 &&
- Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
- Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
- CurrentChange.Tok->is(tok::l_brace) &&
- CurrentChange.Tok->is(BK_BracedInit)) {
- return true;
- }
-
- // Continued braced list.
- if (ScopeStart > Start + 1 &&
- Changes[ScopeStart - 2].Tok->isNot(tok::identifier) &&
- Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
- CurrentChange.Tok->isNot(tok::r_brace)) {
- for (unsigned OuterScopeStart : llvm::reverse(ScopeStack)) {
- // Lambda.
- if (OuterScopeStart > Start &&
- Changes[OuterScopeStart - 1].Tok->is(TT_LambdaLBrace)) {
- return false;
- }
- }
- if (Changes[ScopeStart].NewlinesBefore > 0)
- return false;
- return true;
- }
-
- // Continued template parameter.
- if (Changes[ScopeStart - 1].Tok->is(TT_TemplateOpener))
- return true;
-
- return false;
- };
-
- if (ShouldShiftBeAdded())
- CurrentChange.Spaces += Shift;
- }
-
- if (ContinuedStringLiteral)
+ // This is for lines that are split across multiple lines, as mentioned in
+ // the ScopeStack comment. The stack size being 1 means that the token is
+ // not in a scope that should not move.
+ if (ScopeStack.size() == 1u && CurrentChange.NewlinesBefore > 0 &&
+ (ContinuedStringLiteral || InsideNestedScope)) {
CurrentChange.Spaces += Shift;
+ }
// We should not remove required spaces unless we break the line before.
assert(Shift > 0 || Changes[i].NewlinesBefore > 0 ||
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 292adce..5bd15f5 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4012,13 +4012,13 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
auto Diag = Diags.Report(diag::note_drv_use_standard);
Diag << Std.getName() << Std.getDescription();
unsigned NumAliases = 0;
-#define LANGSTANDARD(id, name, lang, desc, features)
+#define LANGSTANDARD(id, name, lang, desc, features, version)
#define LANGSTANDARD_ALIAS(id, alias) \
if (KindValue == LangStandard::lang_##id) ++NumAliases;
#define LANGSTANDARD_ALIAS_DEPR(id, alias)
#include "clang/Basic/LangStandards.def"
Diag << NumAliases;
-#define LANGSTANDARD(id, name, lang, desc, features)
+#define LANGSTANDARD(id, name, lang, desc, features, version)
#define LANGSTANDARD_ALIAS(id, alias) \
if (KindValue == LangStandard::lang_##id) Diag << alias;
#define LANGSTANDARD_ALIAS_DEPR(id, alias)
diff --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp
index 32ed995..fb178b6 100644
--- a/clang/lib/Frontend/FrontendOptions.cpp
+++ b/clang/lib/Frontend/FrontendOptions.cpp
@@ -14,25 +14,26 @@ using namespace clang;
InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) {
return llvm::StringSwitch<InputKind>(Extension)
- .Cases("ast", "pcm", InputKind(Language::Unknown, InputKind::Precompiled))
+ .Cases({"ast", "pcm"},
+ InputKind(Language::Unknown, InputKind::Precompiled))
.Case("c", Language::C)
- .Cases("S", "s", Language::Asm)
+ .Cases({"S", "s"}, Language::Asm)
.Case("i", InputKind(Language::C).getPreprocessed())
.Case("ii", InputKind(Language::CXX).getPreprocessed())
.Case("cui", InputKind(Language::CUDA).getPreprocessed())
.Case("m", Language::ObjC)
.Case("mi", InputKind(Language::ObjC).getPreprocessed())
- .Cases("mm", "M", Language::ObjCXX)
+ .Cases({"mm", "M"}, Language::ObjCXX)
.Case("mii", InputKind(Language::ObjCXX).getPreprocessed())
- .Cases("C", "cc", "cp", Language::CXX)
- .Cases("cpp", "CPP", "c++", "cxx", "hpp", "hxx", Language::CXX)
+ .Cases({"C", "cc", "cp"}, Language::CXX)
+ .Cases({"cpp", "CPP", "c++", "cxx", "hpp", "hxx"}, Language::CXX)
.Case("cppm", Language::CXX)
- .Cases("iim", "iih", InputKind(Language::CXX).getPreprocessed())
+ .Cases({"iim", "iih"}, InputKind(Language::CXX).getPreprocessed())
.Case("cl", Language::OpenCL)
.Case("clcpp", Language::OpenCLCXX)
- .Cases("cu", "cuh", Language::CUDA)
+ .Cases({"cu", "cuh"}, Language::CUDA)
.Case("hip", Language::HIP)
- .Cases("ll", "bc", Language::LLVM_IR)
+ .Cases({"ll", "bc"}, Language::LLVM_IR)
.Case("hlsl", Language::HLSL)
.Case("cir", Language::CIR)
.Default(Language::Unknown);
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index b899fb9..baad6317 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -459,43 +459,12 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// value is, are implementation-defined.
// (Removed in C++20.)
if (!LangOpts.CPlusPlus) {
- if (LangOpts.C2y)
- Builder.defineMacro("__STDC_VERSION__", "202400L");
- else if (LangOpts.C23)
- Builder.defineMacro("__STDC_VERSION__", "202311L");
- else if (LangOpts.C17)
- Builder.defineMacro("__STDC_VERSION__", "201710L");
- else if (LangOpts.C11)
- Builder.defineMacro("__STDC_VERSION__", "201112L");
- else if (LangOpts.C99)
- Builder.defineMacro("__STDC_VERSION__", "199901L");
- else if (!LangOpts.GNUMode && LangOpts.Digraphs)
- Builder.defineMacro("__STDC_VERSION__", "199409L");
+ if (std::optional<uint32_t> Lang = LangOpts.getCLangStd())
+ Builder.defineMacro("__STDC_VERSION__", Twine(*Lang) + "L");
} else {
// -- __cplusplus
- if (LangOpts.CPlusPlus26)
- // FIXME: Use correct value for C++26.
- Builder.defineMacro("__cplusplus", "202400L");
- else if (LangOpts.CPlusPlus23)
- Builder.defineMacro("__cplusplus", "202302L");
- // [C++20] The integer literal 202002L.
- else if (LangOpts.CPlusPlus20)
- Builder.defineMacro("__cplusplus", "202002L");
- // [C++17] The integer literal 201703L.
- else if (LangOpts.CPlusPlus17)
- Builder.defineMacro("__cplusplus", "201703L");
- // [C++14] The name __cplusplus is defined to the value 201402L when
- // compiling a C++ translation unit.
- else if (LangOpts.CPlusPlus14)
- Builder.defineMacro("__cplusplus", "201402L");
- // [C++11] The name __cplusplus is defined to the value 201103L when
- // compiling a C++ translation unit.
- else if (LangOpts.CPlusPlus11)
- Builder.defineMacro("__cplusplus", "201103L");
- // [C++03] The name __cplusplus is defined to the value 199711L when
- // compiling a C++ translation unit.
- else
- Builder.defineMacro("__cplusplus", "199711L");
+ Builder.defineMacro("__cplusplus",
+ Twine(*LangOpts.getCPlusPlusLangStd()) + "L");
// -- __STDCPP_DEFAULT_NEW_ALIGNMENT__
// [C++17] An integer literal of type std::size_t whose value is the
diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 42f2d65..dee29fe 100644
--- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -852,7 +852,7 @@ RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
if (!IvarT->getAs<TypedefType>() && IvarT->isRecordType()) {
- RecordDecl *RD = IvarT->castAsCanonical<RecordType>()->getOriginalDecl();
+ RecordDecl *RD = IvarT->castAsCanonical<RecordType>()->getDecl();
RD = RD->getDefinition();
if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
// decltype(((Foo_IMPL*)0)->bar) *
@@ -7453,8 +7453,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
if (!IvarT->getAs<TypedefType>() && IvarT->isRecordType()) {
- RecordDecl *RD =
- IvarT->castAsCanonical<RecordType>()->getOriginalDecl();
+ RecordDecl *RD = IvarT->castAsCanonical<RecordType>()->getDecl();
RD = RD->getDefinition();
if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
// decltype(((Foo_IMPL*)0)->bar) *
diff --git a/clang/lib/Headers/avx512cdintrin.h b/clang/lib/Headers/avx512cdintrin.h
index b161440..fb6dcb6 100644
--- a/clang/lib/Headers/avx512cdintrin.h
+++ b/clang/lib/Headers/avx512cdintrin.h
@@ -15,111 +15,98 @@
#define __AVX512CDINTRIN_H
/* Define the default attributes for the functions in this file. */
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define __DEFAULT_FN_ATTRS \
+ constexpr __attribute__((__always_inline__, __nodebug__, \
+ __target__("avx512cd"), __min_vector_width__(512)))
+#else
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, __target__("avx512cd"), \
__min_vector_width__(512)))
-
-#if defined(__cplusplus) && (__cplusplus >= 201103L)
-#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
-#else
-#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
#endif
static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_conflict_epi64 (__m512i __A)
-{
- return (__m512i) __builtin_ia32_vpconflictdi_512 ((__v8di) __A);
+_mm512_conflict_epi64(__m512i __A) {
+ return (__m512i)__builtin_ia32_vpconflictdi_512((__v8di)__A);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_conflict_epi64 (__m512i __W, __mmask8 __U, __m512i __A)
-{
- return (__m512i)__builtin_ia32_selectq_512((__mmask8)__U,
- (__v8di)_mm512_conflict_epi64(__A),
- (__v8di)__W);
+_mm512_mask_conflict_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
+ return (__m512i)__builtin_ia32_selectq_512(
+ (__mmask8)__U, (__v8di)_mm512_conflict_epi64(__A), (__v8di)__W);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_conflict_epi64 (__mmask8 __U, __m512i __A)
-{
+_mm512_maskz_conflict_epi64(__mmask8 __U, __m512i __A) {
return (__m512i)__builtin_ia32_selectq_512((__mmask8)__U,
(__v8di)_mm512_conflict_epi64(__A),
- (__v8di)_mm512_setzero_si512 ());
+ (__v8di)_mm512_setzero_si512());
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_conflict_epi32 (__m512i __A)
-{
- return (__m512i) __builtin_ia32_vpconflictsi_512 ((__v16si) __A);
+_mm512_conflict_epi32(__m512i __A) {
+ return (__m512i)__builtin_ia32_vpconflictsi_512((__v16si)__A);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_mask_conflict_epi32 (__m512i __W, __mmask16 __U, __m512i __A)
-{
- return (__m512i)__builtin_ia32_selectd_512((__mmask16)__U,
- (__v16si)_mm512_conflict_epi32(__A),
- (__v16si)__W);
+_mm512_mask_conflict_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
+ return (__m512i)__builtin_ia32_selectd_512(
+ (__mmask16)__U, (__v16si)_mm512_conflict_epi32(__A), (__v16si)__W);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
-_mm512_maskz_conflict_epi32 (__mmask16 __U, __m512i __A)
-{
- return (__m512i)__builtin_ia32_selectd_512((__mmask16)__U,
- (__v16si)_mm512_conflict_epi32(__A),
- (__v16si)_mm512_setzero_si512());
+_mm512_maskz_conflict_epi32(__mmask16 __U, __m512i __A) {
+ return (__m512i)__builtin_ia32_selectd_512(
+ (__mmask16)__U, (__v16si)_mm512_conflict_epi32(__A),
+ (__v16si)_mm512_setzero_si512());
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm512_lzcnt_epi32(__m512i __A) {
+static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_lzcnt_epi32(__m512i __A) {
return (__m512i)__builtin_elementwise_clzg((__v16si)__A,
(__v16si)_mm512_set1_epi32(32));
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_lzcnt_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
- return (__m512i)__builtin_ia32_selectd_512((__mmask16)__U,
- (__v16si)_mm512_lzcnt_epi32(__A),
- (__v16si)__W);
+ return (__m512i)__builtin_ia32_selectd_512(
+ (__mmask16)__U, (__v16si)_mm512_lzcnt_epi32(__A), (__v16si)__W);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_maskz_lzcnt_epi32(__mmask16 __U, __m512i __A) {
return (__m512i)__builtin_ia32_selectd_512((__mmask16)__U,
(__v16si)_mm512_lzcnt_epi32(__A),
(__v16si)_mm512_setzero_si512());
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
-_mm512_lzcnt_epi64(__m512i __A) {
+static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_lzcnt_epi64(__m512i __A) {
return (__m512i)__builtin_elementwise_clzg(
(__v8di)__A, (__v8di)_mm512_set1_epi64((long long)64));
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_lzcnt_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
- return (__m512i)__builtin_ia32_selectq_512((__mmask8)__U,
- (__v8di)_mm512_lzcnt_epi64(__A),
- (__v8di)__W);
+ return (__m512i)__builtin_ia32_selectq_512(
+ (__mmask8)__U, (__v8di)_mm512_lzcnt_epi64(__A), (__v8di)__W);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_maskz_lzcnt_epi64(__mmask8 __U, __m512i __A) {
return (__m512i)__builtin_ia32_selectq_512((__mmask8)__U,
(__v8di)_mm512_lzcnt_epi64(__A),
(__v8di)_mm512_setzero_si512());
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_broadcastmb_epi64(__mmask8 __A) {
- return (__m512i) _mm512_set1_epi64((long long) __A);
+ return (__m512i)_mm512_set1_epi64((long long)__A);
}
-static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR
+static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_broadcastmw_epi32(__mmask16 __A) {
return (__m512i)_mm512_set1_epi32((int)__A);
}
#undef __DEFAULT_FN_ATTRS
-#undef __DEFAULT_FN_ATTRS_CONSTEXPR
#endif
diff --git a/clang/lib/Headers/avx512vlcdintrin.h b/clang/lib/Headers/avx512vlcdintrin.h
index cb98e7c..7719680f 100644
--- a/clang/lib/Headers/avx512vlcdintrin.h
+++ b/clang/lib/Headers/avx512vlcdintrin.h
@@ -14,203 +14,182 @@
#define __AVX512VLCDINTRIN_H
/* Define the default attributes for the functions in this file. */
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define __DEFAULT_FN_ATTRS128 \
+ constexpr __attribute__((__always_inline__, __nodebug__, \
+ __target__("avx512vl,avx512cd"), \
+ __min_vector_width__(128)))
+#define __DEFAULT_FN_ATTRS256 \
+ constexpr __attribute__((__always_inline__, __nodebug__, \
+ __target__("avx512vl,avx512cd"), \
+ __min_vector_width__(256)))
+#else
#define __DEFAULT_FN_ATTRS128 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512cd"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS256 \
__attribute__((__always_inline__, __nodebug__, \
__target__("avx512vl,avx512cd"), __min_vector_width__(256)))
-
-#if defined(__cplusplus) && (__cplusplus >= 201103L)
-#define __DEFAULT_FN_ATTRS256_CONSTEXPR __DEFAULT_FN_ATTRS256 constexpr
-#define __DEFAULT_FN_ATTRS128_CONSTEXPR __DEFAULT_FN_ATTRS128 constexpr
-#else
-#define __DEFAULT_FN_ATTRS256_CONSTEXPR __DEFAULT_FN_ATTRS256
-#define __DEFAULT_FN_ATTRS128_CONSTEXPR __DEFAULT_FN_ATTRS128
#endif
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_broadcastmb_epi64(__mmask8 __A) {
return (__m128i) _mm_set1_epi64x((long long) __A);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_broadcastmb_epi64(__mmask8 __A) {
- return (__m256i) _mm256_set1_epi64x((long long)__A);
+ return (__m256i)_mm256_set1_epi64x((long long)__A);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_broadcastmw_epi32(__mmask16 __A) {
return (__m128i) _mm_set1_epi32((int)__A);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_broadcastmw_epi32(__mmask16 __A) {
return (__m256i) _mm256_set1_epi32((int)__A);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_conflict_epi64 (__m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictdi_128 ((__v2di) __A);
+_mm_conflict_epi64(__m128i __A) {
+ return (__m128i)__builtin_ia32_vpconflictdi_128((__v2di)__A);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_conflict_epi64 (__m128i __W, __mmask8 __U, __m128i __A)
-{
- return (__m128i)__builtin_ia32_selectq_128((__mmask8)__U,
- (__v2di)_mm_conflict_epi64(__A),
- (__v2di)__W);
+_mm_mask_conflict_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
+ return (__m128i)__builtin_ia32_selectq_128(
+ (__mmask8)__U, (__v2di)_mm_conflict_epi64(__A), (__v2di)__W);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_conflict_epi64 (__mmask8 __U, __m128i __A)
-{
+_mm_maskz_conflict_epi64(__mmask8 __U, __m128i __A) {
return (__m128i)__builtin_ia32_selectq_128((__mmask8)__U,
(__v2di)_mm_conflict_epi64(__A),
(__v2di)_mm_setzero_si128());
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_conflict_epi64 (__m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictdi_256 ((__v4di) __A);
+_mm256_conflict_epi64(__m256i __A) {
+ return (__m256i)__builtin_ia32_vpconflictdi_256((__v4di)__A);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_conflict_epi64 (__m256i __W, __mmask8 __U, __m256i __A)
-{
- return (__m256i)__builtin_ia32_selectq_256((__mmask8)__U,
- (__v4di)_mm256_conflict_epi64(__A),
- (__v4di)__W);
+_mm256_mask_conflict_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
+ return (__m256i)__builtin_ia32_selectq_256(
+ (__mmask8)__U, (__v4di)_mm256_conflict_epi64(__A), (__v4di)__W);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_conflict_epi64 (__mmask8 __U, __m256i __A)
-{
+_mm256_maskz_conflict_epi64(__mmask8 __U, __m256i __A) {
return (__m256i)__builtin_ia32_selectq_256((__mmask8)__U,
(__v4di)_mm256_conflict_epi64(__A),
(__v4di)_mm256_setzero_si256());
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_conflict_epi32 (__m128i __A)
-{
- return (__m128i) __builtin_ia32_vpconflictsi_128 ((__v4si) __A);
+_mm_conflict_epi32(__m128i __A) {
+ return (__m128i)__builtin_ia32_vpconflictsi_128((__v4si)__A);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_mask_conflict_epi32 (__m128i __W, __mmask8 __U, __m128i __A)
-{
- return (__m128i)__builtin_ia32_selectd_128((__mmask8)__U,
- (__v4si)_mm_conflict_epi32(__A),
- (__v4si)__W);
+_mm_mask_conflict_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
+ return (__m128i)__builtin_ia32_selectd_128(
+ (__mmask8)__U, (__v4si)_mm_conflict_epi32(__A), (__v4si)__W);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
-_mm_maskz_conflict_epi32 (__mmask8 __U, __m128i __A)
-{
+_mm_maskz_conflict_epi32(__mmask8 __U, __m128i __A) {
return (__m128i)__builtin_ia32_selectd_128((__mmask8)__U,
(__v4si)_mm_conflict_epi32(__A),
(__v4si)_mm_setzero_si128());
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_conflict_epi32 (__m256i __A)
-{
- return (__m256i) __builtin_ia32_vpconflictsi_256 ((__v8si) __A);
+_mm256_conflict_epi32(__m256i __A) {
+ return (__m256i)__builtin_ia32_vpconflictsi_256((__v8si)__A);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_mask_conflict_epi32 (__m256i __W, __mmask8 __U, __m256i __A)
-{
- return (__m256i)__builtin_ia32_selectd_256((__mmask8)__U,
- (__v8si)_mm256_conflict_epi32(__A),
- (__v8si)__W);
+_mm256_mask_conflict_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
+ return (__m256i)__builtin_ia32_selectd_256(
+ (__mmask8)__U, (__v8si)_mm256_conflict_epi32(__A), (__v8si)__W);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
-_mm256_maskz_conflict_epi32 (__mmask8 __U, __m256i __A)
-{
+_mm256_maskz_conflict_epi32(__mmask8 __U, __m256i __A) {
return (__m256i)__builtin_ia32_selectd_256((__mmask8)__U,
(__v8si)_mm256_conflict_epi32(__A),
(__v8si)_mm256_setzero_si256());
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
-_mm_lzcnt_epi32(__m128i __A) {
+static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_lzcnt_epi32(__m128i __A) {
return (__m128i)__builtin_elementwise_clzg((__v4si)__A,
(__v4si)_mm_set1_epi32(32));
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_mask_lzcnt_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
- return (__m128i)__builtin_ia32_selectd_128((__mmask8)__U,
- (__v4si)_mm_lzcnt_epi32(__A),
- (__v4si)__W);
+ return (__m128i)__builtin_ia32_selectd_128(
+ (__mmask8)__U, (__v4si)_mm_lzcnt_epi32(__A), (__v4si)__W);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_maskz_lzcnt_epi32(__mmask8 __U, __m128i __A) {
- return (__m128i)__builtin_ia32_selectd_128((__mmask8)__U,
- (__v4si)_mm_lzcnt_epi32(__A),
- (__v4si)_mm_setzero_si128());
+ return (__m128i)__builtin_ia32_selectd_128(
+ (__mmask8)__U, (__v4si)_mm_lzcnt_epi32(__A), (__v4si)_mm_setzero_si128());
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_lzcnt_epi32(__m256i __A) {
return (__m256i)__builtin_elementwise_clzg((__v8si)__A,
(__v8si)_mm256_set1_epi32(32));
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_mask_lzcnt_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
- return (__m256i)__builtin_ia32_selectd_256((__mmask8)__U,
- (__v8si)_mm256_lzcnt_epi32(__A),
- (__v8si)__W);
+ return (__m256i)__builtin_ia32_selectd_256(
+ (__mmask8)__U, (__v8si)_mm256_lzcnt_epi32(__A), (__v8si)__W);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_maskz_lzcnt_epi32(__mmask8 __U, __m256i __A) {
return (__m256i)__builtin_ia32_selectd_256((__mmask8)__U,
(__v8si)_mm256_lzcnt_epi32(__A),
(__v8si)_mm256_setzero_si256());
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
-_mm_lzcnt_epi64(__m128i __A) {
+static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_lzcnt_epi64(__m128i __A) {
return (__m128i)__builtin_elementwise_clzg(
(__v2di)__A, (__v2di)_mm_set1_epi64x((long long)64));
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_mask_lzcnt_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
- return (__m128i)__builtin_ia32_selectq_128((__mmask8)__U,
- (__v2di)_mm_lzcnt_epi64(__A),
- (__v2di)__W);
+ return (__m128i)__builtin_ia32_selectq_128(
+ (__mmask8)__U, (__v2di)_mm_lzcnt_epi64(__A), (__v2di)__W);
}
-static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
+static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_maskz_lzcnt_epi64(__mmask8 __U, __m128i __A) {
- return (__m128i)__builtin_ia32_selectq_128((__mmask8)__U,
- (__v2di)_mm_lzcnt_epi64(__A),
- (__v2di)_mm_setzero_si128());
+ return (__m128i)__builtin_ia32_selectq_128(
+ (__mmask8)__U, (__v2di)_mm_lzcnt_epi64(__A), (__v2di)_mm_setzero_si128());
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_lzcnt_epi64(__m256i __A) {
return (__m256i)__builtin_elementwise_clzg(
(__v4di)__A, (__v4di)_mm256_set1_epi64x((long long)64));
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_mask_lzcnt_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
- return (__m256i)__builtin_ia32_selectq_256((__mmask8)__U,
- (__v4di)_mm256_lzcnt_epi64(__A),
- (__v4di)__W);
+ return (__m256i)__builtin_ia32_selectq_256(
+ (__mmask8)__U, (__v4di)_mm256_lzcnt_epi64(__A), (__v4di)__W);
}
-static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
+static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_maskz_lzcnt_epi64(__mmask8 __U, __m256i __A) {
return (__m256i)__builtin_ia32_selectq_256((__mmask8)__U,
(__v4di)_mm256_lzcnt_epi64(__A),
@@ -219,7 +198,5 @@ _mm256_maskz_lzcnt_epi64(__mmask8 __U, __m256i __A) {
#undef __DEFAULT_FN_ATTRS128
#undef __DEFAULT_FN_ATTRS256
-#undef __DEFAULT_FN_ATTRS128_CONSTEXPR
-#undef __DEFAULT_FN_ATTRS256_CONSTEXPR
#endif /* __AVX512VLCDINTRIN_H */
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 74c6c11..3c1e038 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -117,7 +117,7 @@ public:
}
bool VisitTagTypeLoc(TagTypeLoc TL) {
- TagDecl *D = TL.getOriginalDecl();
+ TagDecl *D = TL.getDecl();
if (!IndexCtx.shouldIndexFunctionLocalSymbols() &&
D->getParentFunctionOrMethod())
return true;
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index c78d66f..08835ea 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -911,11 +911,10 @@ void USRGenerator::VisitType(QualType T) {
}
if (const TagType *TT = T->getAs<TagType>()) {
if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TT)) {
- T = ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType(
- Ctx);
+ T = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Ctx);
} else {
Out << '$';
- VisitTagDecl(TT->getOriginalDecl());
+ VisitTagDecl(TT->getDecl());
return;
}
}
diff --git a/clang/lib/InstallAPI/HeaderFile.cpp b/clang/lib/InstallAPI/HeaderFile.cpp
index 0b7041e..d736a0a 100644
--- a/clang/lib/InstallAPI/HeaderFile.cpp
+++ b/clang/lib/InstallAPI/HeaderFile.cpp
@@ -38,7 +38,7 @@ std::optional<std::string> createIncludeHeaderName(const StringRef FullPath) {
bool isHeaderFile(StringRef Path) {
return StringSwitch<bool>(sys::path::extension(Path))
- .Cases(".h", ".H", ".hh", ".hpp", ".hxx", true)
+ .Cases({".h", ".H", ".hh", ".hpp", ".hxx"}, true)
.Default(false);
}
diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp
index f12e040..53fbc36 100644
--- a/clang/lib/InstallAPI/Visitor.cpp
+++ b/clang/lib/InstallAPI/Visitor.cpp
@@ -543,8 +543,8 @@ void InstallAPIVisitor::emitVTableSymbols(const CXXRecordDecl *D,
}
for (const auto &It : D->bases()) {
- const CXXRecordDecl *Base = cast<CXXRecordDecl>(
- It.getType()->castAs<RecordType>()->getOriginalDecl());
+ const auto *Base =
+ cast<CXXRecordDecl>(It.getType()->castAs<RecordType>()->getDecl());
const auto BaseAccess = getAccessForDecl(Base);
if (!BaseAccess)
continue;
diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
index a55b7f5..0ed02f3 100644
--- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp
+++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
@@ -66,10 +66,10 @@ static std::string QualTypeToString(ASTContext &Ctx, QualType QT) {
const QualType NonRefTy = QT.getNonReferenceType();
if (const auto *TTy = llvm::dyn_cast<TagType>(NonRefTy))
- return DeclTypeToString(NonRefTy, TTy->getOriginalDecl());
+ return DeclTypeToString(NonRefTy, TTy->getDecl());
if (const auto *TRy = dyn_cast<RecordType>(NonRefTy))
- return DeclTypeToString(NonRefTy, TRy->getOriginalDecl());
+ return DeclTypeToString(NonRefTy, TRy->getDecl());
const QualType Canon = NonRefTy.getCanonicalType();
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 5c6ecdb..6a5e5d4 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -248,50 +248,67 @@ static bool warnByDefaultOnWrongCase(StringRef Include) {
// The standard C/C++ and Posix headers
return llvm::StringSwitch<bool>(LowerInclude)
- // C library headers
- .Cases("assert.h", "complex.h", "ctype.h", "errno.h", "fenv.h", true)
- .Cases("float.h", "inttypes.h", "iso646.h", "limits.h", "locale.h", true)
- .Cases("math.h", "setjmp.h", "signal.h", "stdalign.h", "stdarg.h", true)
- .Cases("stdatomic.h", "stdbool.h", "stdckdint.h", "stdcountof.h", true)
- .Cases("stddef.h", "stdint.h", "stdio.h", "stdlib.h", "stdnoreturn.h", true)
- .Cases("string.h", "tgmath.h", "threads.h", "time.h", "uchar.h", true)
- .Cases("wchar.h", "wctype.h", true)
-
- // C++ headers for C library facilities
- .Cases("cassert", "ccomplex", "cctype", "cerrno", "cfenv", true)
- .Cases("cfloat", "cinttypes", "ciso646", "climits", "clocale", true)
- .Cases("cmath", "csetjmp", "csignal", "cstdalign", "cstdarg", true)
- .Cases("cstdbool", "cstddef", "cstdint", "cstdio", "cstdlib", true)
- .Cases("cstring", "ctgmath", "ctime", "cuchar", "cwchar", true)
- .Case("cwctype", true)
-
- // C++ library headers
- .Cases("algorithm", "fstream", "list", "regex", "thread", true)
- .Cases("array", "functional", "locale", "scoped_allocator", "tuple", true)
- .Cases("atomic", "future", "map", "set", "type_traits", true)
- .Cases("bitset", "initializer_list", "memory", "shared_mutex", "typeindex", true)
- .Cases("chrono", "iomanip", "mutex", "sstream", "typeinfo", true)
- .Cases("codecvt", "ios", "new", "stack", "unordered_map", true)
- .Cases("complex", "iosfwd", "numeric", "stdexcept", "unordered_set", true)
- .Cases("condition_variable", "iostream", "ostream", "streambuf", "utility", true)
- .Cases("deque", "istream", "queue", "string", "valarray", true)
- .Cases("exception", "iterator", "random", "strstream", "vector", true)
- .Cases("forward_list", "limits", "ratio", "system_error", true)
-
- // POSIX headers (which aren't also C headers)
- .Cases("aio.h", "arpa/inet.h", "cpio.h", "dirent.h", "dlfcn.h", true)
- .Cases("fcntl.h", "fmtmsg.h", "fnmatch.h", "ftw.h", "glob.h", true)
- .Cases("grp.h", "iconv.h", "langinfo.h", "libgen.h", "monetary.h", true)
- .Cases("mqueue.h", "ndbm.h", "net/if.h", "netdb.h", "netinet/in.h", true)
- .Cases("netinet/tcp.h", "nl_types.h", "poll.h", "pthread.h", "pwd.h", true)
- .Cases("regex.h", "sched.h", "search.h", "semaphore.h", "spawn.h", true)
- .Cases("strings.h", "stropts.h", "sys/ipc.h", "sys/mman.h", "sys/msg.h", true)
- .Cases("sys/resource.h", "sys/select.h", "sys/sem.h", "sys/shm.h", "sys/socket.h", true)
- .Cases("sys/stat.h", "sys/statvfs.h", "sys/time.h", "sys/times.h", "sys/types.h", true)
- .Cases("sys/uio.h", "sys/un.h", "sys/utsname.h", "sys/wait.h", "syslog.h", true)
- .Cases("tar.h", "termios.h", "trace.h", "ulimit.h", true)
- .Cases("unistd.h", "utime.h", "utmpx.h", "wordexp.h", true)
- .Default(false);
+ // C library headers
+ .Cases({"assert.h", "complex.h", "ctype.h", "errno.h", "fenv.h"}, true)
+ .Cases({"float.h", "inttypes.h", "iso646.h", "limits.h", "locale.h"},
+ true)
+ .Cases({"math.h", "setjmp.h", "signal.h", "stdalign.h", "stdarg.h"}, true)
+ .Cases({"stdatomic.h", "stdbool.h", "stdckdint.h", "stdcountof.h"}, true)
+ .Cases({"stddef.h", "stdint.h", "stdio.h", "stdlib.h", "stdnoreturn.h"},
+ true)
+ .Cases({"string.h", "tgmath.h", "threads.h", "time.h", "uchar.h"}, true)
+ .Cases({"wchar.h", "wctype.h"}, true)
+
+ // C++ headers for C library facilities
+ .Cases({"cassert", "ccomplex", "cctype", "cerrno", "cfenv"}, true)
+ .Cases({"cfloat", "cinttypes", "ciso646", "climits", "clocale"}, true)
+ .Cases({"cmath", "csetjmp", "csignal", "cstdalign", "cstdarg"}, true)
+ .Cases({"cstdbool", "cstddef", "cstdint", "cstdio", "cstdlib"}, true)
+ .Cases({"cstring", "ctgmath", "ctime", "cuchar", "cwchar"}, true)
+ .Case("cwctype", true)
+
+ // C++ library headers
+ .Cases({"algorithm", "fstream", "list", "regex", "thread"}, true)
+ .Cases({"array", "functional", "locale", "scoped_allocator", "tuple"},
+ true)
+ .Cases({"atomic", "future", "map", "set", "type_traits"}, true)
+ .Cases(
+ {"bitset", "initializer_list", "memory", "shared_mutex", "typeindex"},
+ true)
+ .Cases({"chrono", "iomanip", "mutex", "sstream", "typeinfo"}, true)
+ .Cases({"codecvt", "ios", "new", "stack", "unordered_map"}, true)
+ .Cases({"complex", "iosfwd", "numeric", "stdexcept", "unordered_set"},
+ true)
+ .Cases(
+ {"condition_variable", "iostream", "ostream", "streambuf", "utility"},
+ true)
+ .Cases({"deque", "istream", "queue", "string", "valarray"}, true)
+ .Cases({"exception", "iterator", "random", "strstream", "vector"}, true)
+ .Cases({"forward_list", "limits", "ratio", "system_error"}, true)
+
+ // POSIX headers (which aren't also C headers)
+ .Cases({"aio.h", "arpa/inet.h", "cpio.h", "dirent.h", "dlfcn.h"}, true)
+ .Cases({"fcntl.h", "fmtmsg.h", "fnmatch.h", "ftw.h", "glob.h"}, true)
+ .Cases({"grp.h", "iconv.h", "langinfo.h", "libgen.h", "monetary.h"}, true)
+ .Cases({"mqueue.h", "ndbm.h", "net/if.h", "netdb.h", "netinet/in.h"},
+ true)
+ .Cases({"netinet/tcp.h", "nl_types.h", "poll.h", "pthread.h", "pwd.h"},
+ true)
+ .Cases({"regex.h", "sched.h", "search.h", "semaphore.h", "spawn.h"}, true)
+ .Cases({"strings.h", "stropts.h", "sys/ipc.h", "sys/mman.h", "sys/msg.h"},
+ true)
+ .Cases({"sys/resource.h", "sys/select.h", "sys/sem.h", "sys/shm.h",
+ "sys/socket.h"},
+ true)
+ .Cases({"sys/stat.h", "sys/statvfs.h", "sys/time.h", "sys/times.h",
+ "sys/types.h"},
+ true)
+ .Cases(
+ {"sys/uio.h", "sys/un.h", "sys/utsname.h", "sys/wait.h", "syslog.h"},
+ true)
+ .Cases({"tar.h", "termios.h", "trace.h", "ulimit.h"}, true)
+ .Cases({"unistd.h", "utime.h", "utmpx.h", "wordexp.h"}, true)
+ .Default(false);
}
/// Find a similar string in `Candidates`.
@@ -3648,14 +3665,14 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
std::pair<tok::TokenKind, SourceLocation> Matches) {
Diag(CurTok, diag::err_expected) << Expected;
Diag(Matches.second, diag::note_matching) << Matches.first;
- if (CurTok.isNot(tok::eod))
+ if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
};
auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) {
if (CurTok.isNot(Kind)) {
Diag(CurTok, diag::err_expected) << Kind;
- if (CurTok.isNot(tok::eod))
+ if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
return false;
}
@@ -3746,7 +3763,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
if (Result.isNegative()) {
Diag(CurTok, diag::err_requires_positive_value)
<< toString(Result, 10) << /*positive*/ 0;
- if (CurTok.isNot(tok::eod))
+ if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
return std::nullopt;
}
@@ -3889,7 +3906,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) {
}
if (!ForHasEmbed) {
Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 << Parameter;
- if (CurTok.isNot(tok::eod))
+ if (CurTok.isNot(EndTokenKind))
DiscardUntilEndOfDirective(CurTok);
return std::nullopt;
}
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index dec1956..dd80ae5 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1262,16 +1262,11 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) {
std::optional<LexEmbedParametersResult> Params =
this->LexEmbedParameters(Tok, /*ForHasEmbed=*/true);
- assert((Params || Tok.is(tok::eod)) &&
- "expected success or to be at the end of the directive");
if (!Params)
return EmbedResult::Invalid;
- if (Params->UnrecognizedParams > 0)
- return EmbedResult::NotFound;
-
- if (!Tok.is(tok::r_paren)) {
+ if (Tok.isNot(tok::r_paren)) {
Diag(this->getLocForEndOfToken(FilenameLoc), diag::err_pp_expected_after)
<< II << tok::r_paren;
Diag(LParenLoc, diag::note_matching) << tok::l_paren;
@@ -1280,6 +1275,9 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) {
return EmbedResult::Invalid;
}
+ if (Params->UnrecognizedParams > 0)
+ return EmbedResult::NotFound;
+
SmallString<128> FilenameBuffer;
StringRef Filename = this->getSpelling(FilenameTok, FilenameBuffer);
if (Filename.empty())
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index bbff627..ec01faf 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1272,7 +1272,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// tokens and store them for late parsing at the end of the translation unit.
if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&
TemplateInfo.Kind == ParsedTemplateKind::Template &&
- Actions.canDelayFunctionBody(D)) {
+ LateParsedAttrs->empty() && Actions.canDelayFunctionBody(D)) {
MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams);
ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
@@ -1301,10 +1301,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
}
return DP;
}
- else if (CurParsedObjCImpl &&
- !TemplateInfo.TemplateParams &&
- (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
- Tok.is(tok::colon)) &&
+ if (CurParsedObjCImpl && !TemplateInfo.TemplateParams &&
+ (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) || Tok.is(tok::colon)) &&
Actions.CurContext->isTranslationUnit()) {
ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
Scope::CompoundStmtScope);
@@ -1420,7 +1418,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// Late attributes are parsed in the same scope as the function body.
if (LateParsedAttrs)
- ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);
+ ParseLexedAttributeList(*LateParsedAttrs, Res, /*EnterScope=*/false,
+ /*OnDefinition=*/true);
if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&
trySkippingFunctionBody()) {
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index db14349..e797400 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -361,11 +361,11 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
if (!Callee->getIdentifier())
return false;
return llvm::StringSwitch<bool>(Callee->getName())
- .Cases("begin", "rbegin", "cbegin", "crbegin", true)
- .Cases("end", "rend", "cend", "crend", true)
- .Cases("c_str", "data", "get", true)
+ .Cases({"begin", "rbegin", "cbegin", "crbegin"}, true)
+ .Cases({"end", "rend", "cend", "crend"}, true)
+ .Cases({"c_str", "data", "get"}, true)
// Map and set types.
- .Cases("find", "equal_range", "lower_bound", "upper_bound", true)
+ .Cases({"find", "equal_range", "lower_bound", "upper_bound"}, true)
.Default(false);
}
if (Callee->getReturnType()->isReferenceType()) {
@@ -377,7 +377,7 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
OO == OverloadedOperatorKind::OO_Star;
}
return llvm::StringSwitch<bool>(Callee->getName())
- .Cases("front", "back", "at", "top", "value", true)
+ .Cases({"front", "back", "at", "top", "value"}, true)
.Default(false);
}
return false;
@@ -394,14 +394,14 @@ static bool shouldTrackFirstArgument(const FunctionDecl *FD) {
if (FD->getReturnType()->isPointerType() ||
isRecordWithAttr<PointerAttr>(FD->getReturnType())) {
return llvm::StringSwitch<bool>(FD->getName())
- .Cases("begin", "rbegin", "cbegin", "crbegin", true)
- .Cases("end", "rend", "cend", "crend", true)
+ .Cases({"begin", "rbegin", "cbegin", "crbegin"}, true)
+ .Cases({"end", "rend", "cend", "crend"}, true)
.Case("data", true)
.Default(false);
}
if (FD->getReturnType()->isReferenceType()) {
return llvm::StringSwitch<bool>(FD->getName())
- .Cases("get", "any_cast", true)
+ .Cases({"get", "any_cast"}, true)
.Default(false);
}
return false;
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index f8d61d9..b09e168 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -102,7 +102,7 @@ Sema::ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message,
break;
for (const Type *T = TD->getUnderlyingType().getTypePtr(); /**/; /**/) {
if (auto *TT = dyn_cast<TagType>(T)) {
- D = TT->getOriginalDecl()->getDefinitionOrSelf();
+ D = TT->getDecl()->getDefinitionOrSelf();
} else if (isa<SubstTemplateTypeParmType>(T)) {
// A Subst* node represents a use through a template.
// Any uses of the underlying declaration happened through it's template
@@ -1019,7 +1019,7 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) {
return true;
if (const auto *TT = dyn_cast<TagType>(TyPtr)) {
- TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf();
+ TagDecl *TD = TT->getDecl()->getDefinitionOrSelf();
DiagnoseDeclAvailability(TD, Range);
} else if (const auto *TD = dyn_cast<TypedefType>(TyPtr)) {
diff --git a/clang/lib/Sema/SemaBPF.cpp b/clang/lib/Sema/SemaBPF.cpp
index be890ab..a9761764 100644
--- a/clang/lib/Sema/SemaBPF.cpp
+++ b/clang/lib/Sema/SemaBPF.cpp
@@ -57,7 +57,7 @@ static bool isValidPreserveTypeInfoArg(Expr *Arg) {
// Record type or Enum type.
if (const auto *RT = ArgType->getAsCanonical<TagType>())
- if (!RT->getOriginalDecl()->getDeclName().isEmpty())
+ if (!RT->getDecl()->getDeclName().isEmpty())
return true;
return false;
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 97ba1a51..c52fc5b 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -31,8 +31,7 @@ static CXXRecordDecl *getCurrentInstantiationOf(QualType T,
const TagType *TagTy = dyn_cast<TagType>(T->getCanonicalTypeInternal());
if (!isa_and_present<RecordType, InjectedClassNameType>(TagTy))
return nullptr;
- auto *RD =
- cast<CXXRecordDecl>(TagTy->getOriginalDecl())->getDefinitionOrSelf();
+ auto *RD = cast<CXXRecordDecl>(TagTy->getDecl())->getDefinitionOrSelf();
if (isa<InjectedClassNameType>(TagTy) ||
RD->isCurrentInstantiation(CurContext))
return RD;
@@ -121,7 +120,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
}
} else if (const auto *RecordT = dyn_cast<RecordType>(NNSType)) {
// The nested name specifier refers to a member of a class template.
- return RecordT->getOriginalDecl()->getDefinitionOrSelf();
+ return RecordT->getDecl()->getDefinitionOrSelf();
}
}
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index d986e3b..ddf17d8 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -962,7 +962,7 @@ void CastOperation::CheckDynamicCast() {
}
// C++ 5.2.7p6: Otherwise, v shall be [polymorphic].
- const RecordDecl *SrcDecl = SrcRecord->getOriginalDecl()->getDefinition();
+ const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition();
assert(SrcDecl && "Definition missing");
if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
@@ -1453,7 +1453,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
// converted to an integral type. [...] A value of a scoped enumeration type
// can also be explicitly converted to a floating-point type [...].
if (const EnumType *Enum = dyn_cast<EnumType>(SrcType)) {
- if (Enum->getOriginalDecl()->isScoped()) {
+ if (Enum->getDecl()->isScoped()) {
if (DestType->isBooleanType()) {
Kind = CK_IntegralToBoolean;
return TC_Success;
@@ -3105,7 +3105,7 @@ void CastOperation::CheckCStyleCast() {
}
// GCC's cast to union extension.
- if (RecordDecl *RD = DestRecordTy->getOriginalDecl(); RD->isUnion()) {
+ if (RecordDecl *RD = DestRecordTy->getDecl(); RD->isUnion()) {
if (CastExpr::getTargetFieldForToUnionCast(RD->getDefinitionOrSelf(),
SrcType)) {
Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 063db05..4f409ca 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3580,9 +3580,8 @@ static bool CheckNonNullExpr(Sema &S, const Expr *Expr) {
// As a special case, transparent unions initialized with zero are
// considered null for the purposes of the nonnull attribute.
if (const RecordType *UT = Expr->getType()->getAsUnionType();
- UT && UT->getOriginalDecl()
- ->getMostRecentDecl()
- ->hasAttr<TransparentUnionAttr>()) {
+ UT &&
+ UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
if (const auto *CLE = dyn_cast<CompoundLiteralExpr>(Expr))
if (const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
Expr = ILE->getInit(0);
@@ -12879,8 +12878,8 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
if (const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
if (const EnumType *TargetEnum = Target->getAsCanonical<EnumType>())
- if (SourceEnum->getOriginalDecl()->hasNameForLinkage() &&
- TargetEnum->getOriginalDecl()->hasNameForLinkage() &&
+ if (SourceEnum->getDecl()->hasNameForLinkage() &&
+ TargetEnum->getDecl()->hasNameForLinkage() &&
SourceEnum != TargetEnum) {
if (SourceMgr.isInSystemMacro(CC))
return;
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 5dd4949..0514d10 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -2070,7 +2070,7 @@ static const char *GetCompletionTypeString(QualType T, ASTContext &Context,
// Anonymous tag types are constant strings.
if (const TagType *TagT = dyn_cast<TagType>(T))
- if (TagDecl *Tag = TagT->getOriginalDecl())
+ if (TagDecl *Tag = TagT->getDecl())
if (!Tag->hasNameForLinkage()) {
switch (Tag->getTagKind()) {
case TagTypeKind::Struct:
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 229e91e..c0aba83 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -640,10 +640,9 @@ static void checkNoThrow(Sema &S, const Stmt *E,
QualType::DestructionKind::DK_cxx_destructor) {
const auto *T =
cast<RecordType>(ReturnType.getCanonicalType().getTypePtr());
- checkDeclNoexcept(cast<CXXRecordDecl>(T->getOriginalDecl())
- ->getDefinition()
- ->getDestructor(),
- /*IsDtor=*/true);
+ checkDeclNoexcept(
+ cast<CXXRecordDecl>(T->getDecl())->getDefinition()->getDestructor(),
+ /*IsDtor=*/true);
}
} else
for (const auto *Child : E->children()) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8ac09c4..04d46d6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13816,13 +13816,20 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
VDecl->setInvalidDecl();
}
- // C++ [module.import/6] external definitions are not permitted in header
- // units.
+ // C++ [module.import/6]
+ // ...
+ // A header unit shall not contain a definition of a non-inline function or
+ // variable whose name has external linkage.
+ //
+ // We choose to allow weak & selectany definitions, as they are common in
+ // headers, and have semantics similar to inline definitions which are allowed
+ // in header units.
if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
!VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
VDecl->getFormalLinkage() == Linkage::External && !VDecl->isInline() &&
!VDecl->isTemplated() && !isa<VarTemplateSpecializationDecl>(VDecl) &&
- !VDecl->getInstantiatedFromStaticDataMember()) {
+ !VDecl->getInstantiatedFromStaticDataMember() &&
+ !(VDecl->hasAttr<SelectAnyAttr>() || VDecl->hasAttr<WeakAttr>())) {
Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
VDecl->setInvalidDecl();
}
@@ -16153,16 +16160,24 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
}
}
- // C++ [module.import/6] external definitions are not permitted in header
- // units. Deleted and Defaulted functions are implicitly inline (but the
+ // C++ [module.import/6]
+ // ...
+ // A header unit shall not contain a definition of a non-inline function or
+ // variable whose name has external linkage.
+ //
+ // Deleted and Defaulted functions are implicitly inline (but the
// inline state is not set at this point, so check the BodyKind explicitly).
+ // We choose to allow weak & selectany definitions, as they are common in
+ // headers, and have semantics similar to inline definitions which are allowed
+ // in header units.
// FIXME: Consider an alternate location for the test where the inlined()
// state is complete.
if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
!FD->isInvalidDecl() && !FD->isInlined() &&
BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default &&
FD->getFormalLinkage() == Linkage::External && !FD->isTemplated() &&
- !FD->isTemplateInstantiation()) {
+ !FD->isTemplateInstantiation() &&
+ !(FD->hasAttr<SelectAnyAttr>() || FD->hasAttr<WeakAttr>())) {
assert(FD->isThisDeclarationADefinition());
Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
FD->setInvalidDecl();
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 3107876..e6f8748 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1255,7 +1255,7 @@ bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
// The nonnull attribute, and other similar attributes, can be applied to a
// transparent union that contains a pointer type.
if (const RecordType *UT = T->getAsUnionType()) {
- RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf();
if (UD->hasAttr<TransparentUnionAttr>()) {
for (const auto *I : UD->fields()) {
QualType QT = I->getType();
@@ -3629,18 +3629,20 @@ static FormatAttrKind getFormatAttrKind(StringRef Format) {
// Check for formats that get handled specially.
.Case("NSString", NSStringFormat)
.Case("CFString", CFStringFormat)
- .Cases("gnu_strftime", "strftime", StrftimeFormat)
+ .Cases({"gnu_strftime", "strftime"}, StrftimeFormat)
// Otherwise, check for supported formats.
- .Cases("gnu_scanf", "scanf", "gnu_printf", "printf", "printf0",
- "gnu_strfmon", "strfmon", SupportedFormat)
- .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
- .Cases("kprintf", "syslog", SupportedFormat) // OpenBSD.
- .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
+ .Cases({"gnu_scanf", "scanf", "gnu_printf", "printf", "printf0",
+ "gnu_strfmon", "strfmon"},
+ SupportedFormat)
+ .Cases({"cmn_err", "vcmn_err", "zcmn_err"}, SupportedFormat)
+ .Cases({"kprintf", "syslog"}, SupportedFormat) // OpenBSD.
+ .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
.Case("os_trace", SupportedFormat)
.Case("os_log", SupportedFormat)
- .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
+ .Cases({"gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag"},
+ IgnoredFormat)
.Default(InvalidFormat);
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 215431c..d41ab12 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -5630,7 +5630,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl<const void*> &IdealInits) {
if (const RecordType *RT = Field->getType()->getAsCanonical<RecordType>()) {
- const RecordDecl *RD = RT->getOriginalDecl();
+ const RecordDecl *RD = RT->getDecl();
if (RD->isAnonymousStructOrUnion()) {
for (auto *Field : RD->getDefinitionOrSelf()->fields())
PopulateKeysForFields(Field, IdealInits);
@@ -7630,9 +7630,8 @@ static bool defaultedSpecialMemberIsConstexpr(
continue;
QualType BaseType = S.Context.getBaseElementType(F->getType());
if (const RecordType *RecordTy = BaseType->getAsCanonical<RecordType>()) {
- CXXRecordDecl *FieldRecDecl =
- cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
- ->getDefinitionOrSelf();
+ auto *FieldRecDecl =
+ cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf();
if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM,
BaseType.getCVRQualifiers(),
ConstArg && !F->isMutable()))
@@ -10645,7 +10644,7 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) {
if (const auto *RT =
FT->getBaseElementTypeUnsafe()->getAsCanonical<RecordType>())
if (!RT->isDependentType() &&
- !cast<CXXRecordDecl>(RT->getOriginalDecl()->getDefinitionOrSelf())
+ !cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf())
->canPassInRegisters()) {
PrintDiagAndRemoveAttr(5);
return;
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 98eb5af..3df9f9c 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -3232,10 +3232,8 @@ static bool tryMatchRecordTypes(ASTContext &Context,
assert(lt && rt && lt != rt);
if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false;
- RecordDecl *left =
- cast<RecordType>(lt)->getOriginalDecl()->getDefinitionOrSelf();
- RecordDecl *right =
- cast<RecordType>(rt)->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *left = cast<RecordType>(lt)->getDecl()->getDefinitionOrSelf();
+ RecordDecl *right = cast<RecordType>(rt)->getDecl()->getDefinitionOrSelf();
// Require union-hood to match.
if (left->isUnion() != right->isUnion()) return false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 01abc1f..3e0e9bb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1535,12 +1535,8 @@ void Sema::checkEnumArithmeticConversions(Expr *LHS, Expr *RHS,
// are ill-formed.
if (getLangOpts().CPlusPlus26)
DiagID = diag::warn_conv_mixed_enum_types_cxx26;
- else if (!L->castAsCanonical<EnumType>()
- ->getOriginalDecl()
- ->hasNameForLinkage() ||
- !R->castAsCanonical<EnumType>()
- ->getOriginalDecl()
- ->hasNameForLinkage()) {
+ else if (!L->castAsCanonical<EnumType>()->getDecl()->hasNameForLinkage() ||
+ !R->castAsCanonical<EnumType>()->getDecl()->hasNameForLinkage()) {
// If either enumeration type is unnamed, it's less likely that the
// user cares about this, but this situation is still deprecated in
// C++2a. Use a different warning group.
@@ -7095,7 +7091,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
for (unsigned i = 0, e = Args.size(); i != e; i++) {
if (const auto *RT =
dyn_cast<RecordType>(Args[i]->getType().getCanonicalType())) {
- if (RT->getOriginalDecl()->isOrContainsUnion())
+ if (RT->getDecl()->isOrContainsUnion())
Diag(Args[i]->getBeginLoc(), diag::warn_cmse_nonsecure_union)
<< 0 << i;
}
@@ -9748,7 +9744,7 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType,
if (!UT)
return AssignConvertType::Incompatible;
- RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf();
if (!UD->hasAttr<TransparentUnionAttr>())
return AssignConvertType::Incompatible;
@@ -10844,7 +10840,7 @@ static void diagnoseScopedEnums(Sema &S, const SourceLocation Loc,
auto DiagnosticHelper = [&S](const Expr *expr, const QualType type) {
SourceLocation BeginLoc = expr->getBeginLoc();
QualType IntType = type->castAs<EnumType>()
- ->getOriginalDecl()
+ ->getDecl()
->getDefinitionOrSelf()
->getIntegerType();
std::string InsertionString = "static_cast<" + IntType.getAsString() + ">(";
@@ -11533,7 +11529,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
static bool isScopedEnumerationType(QualType T) {
if (const EnumType *ET = T->getAsCanonical<EnumType>())
- return ET->getOriginalDecl()->isScoped();
+ return ET->getDecl()->isScoped();
return false;
}
@@ -13839,7 +13835,7 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD,
while (RecordTypeList.size() > NextToCheckIndex) {
bool IsNested = NextToCheckIndex > 0;
for (const FieldDecl *Field : RecordTypeList[NextToCheckIndex]
- ->getOriginalDecl()
+ ->getDecl()
->getDefinitionOrSelf()
->fields()) {
// First, check every field for constness.
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 0fe242dce..fe1f89b 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1988,7 +1988,7 @@ static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc,
DeclarationName deleteName =
S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName);
- S.LookupQualifiedName(ops, record->getOriginalDecl()->getDefinitionOrSelf());
+ S.LookupQualifiedName(ops, record->getDecl()->getDefinitionOrSelf());
// We're just doing this for information.
ops.suppressDiagnostics();
@@ -6667,8 +6667,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
// That should be enough to guarantee that this type is complete, if we're
// not processing a decltype expression.
- CXXRecordDecl *RD =
- cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
+ auto *RD = cast<CXXRecordDecl>(RT->getDecl())->getDefinitionOrSelf();
if (RD->isInvalidDecl() || RD->isDependentContext())
return E;
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 331f6e5..4daf0170 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -3846,8 +3846,7 @@ static inline T *getObjCBridgeAttr(const TypedefType *TD) {
if (QT->isPointerType()) {
QT = QT->getPointeeType();
if (const RecordType *RT = QT->getAsCanonical<RecordType>()) {
- for (auto *Redecl :
- RT->getOriginalDecl()->getMostRecentDecl()->redecls()) {
+ for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
if (auto *attr = Redecl->getAttr<T>())
return attr;
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 72b2ac9..f347066 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -782,7 +782,7 @@ bool SemaHLSL::isSemanticValid(FunctionDecl *FD, DeclaratorDecl *D) {
if (!RT)
return false;
- const RecordDecl *RD = RT->getOriginalDecl();
+ const RecordDecl *RD = RT->getDecl();
for (FieldDecl *Field : RD->fields()) {
if (!isSemanticValid(FD, Field))
return false;
@@ -1986,7 +1986,7 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) {
// requirements and adds them to Bindings
void SemaHLSL::collectResourceBindingsOnUserRecordDecl(const VarDecl *VD,
const RecordType *RT) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
for (FieldDecl *FD : RD->fields()) {
const Type *Ty = FD->getType()->getUnqualifiedDesugaredType();
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 543db46..f7974eb 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -775,7 +775,7 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
if (Init >= NumInits || !ILE->getInit(Init)) {
if (const RecordType *RType = ILE->getType()->getAsCanonical<RecordType>())
- if (!RType->getOriginalDecl()->isUnion())
+ if (!RType->getDecl()->isUnion())
assert((Init < NumInits || VerifyOnly) &&
"This ILE should have been expanded");
@@ -9186,9 +9186,8 @@ bool InitializationSequence::Diagnose(Sema &S,
diag::note_member_declared_at);
if (const auto *Record = Entity.getType()->getAs<RecordType>())
- S.Diag(Record->getOriginalDecl()->getLocation(),
- diag::note_previous_decl)
- << S.Context.getCanonicalTagType(Record->getOriginalDecl());
+ S.Diag(Record->getDecl()->getLocation(), diag::note_previous_decl)
+ << S.Context.getCanonicalTagType(Record->getDecl());
}
break;
}
@@ -9974,8 +9973,8 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
// Cases where template arguments in the RHS of the alias are not
// dependent. e.g.
// using AliasFoo = Foo<bool>;
- if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(
- RT->getOriginalDecl()))
+ if (const auto *CTSD =
+ llvm::dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
Template = CTSD->getSpecializedTemplate();
}
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 25728de..5915d6e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -2727,9 +2727,7 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
IsDependent = !DC && ObjectType->isDependentType();
assert(((!DC && ObjectType->isDependentType()) ||
!ObjectType->isIncompleteType() || !ObjectType->getAs<TagType>() ||
- ObjectType->castAs<TagType>()
- ->getOriginalDecl()
- ->isEntityBeingDefined()) &&
+ ObjectType->castAs<TagType>()->getDecl()->isEntityBeingDefined()) &&
"Caller should have completed object type");
} else if (SS && SS->isNotEmpty()) {
// This nested-name-specifier occurs after another nested-name-specifier,
@@ -3191,9 +3189,8 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
// namespaces of its associated classes.
case Type::Record: {
// FIXME: This should use the original decl.
- CXXRecordDecl *Class =
- cast<CXXRecordDecl>(cast<RecordType>(T)->getOriginalDecl())
- ->getDefinitionOrSelf();
+ auto *Class = cast<CXXRecordDecl>(cast<RecordType>(T)->getDecl())
+ ->getDefinitionOrSelf();
addAssociatedClassesAndNamespaces(Result, Class);
break;
}
@@ -4606,7 +4603,7 @@ static void getNestedNameSpecifierIdentifiers(
case Type::InjectedClassName: {
auto *TT = cast<TagType>(T);
getNestedNameSpecifierIdentifiers(TT->getQualifier(), Identifiers);
- Identifiers.push_back(TT->getOriginalDecl()->getIdentifier());
+ Identifiers.push_back(TT->getDecl()->getIdentifier());
return;
}
case Type::Typedef: {
diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp
index 4f9470a..7aaa56e 100644
--- a/clang/lib/Sema/SemaObjC.cpp
+++ b/clang/lib/Sema/SemaObjC.cpp
@@ -1407,7 +1407,7 @@ SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) {
int NoIntegrals = 0, NoObjCIdPointers = 0;
SmallVector<CXXConversionDecl *, 4> ConversionDecls;
- for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
+ for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl())
->getDefinitionOrSelf()
->getVisibleConversionFunctions()) {
if (CXXConversionDecl *Conversion =
@@ -1511,7 +1511,7 @@ bool SemaObjC::isCFStringType(QualType T) {
if (!RT)
return false;
- const RecordDecl *RD = RT->getOriginalDecl();
+ const RecordDecl *RD = RT->getDecl();
if (RD->getTagKind() != TagTypeKind::Struct)
return false;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8339bb1..7da09e8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -2594,7 +2594,7 @@ IsTransparentUnionStandardConversion(Sema &S, Expr* From,
if (!UT)
return false;
// The field to initialize within the transparent union.
- const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf();
if (!UD->hasAttr<TransparentUnionAttr>())
return false;
// It's compatible if the expression matches any of the fields.
@@ -3973,7 +3973,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
if (!S.isCompleteType(From->getExprLoc(), ToType)) {
// We're not going to find any constructors.
} else if (auto *ToRecordDecl =
- dyn_cast<CXXRecordDecl>(ToRecordType->getOriginalDecl())) {
+ dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
ToRecordDecl = ToRecordDecl->getDefinitionOrSelf();
Expr **Args = &From;
@@ -4048,7 +4048,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
} else if (const RecordType *FromRecordType =
From->getType()->getAsCanonical<RecordType>()) {
if (auto *FromRecordDecl =
- dyn_cast<CXXRecordDecl>(FromRecordType->getOriginalDecl())) {
+ dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
FromRecordDecl = FromRecordDecl->getDefinitionOrSelf();
// Add all of the conversion functions as candidates.
const auto &Conversions = FromRecordDecl->getVisibleConversionFunctions();
@@ -6840,7 +6840,7 @@ ExprResult Sema::PerformContextualImplicitConversion(
UnresolvedSet<4>
ViableConversions; // These are *potentially* viable in C++1y.
UnresolvedSet<4> ExplicitConversions;
- const auto &Conversions = cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
+ const auto &Conversions = cast<CXXRecordDecl>(RecordTy->getDecl())
->getDefinitionOrSelf()
->getVisibleConversionFunctions();
@@ -10194,9 +10194,7 @@ public:
if (S.getLangOpts().CPlusPlus11) {
for (QualType EnumTy : CandidateTypes[ArgIdx].enumeration_types()) {
- if (!EnumTy->castAsCanonical<EnumType>()
- ->getOriginalDecl()
- ->isScoped())
+ if (!EnumTy->castAsCanonical<EnumType>()->getDecl()->isScoped())
continue;
if (!AddedTypes.insert(S.Context.getCanonicalType(EnumTy)).second)
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index b981c35..67f3856 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -221,8 +221,8 @@ static SourceLocation SourceLocationForUserDeclaredType(QualType QT) {
SourceLocation Loc;
const Type *T = QT->getUnqualifiedDesugaredType();
if (const TagType *TT = dyn_cast<TagType>(T))
- Loc = TT->getOriginalDecl()->getLocation();
- else if (const ObjCInterfaceType *ObjCIT = dyn_cast<ObjCInterfaceType>(T))
+ Loc = TT->getDecl()->getLocation();
+ else if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(T))
Loc = ObjCIT->getDecl()->getLocation();
return Loc;
}
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index ae0bb616..f398963 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1277,11 +1277,11 @@ static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond,
return;
// Ignore anonymous enums.
- if (!CondEnumType->getOriginalDecl()->getIdentifier() &&
- !CondEnumType->getOriginalDecl()->getTypedefNameForAnonDecl())
+ if (!CondEnumType->getDecl()->getIdentifier() &&
+ !CondEnumType->getDecl()->getTypedefNameForAnonDecl())
return;
- if (!CaseEnumType->getOriginalDecl()->getIdentifier() &&
- !CaseEnumType->getOriginalDecl()->getTypedefNameForAnonDecl())
+ if (!CaseEnumType->getDecl()->getIdentifier() &&
+ !CaseEnumType->getDecl()->getTypedefNameForAnonDecl())
return;
if (S.Context.hasSameUnqualifiedType(CondType, CaseType))
@@ -3760,7 +3760,7 @@ private:
Sema &S;
};
bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {
- auto *R = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
+ auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl());
if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
R->isDependentType())
return true;
@@ -3979,7 +3979,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
<< RetValExp->getSourceRange();
if (FD->hasAttr<CmseNSEntryAttr>() && RetValExp) {
if (const auto *RT = dyn_cast<RecordType>(FnRetType.getCanonicalType())) {
- if (RT->getOriginalDecl()->isOrContainsUnion())
+ if (RT->getDecl()->isOrContainsUnion())
Diag(RetValExp->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 1;
}
}
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 0438af7..f957bdf 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -908,7 +908,7 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
LookupResult FieldResult(*this, &Context.Idents.get(NextMember),
SourceLocation(), LookupMemberName);
- RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
if (!LookupQualifiedName(FieldResult, RD))
return true;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3a6ff99..2cc6593 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -408,9 +408,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, Scope *S, CXXScopeSpec &SS,
IsDependent = !LookupCtx && ObjectType->isDependentType();
assert((IsDependent || !ObjectType->isIncompleteType() ||
!ObjectType->getAs<TagType>() ||
- ObjectType->castAs<TagType>()
- ->getOriginalDecl()
- ->isEntityBeingDefined()) &&
+ ObjectType->castAs<TagType>()->getDecl()->isEntityBeingDefined()) &&
"Caller should have completed object type");
// Template names cannot appear inside an Objective-C class or object type
@@ -1819,7 +1817,7 @@ public:
}
bool VisitTagType(const TagType *T) override {
- return TraverseDecl(T->getOriginalDecl());
+ return TraverseDecl(T->getDecl());
}
bool TraverseDecl(const Decl *D) override {
@@ -2790,7 +2788,7 @@ struct DependencyChecker : DynamicRecursiveASTVisitor {
// An InjectedClassNameType will never have a dependent template name,
// so no need to traverse it.
return TraverseTemplateArguments(
- T->getTemplateArgs(T->getOriginalDecl()->getASTContext()));
+ T->getTemplateArgs(T->getDecl()->getASTContext()));
}
};
} // end anonymous namespace
@@ -2914,7 +2912,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
if (const EnumType *EnumT = T->getAsCanonical<EnumType>()) {
// FIXME: Forward-declared enums require a TSK_ExplicitSpecialization
// check here.
- EnumDecl *Enum = EnumT->getOriginalDecl();
+ EnumDecl *Enum = EnumT->getDecl();
// Get to the parent type.
if (TypeDecl *Parent = dyn_cast<TypeDecl>(Enum->getParent()))
@@ -3352,7 +3350,7 @@ static QualType builtinCommonTypeImpl(Sema &S, ElaboratedTypeKeyword Keyword,
}
static bool isInVkNamespace(const RecordType *RT) {
- DeclContext *DC = RT->getOriginalDecl()->getDeclContext();
+ DeclContext *DC = RT->getDecl()->getDeclContext();
if (!DC)
return false;
@@ -3369,9 +3367,8 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef,
if (auto *RT = OperandArg->getAsCanonical<RecordType>()) {
bool Literal = false;
SourceLocation LiteralLoc;
- if (isInVkNamespace(RT) && RT->getOriginalDecl()->getName() == "Literal") {
- auto SpecDecl =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
+ if (isInVkNamespace(RT) && RT->getDecl()->getName() == "Literal") {
+ auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
assert(SpecDecl);
const TemplateArgumentList &LiteralArgs = SpecDecl->getTemplateArgs();
@@ -3382,9 +3379,8 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef,
}
if (RT && isInVkNamespace(RT) &&
- RT->getOriginalDecl()->getName() == "integral_constant") {
- auto SpecDecl =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
+ RT->getDecl()->getName() == "integral_constant") {
+ auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
assert(SpecDecl);
const TemplateArgumentList &ConstantArgs = SpecDecl->getTemplateArgs();
@@ -4110,7 +4106,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK,
// Check the tag kind
if (const RecordType *RT = Result->getAs<RecordType>()) {
- RecordDecl *D = RT->getOriginalDecl();
+ RecordDecl *D = RT->getDecl();
IdentifierInfo *Id = D->getIdentifier();
assert(Id && "templated class must have an identifier");
@@ -6383,11 +6379,11 @@ bool UnnamedLocalNoLinkageFinder::VisitDeducedTemplateSpecializationType(
}
bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* T) {
- return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf());
+ return VisitTagDecl(T->getDecl()->getDefinitionOrSelf());
}
bool UnnamedLocalNoLinkageFinder::VisitEnumType(const EnumType* T) {
- return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf());
+ return VisitTagDecl(T->getDecl()->getDefinitionOrSelf());
}
bool UnnamedLocalNoLinkageFinder::VisitTemplateTypeParmType(
@@ -6412,7 +6408,7 @@ bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType(
bool UnnamedLocalNoLinkageFinder::VisitInjectedClassNameType(
const InjectedClassNameType* T) {
- return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf());
+ return VisitTagDecl(T->getDecl()->getDefinitionOrSelf());
}
bool UnnamedLocalNoLinkageFinder::VisitDependentNameType(
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 3baa977..6964242 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5577,7 +5577,7 @@ static TemplateDeductionResult CheckDeductionConsistency(
bool IsDeductionGuide = isa<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
if (IsDeductionGuide) {
if (auto *Injected = P->getAsCanonical<InjectedClassNameType>())
- P = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType(
+ P = Injected->getDecl()->getCanonicalTemplateSpecializationType(
S.Context);
}
QualType InstP = S.SubstType(P.getCanonicalType(), MLTAL, FTD->getLocation(),
@@ -5598,10 +5598,10 @@ static TemplateDeductionResult CheckDeductionConsistency(
auto T2 = S.Context.getUnqualifiedArrayType(A.getNonReferenceType());
if (IsDeductionGuide) {
if (auto *Injected = T1->getAsCanonical<InjectedClassNameType>())
- T1 = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType(
+ T1 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
S.Context);
if (auto *Injected = T2->getAsCanonical<InjectedClassNameType>())
- T2 = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType(
+ T2 = Injected->getDecl()->getCanonicalTemplateSpecializationType(
S.Context);
}
if (!S.Context.hasSameType(T1, T2))
@@ -6973,7 +6973,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
case Type::InjectedClassName:
T = cast<InjectedClassNameType>(T)
- ->getOriginalDecl()
+ ->getDecl()
->getCanonicalTemplateSpecializationType(Ctx);
[[fallthrough]];
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 8ba23aa..ad50600 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -996,7 +996,7 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
// dependent. e.g.
// using AliasFoo = Foo<bool>;
if (const auto *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl())) {
+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) {
Template = CTSD->getSpecializedTemplate();
AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
}
@@ -1054,12 +1054,11 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
// such that T can be deduced as U.
auto RType = F->getTemplatedDecl()->getReturnType();
// The (trailing) return type of the deduction guide.
- const TemplateSpecializationType *FReturnType =
- RType->getAs<TemplateSpecializationType>();
+ const auto *FReturnType = RType->getAs<TemplateSpecializationType>();
if (const auto *ICNT = RType->getAsCanonical<InjectedClassNameType>())
// implicitly-generated deduction guide.
FReturnType = cast<TemplateSpecializationType>(
- ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType(
+ ICNT->getDecl()->getCanonicalTemplateSpecializationType(
SemaRef.Context));
assert(FReturnType && "expected to see a return type");
// Deduce template arguments of the deduction guide f from the RHS of
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 7b05e4c..bec2820 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1681,7 +1681,7 @@ namespace {
ICNT && SemaRef.CodeSynthesisContexts.back().Kind ==
Sema::CodeSynthesisContext::BuildingDeductionGuides) {
Type = inherited::TransformType(
- ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType(
+ ICNT->getDecl()->getCanonicalTemplateSpecializationType(
SemaRef.Context));
TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc());
}
@@ -2105,7 +2105,7 @@ TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
if (const TagType *Tag = T->getAs<TagType>())
- return Tag->getOriginalDecl();
+ return Tag->getDecl();
// The resulting type is not a tag; complain.
getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 73fd33a..468bc1d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1522,9 +1522,9 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
// If the old typedef was the name for linkage purposes of an anonymous
// tag decl, re-establish that relationship for the new typedef.
if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) {
- TagDecl *oldTag = oldTagType->getOriginalDecl();
+ TagDecl *oldTag = oldTagType->getDecl();
if (oldTag->getTypedefNameForAnonDecl() == D && !Invalid) {
- TagDecl *newTag = DI->getType()->castAs<TagType>()->getOriginalDecl();
+ TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl();
assert(!newTag->hasNameForLinkage());
newTag->setTypedefNameForAnonDecl(Typedef);
}
@@ -5791,7 +5791,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
QualType TransformRecordType(TypeLocBuilder &TLB, RecordTypeLoc TL) {
const RecordType *T = TL.getTypePtr();
RecordDecl *Record = cast_or_null<RecordDecl>(
- getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl()));
+ getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
if (Record != OldDecl)
return Base::TransformRecordType(TLB, TL);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index a9e7c34..638904d 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1238,8 +1238,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
Result = S.GetTypeFromParser(DS.getRepAsType());
assert(!Result.isNull() && "Didn't get a type for typeof?");
if (!Result->isDependentType())
- if (const TagType *TT = Result->getAs<TagType>())
- S.DiagnoseUseOfDecl(TT->getOriginalDecl(), DS.getTypeSpecTypeLoc());
+ if (const auto *TT = Result->getAs<TagType>())
+ S.DiagnoseUseOfDecl(TT->getDecl(), DS.getTypeSpecTypeLoc());
// TypeQuals handled by caller.
Result = Context.getTypeOfType(
Result, DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualType
@@ -9699,7 +9699,7 @@ QualType Sema::BuildTypeofExprType(Expr *E, TypeOfKind Kind) {
if (!E->isTypeDependent()) {
QualType T = E->getType();
if (const TagType *TT = T->getAs<TagType>())
- DiagnoseUseOfDecl(TT->getOriginalDecl(), E->getExprLoc());
+ DiagnoseUseOfDecl(TT->getDecl(), E->getExprLoc());
}
return Context.getTypeOfExprType(E, Kind);
}
@@ -9865,7 +9865,7 @@ QualType Sema::BuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType,
SourceLocation Loc) {
assert(BaseType->isEnumeralType());
- EnumDecl *ED = BaseType->castAs<EnumType>()->getOriginalDecl();
+ EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
S.DiagnoseUseOfDecl(ED, Loc);
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index aca21cc..3887796 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -1624,9 +1624,9 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT,
// Unions are never base classes, and never have base classes.
// It doesn't matter if they are complete or not. See PR#41843
- if (lhsRecord && lhsRecord->getOriginalDecl()->isUnion())
+ if (lhsRecord && lhsRecord->getDecl()->isUnion())
return false;
- if (rhsRecord && rhsRecord->getOriginalDecl()->isUnion())
+ if (rhsRecord && rhsRecord->getDecl()->isUnion())
return false;
if (lhsRecord == rhsRecord)
@@ -1640,8 +1640,8 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT,
diag::err_incomplete_type_used_in_type_trait_expr))
return false;
- return cast<CXXRecordDecl>(rhsRecord->getOriginalDecl())
- ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getOriginalDecl()));
+ return cast<CXXRecordDecl>(rhsRecord->getDecl())
+ ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
}
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
@@ -1681,9 +1681,8 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
diag::err_incomplete_type))
return false;
- return cast<CXXRecordDecl>(DerivedRecord->getOriginalDecl())
- ->isVirtuallyDerivedFrom(
- cast<CXXRecordDecl>(BaseRecord->getOriginalDecl()));
+ return cast<CXXRecordDecl>(DerivedRecord->getDecl())
+ ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));
}
case BTT_IsSame:
return Self.Context.hasSameType(LhsT, RhsT);
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 04a5e4b..86896ab 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -7160,13 +7160,13 @@ QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
}
auto *TD = cast_or_null<TagDecl>(
- getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl()));
+ getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
if (!TD)
return QualType();
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
- TD != T->getOriginalDecl()) {
+ TD != T->getDecl()) {
if (T->isCanonicalUnqualified())
Result = getDerived().RebuildCanonicalTagType(TD);
else
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 32f7a0e..8b3fd41 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5504,7 +5504,7 @@ void ASTReader::InitializeContext() {
Error("Invalid FILE type in AST file");
return;
}
- Context.setFILEDecl(Tag->getOriginalDecl());
+ Context.setFILEDecl(Tag->getDecl());
}
}
}
@@ -5525,7 +5525,7 @@ void ASTReader::InitializeContext() {
Error("Invalid jmp_buf type in AST file");
return;
}
- Context.setjmp_bufDecl(Tag->getOriginalDecl());
+ Context.setjmp_bufDecl(Tag->getDecl());
}
}
}
@@ -5543,7 +5543,7 @@ void ASTReader::InitializeContext() {
else {
const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
assert(Tag && "Invalid sigjmp_buf type in AST file");
- Context.setsigjmp_bufDecl(Tag->getOriginalDecl());
+ Context.setsigjmp_bufDecl(Tag->getDecl());
}
}
}
@@ -5578,7 +5578,7 @@ void ASTReader::InitializeContext() {
else {
const TagType *Tag = Ucontext_tType->getAs<TagType>();
assert(Tag && "Invalid ucontext_t type in AST file");
- Context.setucontext_tDecl(Tag->getOriginalDecl());
+ Context.setucontext_tDecl(Tag->getDecl());
}
}
}
diff --git a/clang/lib/Serialization/TemplateArgumentHasher.cpp b/clang/lib/Serialization/TemplateArgumentHasher.cpp
index 3e8ffea..353e8a2 100644
--- a/clang/lib/Serialization/TemplateArgumentHasher.cpp
+++ b/clang/lib/Serialization/TemplateArgumentHasher.cpp
@@ -358,7 +358,7 @@ public:
AddQualType(T->getReplacementType());
}
- void VisitTagType(const TagType *T) { AddDecl(T->getOriginalDecl()); }
+ void VisitTagType(const TagType *T) { AddDecl(T->getDecl()); }
void VisitRecordType(const RecordType *T) { VisitTagType(T); }
void VisitEnumType(const EnumType *T) { VisitTagType(T); }
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index b304350..7cc146e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -246,7 +246,7 @@ public:
bool Find(const TypedValueRegion *R) {
QualType T = R->getValueType();
if (const RecordType *RT = T->getAsStructureType()) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
+ const RecordDecl *RD = RT->getDecl()->getDefinition();
assert(RD && "Referred record has no definition");
for (const auto *I : RD->fields()) {
if (I->isUnnamedBitField())
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index 17af1ae..5e75c1c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -154,15 +154,15 @@ void WalkAST::VisitCallExpr(CallExpr *CE) {
.Case("mkstemp", &WalkAST::checkCall_mkstemp)
.Case("mkdtemp", &WalkAST::checkCall_mkstemp)
.Case("mkstemps", &WalkAST::checkCall_mkstemp)
- .Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
- .Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
- .Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
- "vscanf", "vwscanf", "vfscanf", "vfwscanf",
+ .Cases({"strcpy", "__strcpy_chk"}, &WalkAST::checkCall_strcpy)
+ .Cases({"strcat", "__strcat_chk"}, &WalkAST::checkCall_strcat)
+ .Cases({"sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
+ "vscanf", "vwscanf", "vfscanf", "vfwscanf"},
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
- .Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
- "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove",
+ .Cases({"sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
+ "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove"},
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
- .Cases("strncpy", "strncat", "memset", "fprintf",
+ .Cases({"strncpy", "strncat", "memset", "fprintf"},
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
.Case("drand48", &WalkAST::checkCall_rand)
.Case("erand48", &WalkAST::checkCall_rand)
@@ -766,12 +766,14 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
int ArgIndex =
llvm::StringSwitch<int>(Name)
- .Cases("scanf", "wscanf", "vscanf", "vwscanf", 0)
- .Cases("fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf",
- "swscanf", "vsscanf", "vswscanf", 1)
- .Cases("sprintf", "vsprintf", "fprintf", 1)
- .Cases("swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy",
- "memmove", "memset", "strncpy", "strncat", DEPR_ONLY)
+ .Cases({"scanf", "wscanf", "vscanf", "vwscanf"}, 0)
+ .Cases({"fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf",
+ "swscanf", "vsscanf", "vswscanf"},
+ 1)
+ .Cases({"sprintf", "vsprintf", "fprintf"}, 1)
+ .Cases({"swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy",
+ "memmove", "memset", "strncpy", "strncat"},
+ DEPR_ONLY)
.Default(UNKNOWN_CALL);
assert(ArgIndex != UNKNOWN_CALL && "Unsupported function");
diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index 395d724..37f5ec3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -19,6 +19,7 @@
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -39,9 +40,10 @@ public:
class DereferenceChecker
: public CheckerFamily<check::Location, check::Bind,
+ check::PreStmt<BinaryOperator>,
EventDispatcher<ImplicitNullDerefEvent>> {
- void reportBug(const DerefBugType &BT, ProgramStateRef State, const Stmt *S,
- CheckerContext &C) const;
+ void reportDerefBug(const DerefBugType &BT, ProgramStateRef State,
+ const Stmt *S, CheckerContext &C) const;
bool suppressReport(CheckerContext &C, const Expr *E) const;
@@ -50,6 +52,7 @@ public:
CheckerContext &C) const;
void checkBind(SVal L, SVal V, const Stmt *S, bool AtDeclInit,
CheckerContext &C) const;
+ void checkPreStmt(const BinaryOperator *Op, CheckerContext &C) const;
static void AddDerefSource(raw_ostream &os,
SmallVectorImpl<SourceRange> &Ranges,
@@ -57,7 +60,7 @@ public:
const LocationContext *LCtx,
bool loadedFrom = false);
- CheckerFrontend NullDerefChecker, FixedDerefChecker;
+ CheckerFrontend NullDerefChecker, FixedDerefChecker, NullPointerArithmChecker;
const DerefBugType NullBug{&NullDerefChecker, "Dereference of null pointer",
"a null pointer dereference",
"a dereference of a null pointer"};
@@ -72,9 +75,22 @@ public:
const DerefBugType FixedAddressBug{&FixedDerefChecker,
"Dereference of a fixed address",
"a dereference of a fixed address"};
+ const BugType NullPointerArithmBug{
+ &NullPointerArithmChecker,
+ "Possibly undefined arithmetic operation involving a null pointer"};
StringRef getDebugTag() const override { return "DereferenceChecker"; }
};
+
+struct ValueDescStr {
+ SmallVectorImpl<SourceRange> &Ranges;
+ const Expr *Ex;
+ const ProgramState *State;
+ const LocationContext *LCtx;
+ bool IsPointer;
+ ConditionTruthVal IsNull;
+};
+
} // end anonymous namespace
void
@@ -173,9 +189,9 @@ static bool isDeclRefExprToReference(const Expr *E) {
return false;
}
-void DereferenceChecker::reportBug(const DerefBugType &BT,
- ProgramStateRef State, const Stmt *S,
- CheckerContext &C) const {
+void DereferenceChecker::reportDerefBug(const DerefBugType &BT,
+ ProgramStateRef State, const Stmt *S,
+ CheckerContext &C) const {
if (&BT == &FixedAddressBug) {
if (!FixedDerefChecker.isEnabled())
// Deliberately don't add a sink node if check is disabled.
@@ -249,9 +265,8 @@ void DereferenceChecker::reportBug(const DerefBugType &BT,
bugreporter::trackExpressionValue(N, bugreporter::getDerefExpr(S), *BR);
- for (SmallVectorImpl<SourceRange>::iterator
- I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
- BR->addRange(*I);
+ for (const auto &R : Ranges)
+ BR->addRange(R);
C.emitReport(std::move(BR));
}
@@ -262,7 +277,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
if (l.isUndef()) {
const Expr *DerefExpr = getDereferenceExpr(S);
if (!suppressReport(C, DerefExpr))
- reportBug(UndefBug, C.getState(), DerefExpr, C);
+ reportDerefBug(UndefBug, C.getState(), DerefExpr, C);
return;
}
@@ -283,7 +298,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
// we call an "explicit" null dereference.
const Expr *expr = getDereferenceExpr(S);
if (!suppressReport(C, expr)) {
- reportBug(NullBug, nullState, expr, C);
+ reportDerefBug(NullBug, nullState, expr, C);
return;
}
}
@@ -301,7 +316,7 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
if (location.isConstant()) {
const Expr *DerefExpr = getDereferenceExpr(S, isLoad);
if (!suppressReport(C, DerefExpr))
- reportBug(FixedAddressBug, notNullState, DerefExpr, C);
+ reportDerefBug(FixedAddressBug, notNullState, DerefExpr, C);
return;
}
@@ -317,7 +332,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
// One should never write to label addresses.
if (auto Label = L.getAs<loc::GotoLabel>()) {
- reportBug(LabelBug, C.getState(), S, C);
+ reportDerefBug(LabelBug, C.getState(), S, C);
return;
}
@@ -338,7 +353,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
if (!StNonNull) {
const Expr *expr = getDereferenceExpr(S, /*IsBind=*/true);
if (!suppressReport(C, expr)) {
- reportBug(NullBug, StNull, expr, C);
+ reportDerefBug(NullBug, StNull, expr, C);
return;
}
}
@@ -356,7 +371,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
if (V.isConstant()) {
const Expr *DerefExpr = getDereferenceExpr(S, true);
if (!suppressReport(C, DerefExpr))
- reportBug(FixedAddressBug, State, DerefExpr, C);
+ reportDerefBug(FixedAddressBug, State, DerefExpr, C);
return;
}
@@ -379,6 +394,96 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
C.addTransition(State, this);
}
+namespace llvm {
+template <> struct format_provider<ValueDescStr> {
+ static void format(const ValueDescStr &V, raw_ostream &Stream,
+ StringRef Style) {
+ static const char *ValueStr[2][3] = {
+ {"zero", "nonzero integer value", "probably nonzero integer value"},
+ {"null pointer", "non-null pointer", "probably non-null pointer"},
+ };
+ Stream
+ << ValueStr[V.IsPointer][V.IsNull.isConstrainedTrue()
+ ? 0
+ : (V.IsNull.isConstrainedFalse() ? 1 : 2)];
+ DereferenceChecker::AddDerefSource(Stream, V.Ranges, V.Ex, V.State, V.LCtx,
+ false);
+ }
+};
+} // namespace llvm
+
+void DereferenceChecker::checkPreStmt(const BinaryOperator *Op,
+ CheckerContext &C) const {
+ if (!Op->isAdditiveOp() || !NullPointerArithmChecker.isEnabled())
+ return;
+ const Expr *E1 = Op->getLHS();
+ const Expr *E2 = Op->getRHS();
+ QualType T1 = E1->getType().getCanonicalType();
+ QualType T2 = E2->getType().getCanonicalType();
+ bool T1IsPointer = T1->isPointerType();
+ bool T2IsPointer = T2->isPointerType();
+ if (T1->isIntegerType() && T2->isIntegerType())
+ return;
+ if (!T1IsPointer && !T1->isIntegerType() && !T2IsPointer &&
+ !T2->isIntegerType())
+ return;
+
+ ProgramStateRef State = C.getState();
+ ConditionTruthVal V1IsNull = State->isNull(C.getSVal(E1));
+ ConditionTruthVal V2IsNull = State->isNull(C.getSVal(E2));
+ bool IsConstrained = true;
+
+ // Check cases 'NULL + x' and 'NULL - x'
+ if (T1IsPointer && !T2IsPointer) {
+ if (!V1IsNull.isConstrainedTrue() || V2IsNull.isConstrainedTrue())
+ return;
+ IsConstrained = V2IsNull.isConstrainedFalse();
+ }
+
+ // Check case 'x + NULL'
+ if (!T1IsPointer && T2IsPointer) {
+ if (V1IsNull.isConstrainedTrue() || !V2IsNull.isConstrainedTrue())
+ return;
+ IsConstrained = V1IsNull.isConstrainedFalse();
+ }
+
+ // Check case 'NULL - p' or 'p - NULL'
+ if (T1IsPointer && T2IsPointer) {
+ if (!V1IsNull.isConstrainedTrue() && !V2IsNull.isConstrainedTrue())
+ return;
+ if (V1IsNull.isConstrainedTrue() && V2IsNull.isConstrainedTrue())
+ return;
+ IsConstrained =
+ V1IsNull.isConstrainedFalse() || V2IsNull.isConstrainedFalse();
+ }
+
+ SmallVector<SourceRange, 2> Ranges;
+ const char *OpcodeStr =
+ Op->getOpcode() == BO_Add ? "Addition" : "Subtraction";
+ const char *ResultStr = IsConstrained ? "results" : "may result";
+ ValueDescStr DerefArg1{
+ Ranges, E1, State.get(), C.getLocationContext(), T1IsPointer, V1IsNull};
+ ValueDescStr DerefArg2{
+ Ranges, E2, State.get(), C.getLocationContext(), T2IsPointer, V2IsNull};
+ std::string Msg =
+ llvm::formatv("{0} of a {1} and a {2} {3} in undefined behavior",
+ OpcodeStr, DerefArg1, DerefArg2, ResultStr);
+
+ ExplodedNode *N = C.generateErrorNode(State);
+ if (!N)
+ return;
+ auto BR =
+ std::make_unique<PathSensitiveBugReport>(NullPointerArithmBug, Msg, N);
+ if (V1IsNull.isConstrainedTrue())
+ bugreporter::trackExpressionValue(N, E1, *BR);
+ if (V2IsNull.isConstrainedTrue())
+ bugreporter::trackExpressionValue(N, E2, *BR);
+ for (const auto &R : Ranges)
+ BR->addRange(R);
+
+ C.emitReport(std::move(BR));
+}
+
void ento::registerNullDereferenceChecker(CheckerManager &Mgr) {
Mgr.getChecker<DereferenceChecker>()->NullDerefChecker.enable(Mgr);
}
@@ -395,3 +500,11 @@ bool ento::shouldRegisterFixedAddressDereferenceChecker(
const CheckerManager &) {
return true;
}
+
+void ento::registerNullPointerArithmChecker(CheckerManager &Mgr) {
+ Mgr.getChecker<DereferenceChecker>()->NullPointerArithmChecker.enable(Mgr);
+}
+
+bool ento::shouldRegisterNullPointerArithmChecker(const CheckerManager &) {
+ return true;
+}
diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
index b1a7cd7..bc67391 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
@@ -148,9 +148,8 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call,
QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
- if (!UT || !UT->getOriginalDecl()
- ->getMostRecentDecl()
- ->hasAttr<TransparentUnionAttr>())
+ if (!UT ||
+ !UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>())
continue;
auto CSV = DV->getAs<nonloc::CompoundVal>();
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
index c1a5000..419d263 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
@@ -164,7 +164,9 @@ bool tryToFindPtrOrigin(
auto Name = safeGetName(callee);
if (Name == "__builtin___CFStringMakeConstantString" ||
- Name == "NSClassFromString")
+ Name == "NSStringFromSelector" || Name == "NSSelectorFromString" ||
+ Name == "NSStringFromClass" || Name == "NSClassFromString" ||
+ Name == "NSStringFromProtocol" || Name == "NSProtocolFromString")
return callback(E, true);
} else if (auto *CalleeE = call->getCallee()) {
if (auto *E = dyn_cast<DeclRefExpr>(CalleeE->IgnoreParenCasts())) {
@@ -182,7 +184,7 @@ bool tryToFindPtrOrigin(
if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(RetType)) {
if (auto *SubstType = Subst->desugar().getTypePtr()) {
if (auto *RD = dyn_cast<RecordType>(SubstType)) {
- if (auto *CXX = dyn_cast<CXXRecordDecl>(RD->getOriginalDecl()))
+ if (auto *CXX = dyn_cast<CXXRecordDecl>(RD->getDecl()))
if (isSafePtr(CXX))
return callback(E, true);
}
@@ -202,6 +204,8 @@ bool tryToFindPtrOrigin(
!Selector.getNumArgs())
return callback(E, true);
}
+ if (auto *ObjCProtocol = dyn_cast<ObjCProtocolExpr>(E))
+ return callback(ObjCProtocol, true);
if (auto *ObjCDict = dyn_cast<ObjCDictionaryLiteral>(E))
return callback(ObjCDict, true);
if (auto *ObjCArray = dyn_cast<ObjCArrayLiteral>(E))
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp
index d8539ea..1d4e6dd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp
@@ -263,18 +263,43 @@ public:
void visitCallArg(const Expr *Arg, const ParmVarDecl *Param,
const Decl *DeclWithIssue) const {
auto *ArgExpr = Arg->IgnoreParenCasts();
- if (auto *InnerCE = dyn_cast<CallExpr>(Arg)) {
- auto *InnerCallee = InnerCE->getDirectCallee();
- if (InnerCallee && InnerCallee->isInStdNamespace() &&
- safeGetName(InnerCallee) == "move" && InnerCE->getNumArgs() == 1) {
- ArgExpr = InnerCE->getArg(0);
- if (ArgExpr)
- ArgExpr = ArgExpr->IgnoreParenCasts();
+ while (ArgExpr) {
+ ArgExpr = ArgExpr->IgnoreParenCasts();
+ if (auto *InnerCE = dyn_cast<CallExpr>(ArgExpr)) {
+ auto *InnerCallee = InnerCE->getDirectCallee();
+ if (InnerCallee && InnerCallee->isInStdNamespace() &&
+ safeGetName(InnerCallee) == "move" && InnerCE->getNumArgs() == 1) {
+ ArgExpr = InnerCE->getArg(0);
+ continue;
+ }
+ }
+ if (auto *UO = dyn_cast<UnaryOperator>(ArgExpr)) {
+ auto OpCode = UO->getOpcode();
+ if (OpCode == UO_Deref || OpCode == UO_AddrOf) {
+ ArgExpr = UO->getSubExpr();
+ continue;
+ }
}
+ break;
}
+
+ if (auto *MemberCallExpr = dyn_cast<CXXMemberCallExpr>(ArgExpr)) {
+ if (isOwnerPtrType(MemberCallExpr->getObjectType()))
+ return;
+ }
+
+ if (auto *OpCE = dyn_cast<CXXOperatorCallExpr>(ArgExpr)) {
+ auto *Method = dyn_cast_or_null<CXXMethodDecl>(OpCE->getDirectCallee());
+ if (Method && isOwnerPtr(safeGetName(Method->getParent()))) {
+ if (OpCE->getOperator() == OO_Star && OpCE->getNumArgs() == 1)
+ return;
+ }
+ }
+
if (isNullPtr(ArgExpr) || isa<IntegerLiteral>(ArgExpr) ||
isa<CXXDefaultArgExpr>(ArgExpr))
return;
+
if (auto *DRE = dyn_cast<DeclRefExpr>(ArgExpr)) {
if (auto *ValDecl = DRE->getDecl()) {
if (isa<ParmVarDecl>(ValDecl))
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index e5c74bb..d3d1f13 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -138,6 +138,11 @@ bool isCheckedPtr(const std::string &Name) {
return Name == "CheckedPtr" || Name == "CheckedRef";
}
+bool isOwnerPtr(const std::string &Name) {
+ return isRefType(Name) || isCheckedPtr(Name) || Name == "unique_ptr" ||
+ Name == "UniqueRef" || Name == "LazyUniqueRef";
+}
+
bool isSmartPtrClass(const std::string &Name) {
return isRefType(Name) || isCheckedPtr(Name) || isRetainPtrOrOSPtr(Name) ||
Name == "WeakPtr" || Name == "WeakPtrFactory" ||
@@ -206,10 +211,7 @@ bool isRetainPtrOrOSPtrType(const clang::QualType T) {
}
bool isOwnerPtrType(const clang::QualType T) {
- return isPtrOfType(T, [](auto Name) {
- return isRefType(Name) || isCheckedPtr(Name) || Name == "unique_ptr" ||
- Name == "UniqueRef" || Name == "LazyUniqueRef";
- });
+ return isPtrOfType(T, [](auto Name) { return isOwnerPtr(Name); });
}
std::optional<bool> isUncounted(const QualType T) {
@@ -255,7 +257,7 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) {
return;
}
- for (auto *Redecl : RT->getOriginalDecl()->getMostRecentDecl()->redecls()) {
+ for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
if (Redecl->getAttr<ObjCBridgeAttr>() ||
Redecl->getAttr<ObjCBridgeMutableAttr>()) {
CFPointees.insert(RT);
@@ -296,7 +298,7 @@ std::optional<bool> isUnretained(const QualType T, bool IsARCEnabled) {
auto *Record = PointeeType->getAsStructureType();
if (!Record)
return false;
- auto *Decl = Record->getOriginalDecl();
+ auto *Decl = Record->getDecl();
if (!Decl)
return false;
auto TypeName = Decl->getName();
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
index 8300a6c..12e2e2d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
@@ -143,6 +143,10 @@ bool isCheckedPtr(const std::string &Name);
/// \returns true if \p Name is RetainPtr or its variant, false if not.
bool isRetainPtrOrOSPtr(const std::string &Name);
+/// \returns true if \p Name is an owning smar pointer such as Ref, CheckedPtr,
+/// and unique_ptr.
+bool isOwnerPtr(const std::string &Name);
+
/// \returns true if \p Name is a smart pointer type name, false if not.
bool isSmartPtrClass(const std::string &Name);
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
index 6f3a280..c6421f8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
@@ -121,13 +121,13 @@ public:
return true;
}
} else if (auto *RD = dyn_cast<RecordType>(PointeeType)) {
- if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl))
+ if (declaresSameEntity(RD->getDecl(), ClassDecl))
return true;
} else if (auto *ST =
dyn_cast<SubstTemplateTypeParmType>(PointeeType)) {
auto Type = ST->getReplacementType();
if (auto *RD = dyn_cast<RecordType>(Type)) {
- if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl))
+ if (declaresSameEntity(RD->getDecl(), ClassDecl))
return true;
}
}
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 06ba015..62460cc 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -89,7 +89,7 @@ static bool isCallback(QualType T) {
T = T->getPointeeType();
if (const RecordType *RT = T->getAsStructureType()) {
- const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
for (const auto *I : RD->fields()) {
QualType FieldT = I->getType();
if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
@@ -391,9 +391,8 @@ bool CallEvent::isVariadic(const Decl *D) {
static bool isTransparentUnion(QualType T) {
const RecordType *UT = T->getAsUnionType();
- return UT && UT->getOriginalDecl()
- ->getMostRecentDecl()
- ->hasAttr<TransparentUnionAttr>();
+ return UT &&
+ UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>();
}
// In some cases, symbolic cases should be transformed before we associate
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index af0ef52..2838533 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2457,7 +2457,7 @@ NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B,
const TypedValueRegion *R) {
const RecordDecl *RD =
- R->getValueType()->castAsCanonical<RecordType>()->getOriginalDecl();
+ R->getValueType()->castAsCanonical<RecordType>()->getDecl();
if (!RD->getDefinition())
return UnknownVal();
diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp
index 72bc762..8efd320 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -146,6 +146,14 @@ void testValueInRangeOfEnumerationValues() {
const NumberType neg_one = (NumberType) ((NumberType) 0 - (NumberType) 1); // ok, not a constant expression context
}
+struct EnumTest {
+ enum type {
+ Type1,
+ BOUND
+ };
+ static const type binding_completed = type(BOUND + 1); // both-error {{in-class initializer for static data member is not a constant expression}} \
+ // both-note {{integer value 2 is outside the valid range of values}}
+};
template<class T, unsigned size> struct Bitfield {
static constexpr T max = static_cast<T>((1 << size) - 1);
diff --git a/clang/test/AST/ByteCode/typeid.cpp b/clang/test/AST/ByteCode/typeid.cpp
index 00b01c8..090309d1 100644
--- a/clang/test/AST/ByteCode/typeid.cpp
+++ b/clang/test/AST/ByteCode/typeid.cpp
@@ -59,3 +59,13 @@ namespace TypeidPtrInEvaluationResult {
consteval const std::type_info *ftype_info() { return &typeid(c); }
const std::type_info *T1 = ftype_info();
}
+
+// Regression test for crash in ArrayElemPtrPop with typeid pointers. GH-163127
+namespace TypeidPtrRegression {
+ void dontcrash() {
+ // this should just be an error and not an ICE
+ constexpr auto res = ((void**)&typeid(int))[0]; // both-error {{must be initialized by a constant expression}} \
+ // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+ }
+}
+
diff --git a/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm b/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm
index 104b555..8aad838 100644
--- a/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm
+++ b/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm
@@ -11,6 +11,8 @@ class Obj;
Obj* provide_obj_ptr();
void receive_obj_ptr(Obj* p = nullptr);
+void receive_obj_ref(Obj&);
+void receive_obj_rref(Obj&&);
sqlite3* open_db();
void close_db(sqlite3*);
@@ -38,6 +40,16 @@ Obj& ref() {
return obj;
}
+void opaque_call_arg(Obj* obj, Obj&& otherObj, const RefPtr<Obj>& safeObj, WeakPtr<Obj> weakObj, std::unique_ptr<Obj>& uniqObj) {
+ receive_obj_ref(*obj);
+ receive_obj_ptr(&*obj);
+ receive_obj_rref(std::move(otherObj));
+ receive_obj_ref(*safeObj.get());
+ receive_obj_ptr(weakObj.get());
+ // expected-warning@-1{{Call argument for parameter 'p' uses a forward declared type 'Obj *'}}
+ receive_obj_ref(*uniqObj);
+}
+
Obj&& provide_obj_rval();
void receive_obj_rval(Obj&& p);
diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h
index a49faa1..7055a94 100644
--- a/clang/test/Analysis/Checkers/WebKit/mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h
@@ -25,23 +25,23 @@ namespace std {
template <typename T>
class unique_ptr {
private:
- T *t;
+ void *t;
public:
unique_ptr() : t(nullptr) { }
unique_ptr(T *t) : t(t) { }
~unique_ptr() {
if (t)
- delete t;
+ delete static_cast<T*>(t);
}
template <typename U> unique_ptr(unique_ptr<U>&& u)
: t(u.t)
{
u.t = nullptr;
}
- T *get() const { return t; }
- T *operator->() const { return t; }
- T &operator*() const { return *t; }
+ T *get() const { return static_cast<T*>(t); }
+ T *operator->() const { return get(); }
+ T &operator*() const { return *get(); }
unique_ptr &operator=(T *) { return *this; }
explicit operator bool() const { return !!t; }
};
@@ -313,4 +313,90 @@ public:
UniqueRef &operator=(T &) { return *this; }
};
+class WeakPtrImpl {
+private:
+ void* ptr { nullptr };
+ mutable unsigned m_refCount { 0 };
+
+ template <typename U> friend class CanMakeWeakPtr;
+ template <typename U> friend class WeakPtr;
+
+public:
+ template <typename T>
+ static Ref<WeakPtrImpl> create(T& t)
+ {
+ return adoptRef(*new WeakPtrImpl(t));
+ }
+
+ void ref() const { m_refCount++; }
+ void deref() const {
+ m_refCount--;
+ if (!m_refCount)
+ delete const_cast<WeakPtrImpl*>(this);
+ }
+
+ template <typename T>
+ T* get() { return static_cast<T*>(ptr); }
+ operator bool() const { return !!ptr; }
+ void clear() { ptr = nullptr; }
+
+private:
+ template <typename T>
+ WeakPtrImpl(T* t)
+ : ptr(static_cast<void*>(t))
+ { }
+};
+
+template <typename T>
+class CanMakeWeakPtr {
+private:
+ RefPtr<WeakPtrImpl> impl;
+
+ template <typename U> friend class CanMakeWeakPtr;
+ template <typename U> friend class WeakPtr;
+
+ Ref<WeakPtrImpl> createWeakPtrImpl() {
+ if (!impl)
+ impl = WeakPtrImpl::create(static_cast<T>(*this));
+ return *impl;
+ }
+
+public:
+ ~CanMakeWeakPtr() {
+ if (!impl)
+ return;
+ impl->clear();
+ impl = nullptr;
+ }
+};
+
+template <typename T>
+class WeakPtr {
+private:
+ RefPtr<WeakPtrImpl> impl;
+
+public:
+ WeakPtr(T& t) {
+ *this = t;
+ }
+ WeakPtr(T* t) {
+ *this = t;
+ }
+
+ template <typename U>
+ WeakPtr<T> operator=(U& obj) {
+ impl = obj.createWeakPtrImpl();
+ }
+
+ template <typename U>
+ WeakPtr<T> operator=(U* obj) {
+ impl = obj ? obj->createWeakPtrImpl() : nullptr;
+ }
+
+ T* get() {
+ return impl ? impl->get<T>() : nullptr;
+ }
+
+};
+
#endif
diff --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
index a5fc3d7..edf4011 100644
--- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h
@@ -98,12 +98,20 @@ typedef CVImageBufferRef CVPixelBufferRef;
typedef signed int CVReturn;
CVReturn CVPixelBufferCreateWithIOSurface(CFAllocatorRef allocator, IOSurfaceRef surface, CFDictionaryRef pixelBufferAttributes, CF_RETURNS_RETAINED CVPixelBufferRef * pixelBufferOut);
+extern "C" NSString *NSStringFromSelector(SEL aSelector);
+extern "C" SEL NSSelectorFromString(NSString *aSelectorName);
+
+extern "C" NSString *NSStringFromClass(Class aClass);
+extern "C" Class NSClassFromString(NSString *aClassName);
+
+extern "C" NSString *NSStringFromProtocol(Protocol *proto);
+extern "C" Protocol * NSProtocolFromString(NSString *namestr);
+
CFRunLoopRef CFRunLoopGetCurrent(void);
CFRunLoopRef CFRunLoopGetMain(void);
extern CFTypeRef CFRetain(CFTypeRef cf);
extern void CFRelease(CFTypeRef cf);
#define CFSTR(cStr) ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
-extern Class NSClassFromString(NSString *aClassName);
#if __has_feature(objc_arc)
id CFBridgingRelease(CFTypeRef X) {
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
index 5dc3b38..4f231ee 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
@@ -578,6 +578,24 @@ void foo() {
} // autoreleased
+namespace sel_string {
+
+void consumeStr(NSString *);
+void consumeSel(SEL);
+void consumeClass(Class);
+void consumeProtocol(Protocol *);
+
+void foo() {
+ consumeStr(NSStringFromSelector(@selector(mutableCopy)));
+ consumeSel(NSSelectorFromString(@"mutableCopy"));
+ consumeStr(NSStringFromClass(NSNumber.class));
+ consumeClass(NSClassFromString(@"NSNumber"));
+ consumeStr(NSStringFromProtocol(@protocol(NSCopying)));
+ consumeProtocol(NSProtocolFromString(@"NSCopying"));
+}
+
+} // namespace sel_string
+
@interface TestObject : NSObject
- (void)doWork:(NSString *)msg, ...;
- (void)doWorkOnSelf;
diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c
index 0092331..bfe418b 100644
--- a/clang/test/Analysis/analyzer-enabled-checkers.c
+++ b/clang/test/Analysis/analyzer-enabled-checkers.c
@@ -19,6 +19,7 @@
// CHECK-NEXT: core.NonNullParamChecker
// CHECK-NEXT: core.NonnilStringConstants
// CHECK-NEXT: core.NullDereference
+// CHECK-NEXT: core.NullPointerArithm
// CHECK-NEXT: core.StackAddressEscape
// CHECK-NEXT: core.UndefinedBinaryOperatorResult
// CHECK-NEXT: core.VLASize
diff --git a/clang/test/Analysis/null-pointer-arithm.c b/clang/test/Analysis/null-pointer-arithm.c
new file mode 100644
index 0000000..2288247
--- /dev/null
+++ b/clang/test/Analysis/null-pointer-arithm.c
@@ -0,0 +1,76 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=core
+
+extern int *get_pointer();
+
+int *test_add1(int offset) {
+ int *p = get_pointer();
+ if (p) {}
+ return p + offset; // expected-warning{{Addition of a null pointer (from variable 'p') and a probably nonzero integer value (from variable 'offset') may result in undefined behavior}}
+}
+
+int *test_add2(int offset) {
+ int *p = get_pointer();
+ if (p) {}
+ if (offset) {}
+ return p + offset; // expected-warning{{Addition of a null pointer (from variable 'p') and a nonzero integer value (from variable 'offset') results in undefined behavior}}
+}
+
+int *test_add3(int offset) {
+ int *p = get_pointer();
+ if (p) {}
+ if (offset != 0) return 0;
+ return p + offset;
+}
+
+int *test_add4(int offset) {
+ int *p = get_pointer();
+ if (p) {}
+ if (offset == 0) return 0;
+ return p + offset; // expected-warning{{Addition of a null pointer (from variable 'p') and a nonzero integer value (from variable 'offset') results in undefined behavior}}
+}
+
+int *test_add5(int offset) {
+ int *p = get_pointer();
+ if (p) {}
+ return offset + p; // expected-warning{{Addition of a probably nonzero integer value (from variable 'offset') and a null pointer (from variable 'p') may result in undefined behavior}}
+}
+
+int *test_sub1(int offset) {
+ int *p = get_pointer();
+ if (p) {}
+ return p - offset; // expected-warning{{Subtraction of a null pointer (from variable 'p') and a probably nonzero integer value (from variable 'offset') may result in undefined behavior}}
+}
+
+int test_sub_p1() {
+ int *p = get_pointer();
+ if (p) {}
+ return p - p;
+}
+
+int test_sub_p2() {
+ int *p1 = get_pointer();
+ int *p2 = get_pointer();
+ if (p1) {}
+ if (p2) {}
+ return p1 - p2;
+ // expected-warning@-1{{Subtraction of a non-null pointer (from variable 'p1') and a null pointer (from variable 'p2') results in undefined behavior}}
+ // expected-warning@-2{{Subtraction of a null pointer (from variable 'p1') and a non-null pointer (from variable 'p2') results in undefined behavior}}
+}
+
+int test_sub_p3() {
+ int *p1 = get_pointer();
+ int *p2 = get_pointer();
+ if (p1) {}
+ return p1 - p2; // expected-warning{{Subtraction of a null pointer (from variable 'p1') and a probably non-null pointer (from variable 'p2') may result in undefined behavior}}
+}
+
+struct S {
+ char *p;
+ int offset;
+};
+
+char *test_struct(struct S s) {
+ if (s.p) {}
+ return s.p + s.offset; // expected-warning{{Addition of a null pointer (via field 'p') and a probably nonzero integer value (via field 'offset') may result in undefined behavior}}
+}
diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
index 7fae958..9b32960 100644
--- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
+++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
@@ -27,6 +27,7 @@
// CHECK-NEXT: core.NonNullParamChecker
// CHECK-NEXT: core.NonnilStringConstants
// CHECK-NEXT: core.NullDereference
+// CHECK-NEXT: core.NullPointerArithm
// CHECK-NEXT: core.StackAddressEscape
// CHECK-NEXT: core.UndefinedBinaryOperatorResult
// CHECK-NEXT: core.VLASize
diff --git a/clang/test/C/C2y/n3364.c b/clang/test/C/C2y/n3364.c
index d75f17d..ccf7e8d 100644
--- a/clang/test/C/C2y/n3364.c
+++ b/clang/test/C/C2y/n3364.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -verify -std=c2y -ffreestanding -Wall -pedantic -emit-llvm -o - %s
-// RUN: %clang_cc1 -verify -ffreestanding -Wall -pedantic -emit-llvm -o - %s
+// RUN: %clang_cc1 -verify -std=c2y -ffreestanding -Wall -pedantic -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -verify -ffreestanding -Wall -pedantic -emit-llvm -o - %s | FileCheck %s
// expected-no-diagnostics
/* WG14 N3364: Yes
@@ -23,20 +23,20 @@
float f1 = FLT_SNAN;
float f2 = +FLT_SNAN;
float f3 = -FLT_SNAN;
-// CHECK: @f1 = {{.*}}global float 0x7FF0000020000000
-// CHECK: @f2 = {{.*}}global float 0x7FF0000020000000
-// CHECK: @f3 = {{.*}}global float 0xFFF0000020000000
+// CHECK: @f1 = {{.*}}global float 0x7FF4000000000000
+// CHECK: @f2 = {{.*}}global float 0x7FF4000000000000
+// CHECK: @f3 = {{.*}}global float 0xFFF4000000000000
double d1 = DBL_SNAN;
double d2 = +DBL_SNAN;
double d3 = -DBL_SNAN;
-// CHECK: @d1 = {{.*}}global double 0x7FF0000000000001
-// CHECK: @d2 = {{.*}}global double 0x7FF0000000000001
-// CHECK: @d3 = {{.*}}global double 0xFFF0000000000001
+// CHECK: @d1 = {{.*}}global double 0x7FF4000000000000
+// CHECK: @d2 = {{.*}}global double 0x7FF4000000000000
+// CHECK: @d3 = {{.*}}global double 0xFFF4000000000000
long double ld1 = LDBL_SNAN;
long double ld2 = +LDBL_SNAN;
long double ld3 = -LDBL_SNAN;
-// CHECK: @ld1 = {{.*}}global {{double 0x7FF0000000000001|x86_fp80 0xK7FFF8000000000000001|fp128 0xL00000000000000017FFF000000000000}}
-// CHECK: @ld2 = {{.*}}global {{double 0x7FF0000000000001|x86_fp80 0xK7FFF8000000000000001|fp128 0xL00000000000000017FFF000000000000}}
-// CHECK: @ld3 = {{.*}}global {{double 0xFFF0000000000001|x86_fp80 0xKFFFF8000000000000001|fp128 0xL0000000000000001FFFF000000000000}}
+// CHECK: @ld1 = {{.*}}global {{double 0x7FF4000000000000|x86_fp80 0xK7FFFA000000000000000|fp128 0xL00000000000000007FFF400000000000|ppc_fp128 0xM7FF40000000000000000000000000000}}
+// CHECK: @ld2 = {{.*}}global {{double 0x7FF4000000000000|x86_fp80 0xK7FFFA000000000000000|fp128 0xL00000000000000007FFF400000000000|ppc_fp128 0xM7FF40000000000000000000000000000}}
+// CHECK: @ld3 = {{.*}}global {{double 0xFFF4000000000000|x86_fp80 0xKFFFFA000000000000000|fp128 0xL0000000000000000FFFF400000000000|ppc_fp128 0xMFFF40000000000008000000000000000}}
diff --git a/clang/test/CIR/CodeGen/throws.cpp b/clang/test/CIR/CodeGen/throws.cpp
index ff6aa62..4255d43 100644
--- a/clang/test/CIR/CodeGen/throws.cpp
+++ b/clang/test/CIR/CodeGen/throws.cpp
@@ -123,3 +123,24 @@ void paren_expr() { (throw 0, 1 + 2); }
// OGCG: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 4)
// OGCG: store i32 0, ptr %[[EXCEPTION_ADDR]], align 16
// OGCG: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTIi, ptr null)
+
+void throw_complex_expr() {
+ throw __builtin_complex(1.1f, 2.2f);
+}
+
+// CIR: %[[EXCEPTION_ADDR:.*]] = cir.alloc.exception 8 -> !cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[EXCEPTION_VALUE:.*]] = cir.const #cir.const_complex<#cir.fp<1.100000e+00> : !cir.float, #cir.fp<2.200000e+00> : !cir.float> : !cir.complex<!cir.float>
+// CIR: cir.store{{.*}} %[[EXCEPTION_VALUE]], %[[EXCEPTION_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
+// CIR: cir.throw %[[EXCEPTION_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>, @_ZTICf
+// CIR: cir.unreachable
+
+// LLVM: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 8)
+// LLVM: store { float, float } { float 0x3FF19999A0000000, float 0x40019999A0000000 }, ptr %[[EXCEPTION_ADDR]], align 16
+// LLVM: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTICf, ptr null)
+
+// OGCG: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 8)
+// OGCG: %[[EXCEPTION_REAL:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[EXCEPTION_ADDR]], i32 0, i32 0
+// OGCG: %[[EXCEPTION_IMAG:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[EXCEPTION_ADDR]], i32 0, i32 1
+// OGCG: store float 0x3FF19999A0000000, ptr %[[EXCEPTION_REAL]], align 16
+// OGCG: store float 0x40019999A0000000, ptr %[[EXCEPTION_IMAG]], align 4
+// OGCG: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTICf, ptr null)
diff --git a/clang/test/CIR/CodeGen/vla.c b/clang/test/CIR/CodeGen/vla.c
new file mode 100644
index 0000000..e2adf45
--- /dev/null
+++ b/clang/test/CIR/CodeGen/vla.c
@@ -0,0 +1,285 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+void f0(int len) {
+ int arr[len];
+}
+
+// CIR: cir.func{{.*}} @f0(%[[LEN_ARG:.*]]: !s32i {{.*}})
+// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init]
+// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]
+// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]
+// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]
+// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !s32i -> !u64i
+// CIR: %[[STACK_PTR:.*]] = cir.stacksave
+// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]
+// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[LEN_SIZE_T]] : !u64i, ["arr"]
+// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]
+// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]
+
+// LLVM: define{{.*}} void @f0(i32 %[[LEN_ARG:.*]]) {
+// LLVM: %[[LEN_ADDR:.*]] = alloca i32
+// LLVM: %[[SAVED_STACK:.*]] = alloca ptr
+// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// LLVM: %[[LEN_SIZE_T:.*]] = sext i32 %[[LEN]] to i64
+// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[LEN_SIZE_T]]
+// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+// Note: VLA_EXPR0 below is emitted to capture debug info.
+
+// OGCG: define{{.*}} void @f0(i32 {{.*}} %[[LEN_ARG:.*]])
+// OGCG: %[[LEN_ADDR:.*]] = alloca i32
+// OGCG: %[[SAVED_STACK:.*]] = alloca ptr
+// OGCG: %[[VLA_EXPR0:.*]] = alloca i64
+// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64
+// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[LEN_SIZE_T]]
+// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]]
+// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+void f1(int len) {
+ int arr[16][len];
+}
+
+// CIR: cir.func{{.*}} @f1(%[[LEN_ARG:.*]]: !s32i {{.*}})
+// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init]
+// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]
+// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]
+// CIR: %[[SIXTEEN:.*]] = cir.const #cir.int<16> : !s32i
+// CIR: %[[SIXTEEN_SIZE_T:.*]] = cir.cast integral %[[SIXTEEN]] : !s32i -> !u64i
+// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]
+// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !s32i -> !u64i
+// CIR: %[[STACK_PTR:.*]] = cir.stacksave
+// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]
+// CIR: %[[TOTAL_LEN:.*]] = cir.binop(mul, %[[SIXTEEN_SIZE_T]], %[[LEN_SIZE_T]]) nuw
+// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[TOTAL_LEN]] : !u64i, ["arr"]
+// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]
+// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]
+
+// LLVM: define{{.*}} void @f1(i32 %[[LEN_ARG:.*]]) {
+// LLVM: %[[LEN_ADDR:.*]] = alloca i32
+// LLVM: %[[SAVED_STACK:.*]] = alloca ptr
+// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// LLVM: %[[LEN_SIZE_T:.*]] = sext i32 %[[LEN]] to i64
+// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// LLVM: %[[TOTAL_LEN:.*]] = mul nuw i64 16, %[[LEN_SIZE_T]]
+// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN]]
+// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+// Note: VLA_EXPR0 below is emitted to capture debug info.
+
+// OGCG: define{{.*}} void @f1(i32 {{.*}} %[[LEN_ARG:.*]])
+// OGCG: %[[LEN_ADDR:.*]] = alloca i32
+// OGCG: %[[SAVED_STACK:.*]] = alloca ptr
+// OGCG: %[[VLA_EXPR0:.*]] = alloca i64
+// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64
+// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// OGCG: %[[TOTAL_LEN:.*]] = mul nuw i64 16, %[[LEN_SIZE_T]]
+// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN]]
+// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]]
+// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+void f2(int len) {
+ int arr[len + 4];
+}
+
+// CIR: cir.func{{.*}} @f2(%[[LEN_ARG:.*]]: !s32i {{.*}})
+// CIR: %[[LEN_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["len", init]
+// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]
+// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]
+// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]
+// CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s32i
+// CIR: %[[TOTAL_LEN:.*]] = cir.binop(add, %[[LEN]], %[[FOUR]]) nsw : !s32i
+// CIR: %[[TOTAL_LEN_SIZE_T:.*]] = cir.cast integral %[[TOTAL_LEN]] : !s32i -> !u64i
+// CIR: %[[STACK_PTR:.*]] = cir.stacksave
+// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]
+// CIR: %[[ARR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, %[[TOTAL_LEN_SIZE_T]] : !u64i, ["arr"]
+// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]
+// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]
+
+// LLVM: define{{.*}} void @f2(i32 %[[LEN_ARG:.*]]) {
+// LLVM: %[[LEN_ADDR:.*]] = alloca i32
+// LLVM: %[[SAVED_STACK:.*]] = alloca ptr
+// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// LLVM: %[[TOTAL_LEN:.*]] = add nsw i32 %[[LEN]], 4
+// LLVM: %[[TOTAL_LEN_SIZE_T:.*]] = sext i32 %[[TOTAL_LEN]] to i64
+// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// LLVM: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN_SIZE_T]]
+// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+// Note: VLA_EXPR0 below is emitted to capture debug info.
+
+// OGCG: define{{.*}} void @f2(i32 {{.*}} %[[LEN_ARG:.*]])
+// OGCG: %[[LEN_ADDR:.*]] = alloca i32
+// OGCG: %[[SAVED_STACK:.*]] = alloca ptr
+// OGCG: %[[VLA_EXPR0:.*]] = alloca i64
+// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// OGCG: %[[TOTAL_LEN:.*]] = add nsw i32 %[[LEN]], 4
+// OGCG: %[[TOTAL_LEN_SIZE_T:.*]] = zext i32 %[[TOTAL_LEN]] to i64
+// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// OGCG: %[[ARR:.*]] = alloca i32, i64 %[[TOTAL_LEN_SIZE_T]]
+// OGCG: store i64 %[[TOTAL_LEN_SIZE_T]], ptr %[[VLA_EXPR0]]
+// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+void f3(unsigned len) {
+ char s1[len];
+ unsigned i = 0u;
+ while (++i < len) {
+ char s2[i];
+ }
+}
+
+// CIR: cir.func{{.*}} @f3(%[[LEN_ARG:.*]]: !u32i {{.*}})
+// CIR: %[[LEN_ADDR:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["len", init]
+// CIR: %[[SAVED_STACK:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]
+// CIR: cir.store{{.*}} %[[LEN_ARG]], %[[LEN_ADDR]]
+// CIR: %[[LEN:.*]] = cir.load{{.*}} %[[LEN_ADDR]]
+// CIR: %[[LEN_SIZE_T:.*]] = cir.cast integral %[[LEN]] : !u32i -> !u64i
+// CIR: %[[STACK_PTR:.*]] = cir.stacksave
+// CIR: cir.store{{.*}} %[[STACK_PTR]], %[[SAVED_STACK]]
+// CIR: %[[S1:.*]] = cir.alloca !s8i, !cir.ptr<!s8i>, %[[LEN_SIZE_T]] : !u64i, ["s1"]
+// CIR: %[[I:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["i", init]
+// CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !u32i
+// CIR: cir.store{{.*}} %[[ZERO]], %[[I]]
+// CIR: cir.scope {
+// CIR: cir.while {
+// CIR: %[[CUR_I:.*]] = cir.load{{.*}} %[[I]]
+// CIR: %[[NEXT:.*]] = cir.unary(inc, %[[CUR_I]])
+// CIR: cir.store{{.*}} %[[NEXT]], %[[I]]
+// CIR: %[[LEN2:.*]] = cir.load{{.*}} %[[LEN_ADDR]]
+// CIR: %[[CMP:.*]] = cir.cmp(lt, %[[NEXT]], %[[LEN2]])
+// CIR: cir.condition(%[[CMP]])
+// CIR: } do {
+// CIR: cir.scope {
+// CIR: %[[SAVED_STACK2:.*]] = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"]
+// CIR: %[[I_LEN:.*]] = cir.load{{.*}} %[[I]]
+// CIR: %[[I_LEN_SIZE_T2:.*]] = cir.cast integral %[[I_LEN]] : !u32i -> !u64i
+// CIR: %[[STACK_PTR2:.*]] = cir.stacksave
+// CIR: cir.store{{.*}} %[[STACK_PTR2]], %[[SAVED_STACK2]]
+// CIR: %[[S2:.*]] = cir.alloca !s8i, !cir.ptr<!s8i>, %[[I_LEN_SIZE_T2]] : !u64i, ["s2"]
+// CIR: %[[SAVED_RESTORE_PTR2:.*]] = cir.load{{.*}} %[[SAVED_STACK2]]
+// CIR: cir.stackrestore %[[SAVED_RESTORE_PTR2]]
+// CIR: }
+// CIR: cir.yield
+// CIR: }
+// CIR: }
+// CIR: %[[STACK_RESTORE_PTR:.*]] = cir.load{{.*}} %[[SAVED_STACK]]
+// CIR: cir.stackrestore %[[STACK_RESTORE_PTR]]
+
+// LLVM: define{{.*}} void @f3(i32 %[[LEN_ARG:.*]]) {
+// LLVM: %[[SAVED_STACK2:.*]] = alloca ptr
+// LLVM: %[[LEN_ADDR:.*]] = alloca i32
+// LLVM: %[[SAVED_STACK:.*]] = alloca ptr
+// LLVM: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// LLVM: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// LLVM: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64
+// LLVM: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// LLVM: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// LLVM: %[[S1:.*]] = alloca i8, i64 %[[LEN_SIZE_T]]
+// LLVM: %[[I:.*]] = alloca i32
+// LLVM: store i32 0, ptr %[[I]]
+// LLVM: br label %[[WHILE_START:.*]]
+// LLVM: [[WHILE_START]]:
+// LLVM: br label %[[WHILE_COND:.*]]
+// LLVM: [[WHILE_COND]]:
+// LLVM: %[[CUR_I:.*]] = load i32, ptr %[[I]]
+// LLVM: %[[NEXT:.*]] = add i32 %[[CUR_I]], 1
+// LLVM: store i32 %[[NEXT]], ptr %[[I]]
+// LLVM: %[[LEN2:.*]] = load i32, ptr %[[LEN_ADDR]]
+// LLVM: %[[CMP:.*]] = icmp ult i32 %[[NEXT]], %[[LEN2]]
+// LLVM: br i1 %[[CMP]], label %[[WHILE_BODY:.*]], label %[[WHILE_END:.*]]
+// LLVM: [[WHILE_BODY]]:
+// LLVM: br label %[[WHILE_BODY2:.*]]
+// LLVM: [[WHILE_BODY2]]:
+// LLVM: %[[I_LEN:.*]] = load i32, ptr %[[I]]
+// LLVM: %[[I_LEN_SIZE_T2:.*]] = zext i32 %[[I_LEN]] to i64
+// LLVM: %[[STACK_PTR2:.*]] = call ptr @llvm.stacksave.p0()
+// LLVM: store ptr %[[STACK_PTR2]], ptr %[[SAVED_STACK2]]
+// LLVM: %[[S2:.*]] = alloca i8, i64 %[[I_LEN_SIZE_T2]]
+// LLVM: %[[STACK_RESTORE_PTR2:.*]] = load ptr, ptr %[[SAVED_STACK2]]
+// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR2]])
+// LLVM: br label %[[WHILE_BODY_END:.*]]
+// LLVM: [[WHILE_BODY_END]]:
+// LLVM: br label %[[WHILE_COND]]
+// LLVM: [[WHILE_END]]:
+// LLVM: br label %[[F3_END:.*]]
+// LLVM: [[F3_END]]:
+// LLVM: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// LLVM: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+// Note: VLA_EXPR0 and VLA_EXPR1 below are emitted to capture debug info.
+
+// OGCG: define{{.*}} void @f3(i32 {{.*}} %[[LEN_ARG:.*]])
+// OGCG: %[[LEN_ADDR:.*]] = alloca i32
+// OGCG: %[[SAVED_STACK:.*]] = alloca ptr
+// OGCG: %[[VLA_EXPR0:.*]] = alloca i64
+// OGCG: %[[I:.*]] = alloca i32
+// OGCG: %[[SAVED_STACK1:.*]] = alloca ptr
+// OGCG: %[[VLA_EXPR1:.*]] = alloca i64
+// OGCG: store i32 %[[LEN_ARG]], ptr %[[LEN_ADDR]]
+// OGCG: %[[LEN:.*]] = load i32, ptr %[[LEN_ADDR]]
+// OGCG: %[[LEN_SIZE_T:.*]] = zext i32 %[[LEN]] to i64
+// OGCG: %[[STACK_PTR:.*]] = call ptr @llvm.stacksave.p0()
+// OGCG: store ptr %[[STACK_PTR]], ptr %[[SAVED_STACK]]
+// OGCG: %[[S1:.*]] = alloca i8, i64 %[[LEN_SIZE_T]]
+// OGCG: store i64 %[[LEN_SIZE_T]], ptr %[[VLA_EXPR0]]
+// OGCG: br label %[[WHILE_COND:.*]]
+// OGCG: [[WHILE_COND]]:
+// OGCG: %[[CUR_I:.*]] = load i32, ptr %[[I]]
+// OGCG: %[[NEXT:.*]] = add i32 %[[CUR_I]], 1
+// OGCG: store i32 %[[NEXT]], ptr %[[I]]
+// OGCG: %[[LEN2:.*]] = load i32, ptr %[[LEN_ADDR]]
+// OGCG: %[[CMP:.*]] = icmp ult i32 %[[NEXT]], %[[LEN2]]
+// OGCG: br i1 %[[CMP]], label %[[WHILE_BODY:.*]], label %[[WHILE_END:.*]]
+// OGCG: [[WHILE_BODY]]:
+// OGCG: %[[I_LEN:.*]] = load i32, ptr %[[I]]
+// OGCG: %[[I_LEN_SIZE_T:.*]] = zext i32 %[[I_LEN]] to i64
+// OGCG: %[[STACK_PTR1:.*]] = call ptr @llvm.stacksave.p0()
+// OGCG: store ptr %[[STACK_PTR1]], ptr %[[SAVED_STACK1]]
+// OGCG: %[[S2:.*]] = alloca i8, i64 %[[I_LEN_SIZE_T]]
+// OGCG: store i64 %[[I_LEN_SIZE_T]], ptr %[[VLA_EXPR1]]
+// OGCG: %[[STACK_RESTORE_PTR1:.*]] = load ptr, ptr %[[SAVED_STACK1]]
+// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR1]])
+// OGCG: br label %[[WHILE_COND]]
+// OGCG: [[WHILE_END]]:
+// OGCG: %[[STACK_RESTORE_PTR:.*]] = load ptr, ptr %[[SAVED_STACK]]
+// OGCG: call void @llvm.stackrestore.p0(ptr %[[STACK_RESTORE_PTR]])
+
+
+// The following test case is disabled because it runs into a bug (unrelated
+// to VLA) in the handling of cleanups in loops with break statements.
+//
+// void f4(unsigned len) {
+// char s1[len];
+// while (1) {
+// char s2[len];
+// if (1)
+// break;
+// }
+// }
+ \ No newline at end of file
diff --git a/clang/test/CXX/module/module.import/p6.cpp b/clang/test/CXX/module/module.import/p6.cpp
index cb2d799..9e378a5 100644
--- a/clang/test/CXX/module/module.import/p6.cpp
+++ b/clang/test/CXX/module/module.import/p6.cpp
@@ -3,6 +3,9 @@
// RUN: %clang_cc1 -std=c++20 -x c++-header %t/bad-header-unit.h \
// RUN: -emit-header-unit -o %t/bad-header-unit.pcm -verify
+// RUN: %clang_cc1 -std=c++20 -x c++-header %t/bad-header-unit-declspec.h \
+// RUN: -emit-header-unit -o %t/bad-header-unit.pcm -verify \
+// RUN: -fdeclspec
//--- bad-header-unit.h
@@ -77,3 +80,13 @@ template <typename T> bool b() {
}
inline bool B = b<int>();
+
+__attribute__((weak)) int weak_fun_definition() { return 42; }
+
+__attribute__((weak)) int weak_var_definition = 42;
+
+//--- bad-header-unit-declspec.h
+
+/* The cases below should compile without diagnostics. */
+
+__declspec(selectany) int selectany_var_definition = 42; // expected-no-diagnostics
diff --git a/clang/test/CodeGen/X86/avx512cd-builtins.c b/clang/test/CodeGen/X86/avx512cd-builtins.c
index 2890889..80a20b1 100644
--- a/clang/test/CodeGen/X86/avx512cd-builtins.c
+++ b/clang/test/CodeGen/X86/avx512cd-builtins.c
@@ -14,37 +14,53 @@
__m512i test_mm512_conflict_epi64(__m512i __A) {
// CHECK-LABEL: test_mm512_conflict_epi64
// CHECK: call {{.*}}<8 x i64> @llvm.x86.avx512.conflict.q.512(<8 x i64> %{{.*}})
- return _mm512_conflict_epi64(__A);
+ return _mm512_conflict_epi64(__A);
}
+
+TEST_CONSTEXPR(match_v8di(_mm512_conflict_epi64((__m512i)(__v8di){1, 2, 1, 3, 2, 4, 1, 5}), 0, 0, 1, 0, 2, 0, 5, 0));
+TEST_CONSTEXPR(match_v8di(_mm512_conflict_epi64((__m512i)(__v8di){5, 5, 5, 5, 5, 5, 5, 5}), 0, 1, 3, 7, 15, 31, 63, 127));
+TEST_CONSTEXPR(match_v8di(_mm512_conflict_epi64((__m512i)(__v8di){1, 2, 3, 4, 5, 6, 7, 8}), 0, 0, 0, 0, 0, 0, 0, 0));
__m512i test_mm512_mask_conflict_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_conflict_epi64
// CHECK: call {{.*}}<8 x i64> @llvm.x86.avx512.conflict.q.512(<8 x i64> %{{.*}})
// CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
- return _mm512_mask_conflict_epi64(__W,__U,__A);
+ return _mm512_mask_conflict_epi64(__W,__U,__A);
}
+
+TEST_CONSTEXPR(match_v8di(_mm512_mask_conflict_epi64((__m512i)(__v8di){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 0x55, (__m512i)(__v8di){1, 2, 1, 3, 2, 4, 1, 5}), 0, 0xFF, 1, 0xFF, 2, 0xFF, 5, 0xFF));
__m512i test_mm512_maskz_conflict_epi64(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_maskz_conflict_epi64
// CHECK: call {{.*}}<8 x i64> @llvm.x86.avx512.conflict.q.512(<8 x i64> %{{.*}})
// CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
- return _mm512_maskz_conflict_epi64(__U,__A);
+ return _mm512_maskz_conflict_epi64(__U,__A);
}
+
+TEST_CONSTEXPR(match_v8di(_mm512_maskz_conflict_epi64(0x55, (__m512i)(__v8di){1, 2, 1, 3, 2, 4, 1, 5}), 0, 0, 1, 0, 2, 0, 5, 0));
__m512i test_mm512_conflict_epi32(__m512i __A) {
// CHECK-LABEL: test_mm512_conflict_epi32
// CHECK: call <16 x i32> @llvm.x86.avx512.conflict.d.512(<16 x i32> %{{.*}})
- return _mm512_conflict_epi32(__A);
+ return _mm512_conflict_epi32(__A);
}
+
+TEST_CONSTEXPR(match_v16si(_mm512_conflict_epi32((__m512i)(__v16si){1, 2, 1, 3, 2, 4, 1, 5, 6, 7, 6, 8, 7, 9, 6, 10}), 0, 0, 1, 0, 2, 0, 5, 0, 0, 0, 256, 0, 512, 0, 1280, 0));
+TEST_CONSTEXPR(match_v16si(_mm512_conflict_epi32((__m512i)(__v16si){9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}), 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767));
+TEST_CONSTEXPR(match_v16si(_mm512_conflict_epi32((__m512i)(__v16si){1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
__m512i test_mm512_mask_conflict_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_conflict_epi32
// CHECK: call <16 x i32> @llvm.x86.avx512.conflict.d.512(<16 x i32> %{{.*}})
// CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
- return _mm512_mask_conflict_epi32(__W,__U,__A);
+ return _mm512_mask_conflict_epi32(__W,__U,__A);
}
+
+TEST_CONSTEXPR(match_v16si(_mm512_mask_conflict_epi32((__m512i)(__v16si){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 0x5555, (__m512i)(__v16si){1, 2, 1, 3, 2, 4, 1, 5, 6, 7, 6, 8, 7, 9, 6, 10}), 0, 0xFF, 1, 0xFF, 2, 0xFF, 5, 0xFF, 0, 0xFF, 256, 0xFF, 512, 0xFF, 1280, 0xFF));
__m512i test_mm512_maskz_conflict_epi32(__mmask16 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_maskz_conflict_epi32
// CHECK: call <16 x i32> @llvm.x86.avx512.conflict.d.512(<16 x i32> %{{.*}})
// CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
- return _mm512_maskz_conflict_epi32(__U,__A);
+ return _mm512_maskz_conflict_epi32(__U,__A);
}
+
+TEST_CONSTEXPR(match_v16si(_mm512_maskz_conflict_epi32(0x5555, (__m512i)(__v16si){1, 2, 1, 3, 2, 4, 1, 5, 6, 7, 6, 8, 7, 9, 6, 10}), 0, 0, 1, 0, 2, 0, 5, 0, 0, 0, 256, 0, 512, 0, 1280, 0));
__m512i test_mm512_lzcnt_epi32(__m512i __A) {
// CHECK-LABEL: test_mm512_lzcnt_epi32
// CHECK: call <16 x i32> @llvm.ctlz.v16i32(<16 x i32> %{{.*}}, i1 true)
diff --git a/clang/test/CodeGen/X86/avx512vlcd-builtins.c b/clang/test/CodeGen/X86/avx512vlcd-builtins.c
index 56c04a0..29fc6fd 100644
--- a/clang/test/CodeGen/X86/avx512vlcd-builtins.c
+++ b/clang/test/CodeGen/X86/avx512vlcd-builtins.c
@@ -66,83 +66,114 @@ TEST_CONSTEXPR(match_v8si(_mm256_broadcastmw_epi32((__mmask16)(0xcafe)), 0xcafe,
__m128i test_mm_conflict_epi64(__m128i __A) {
// CHECK-LABEL: test_mm_conflict_epi64
// CHECK: call {{.*}}<2 x i64> @llvm.x86.avx512.conflict.q.128(<2 x i64> %{{.*}})
- return _mm_conflict_epi64(__A);
+ return _mm_conflict_epi64(__A);
}
+TEST_CONSTEXPR(match_v2di(_mm_conflict_epi64((__m128i)(__v2di){1, 2}), 0, 0));
+TEST_CONSTEXPR(match_v2di(_mm_conflict_epi64((__m128i)(__v2di){5, 5}), 0, 1));
+
__m128i test_mm_mask_conflict_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: test_mm_mask_conflict_epi64
// CHECK: call {{.*}}<2 x i64> @llvm.x86.avx512.conflict.q.128(<2 x i64> %{{.*}})
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
- return _mm_mask_conflict_epi64(__W, __U, __A);
+ return _mm_mask_conflict_epi64(__W, __U, __A);
}
+TEST_CONSTEXPR(match_v2di(_mm_mask_conflict_epi64((__m128i)(__v2di){0xFF, 0xFF}, 0x2, (__m128i)(__v2di){5, 5}), 0xFF, 1));
+
__m128i test_mm_maskz_conflict_epi64(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: test_mm_maskz_conflict_epi64
// CHECK: call {{.*}}<2 x i64> @llvm.x86.avx512.conflict.q.128(<2 x i64> %{{.*}})
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
- return _mm_maskz_conflict_epi64(__U, __A);
+ return _mm_maskz_conflict_epi64(__U, __A);
}
+TEST_CONSTEXPR(match_v2di(_mm_maskz_conflict_epi64(0x2, (__m128i)(__v2di){5, 5}), 0, 1));
+
__m256i test_mm256_conflict_epi64(__m256i __A) {
// CHECK-LABEL: test_mm256_conflict_epi64
// CHECK: call {{.*}}<4 x i64> @llvm.x86.avx512.conflict.q.256(<4 x i64> %{{.*}})
- return _mm256_conflict_epi64(__A);
+ return _mm256_conflict_epi64(__A);
}
+TEST_CONSTEXPR(match_v4di(_mm256_conflict_epi64((__m256i)(__v4di){1, 2, 1, 3}), 0, 0, 1, 0));
+TEST_CONSTEXPR(match_v4di(_mm256_conflict_epi64((__m256i)(__v4di){7, 7, 7, 7}), 0, 1, 3, 7));
+TEST_CONSTEXPR(match_v4di(_mm256_conflict_epi64((__m256i)(__v4di){1, 2, 3, 4}), 0, 0, 0, 0));
+
__m256i test_mm256_mask_conflict_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_mask_conflict_epi64
// CHECK: call {{.*}}<4 x i64> @llvm.x86.avx512.conflict.q.256(<4 x i64> %{{.*}})
// CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
- return _mm256_mask_conflict_epi64(__W, __U, __A);
+ return _mm256_mask_conflict_epi64(__W, __U, __A);
}
+TEST_CONSTEXPR(match_v4di(_mm256_mask_conflict_epi64((__m256i)(__v4di){0xFF, 0xFF, 0xFF, 0xFF}, 0x5, (__m256i)(__v4di){1, 2, 1, 3}), 0, 0xFF, 1, 0xFF));
+
__m256i test_mm256_maskz_conflict_epi64(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_maskz_conflict_epi64
// CHECK: call {{.*}}<4 x i64> @llvm.x86.avx512.conflict.q.256(<4 x i64> %{{.*}})
// CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
- return _mm256_maskz_conflict_epi64(__U, __A);
+ return _mm256_maskz_conflict_epi64(__U, __A);
}
+TEST_CONSTEXPR(match_v4di(_mm256_maskz_conflict_epi64(0x5, (__m256i)(__v4di){1, 2, 1, 3}), 0, 0, 1, 0));
+
__m128i test_mm_conflict_epi32(__m128i __A) {
// CHECK-LABEL: test_mm_conflict_epi32
// CHECK: call <4 x i32> @llvm.x86.avx512.conflict.d.128(<4 x i32> %{{.*}})
- return _mm_conflict_epi32(__A);
+ return _mm_conflict_epi32(__A);
}
+TEST_CONSTEXPR(match_v4si(_mm_conflict_epi32((__m128i)(__v4si){1, 2, 1, 3}), 0, 0, 1, 0));
+TEST_CONSTEXPR(match_v4si(_mm_conflict_epi32((__m128i)(__v4si){3, 3, 3, 3}), 0, 1, 3, 7));
+TEST_CONSTEXPR(match_v4si(_mm_conflict_epi32((__m128i)(__v4si){1, 2, 3, 4}), 0, 0, 0, 0));
+
__m128i test_mm_mask_conflict_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: test_mm_mask_conflict_epi32
// CHECK: call <4 x i32> @llvm.x86.avx512.conflict.d.128(<4 x i32> %{{.*}})
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
- return _mm_mask_conflict_epi32(__W, __U, __A);
+ return _mm_mask_conflict_epi32(__W, __U, __A);
}
+TEST_CONSTEXPR(match_v4si(_mm_mask_conflict_epi32((__m128i)(__v4si){0xFF, 0xFF, 0xFF, 0xFF}, 0x5, (__m128i)(__v4si){1, 2, 1, 3}), 0, 0xFF, 1, 0xFF));
+
__m128i test_mm_maskz_conflict_epi32(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: test_mm_maskz_conflict_epi32
// CHECK: call <4 x i32> @llvm.x86.avx512.conflict.d.128(<4 x i32> %{{.*}})
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
- return _mm_maskz_conflict_epi32(__U, __A);
+ return _mm_maskz_conflict_epi32(__U, __A);
}
+TEST_CONSTEXPR(match_v4si(_mm_maskz_conflict_epi32(0x5, (__m128i)(__v4si){1, 2, 1, 3}), 0, 0, 1, 0));
+
__m256i test_mm256_conflict_epi32(__m256i __A) {
// CHECK-LABEL: test_mm256_conflict_epi32
// CHECK: call <8 x i32> @llvm.x86.avx512.conflict.d.256(<8 x i32> %{{.*}})
- return _mm256_conflict_epi32(__A);
+ return _mm256_conflict_epi32(__A);
}
+TEST_CONSTEXPR(match_v8si(_mm256_conflict_epi32((__m256i)(__v8si){1, 2, 1, 3, 2, 4, 1, 5}), 0, 0, 1, 0, 2, 0, 5, 0));
+TEST_CONSTEXPR(match_v8si(_mm256_conflict_epi32((__m256i)(__v8si){4, 4, 4, 4, 4, 4, 4, 4}), 0, 1, 3, 7, 15, 31, 63, 127));
+TEST_CONSTEXPR(match_v8si(_mm256_conflict_epi32((__m256i)(__v8si){1, 2, 3, 4, 5, 6, 7, 8}), 0, 0, 0, 0, 0, 0, 0, 0));
+
__m256i test_mm256_mask_conflict_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_mask_conflict_epi32
// CHECK: call <8 x i32> @llvm.x86.avx512.conflict.d.256(<8 x i32> %{{.*}})
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
- return _mm256_mask_conflict_epi32(__W, __U, __A);
+ return _mm256_mask_conflict_epi32(__W, __U, __A);
}
+TEST_CONSTEXPR(match_v8si(_mm256_mask_conflict_epi32((__m256i)(__v8si){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, /*0101 0101=*/0x55, (__m256i)(__v8si){1, 2, 1, 3, 2, 4, 1, 5}), 0, 0xFF, 1, 0xFF, 2, 0xFF, 5, 0xFF));
+
__m256i test_mm256_maskz_conflict_epi32(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_maskz_conflict_epi32
// CHECK: call <8 x i32> @llvm.x86.avx512.conflict.d.256(<8 x i32> %{{.*}})
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
- return _mm256_maskz_conflict_epi32(__U, __A);
+ return _mm256_maskz_conflict_epi32(__U, __A);
}
+TEST_CONSTEXPR(match_v8si(_mm256_maskz_conflict_epi32(0x55, (__m256i)(__v8si){1, 2, 1, 3, 2, 4, 1, 5}), 0, 0, 1, 0, 2, 0, 5, 0));
+
__m128i test_mm_lzcnt_epi32(__m128i __A) {
// CHECK-LABEL: test_mm_lzcnt_epi32
// CHECK: call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %{{.*}}, i1 true)
diff --git a/clang/test/CodeGen/unified-lto-module-flag.ll b/clang/test/CodeGen/unified-lto-module-flag.ll
new file mode 100644
index 0000000..deefe82
--- /dev/null
+++ b/clang/test/CodeGen/unified-lto-module-flag.ll
@@ -0,0 +1,11 @@
+; Test that we do not duplicate the UnifiedLTO module flag.
+;
+; RUN: %clang_cc1 -emit-llvm -flto=full -funified-lto -o - %s | FileCheck %s
+
+; CHECK: !llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"wchar_size", i32 2}
+!1 = !{i32 7, !"frame-pointer", i32 2}
+!2 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
+!3 = !{i32 1, !"UnifiedLTO", i32 1}
diff --git a/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp b/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
index 4fb977a..e40b2d7 100644
--- a/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
+++ b/clang/test/CodeGenCXX/sizeof-unwind-exception.cpp
@@ -3,6 +3,8 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-DARWIN
// RUN: %clang_cc1 -triple arm-unknown-gnueabi -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-EABI
// RUN: %clang_cc1 -triple mipsel-unknown-unknown -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=MIPS
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -fcxx-exceptions -fexceptions -exception-model=seh %s -O2 -o - | FileCheck %s --check-prefix=MINGW-X86-64
+// RUN: %clang_cc1 -triple thumbv7-windows-gnu -emit-llvm -fcxx-exceptions -fexceptions -exception-model=seh %s -O2 -o - | FileCheck %s --check-prefix=MINGW-ARMV7
void foo();
void test() {
@@ -25,9 +27,15 @@ void test() {
// ARM-EABI-NEXT: [[T1:%.*]] = getelementptr i8, ptr [[EXN]], i32 88
// MIPS: [[T0:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXN:%.*]]) [[NUW:#[0-9]+]]
// MIPS-NEXT: [[T1:%.*]] = getelementptr i8, ptr [[EXN]], i32 24
+// MINGW-X86-64: [[T0:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// MINGW-X86-64-NEXT:[[T1:%.*]] = getelementptr i8, ptr [[EXN]], i64 64
+// MINGW-ARMV7: [[T0:%.*]] = tail call arm_aapcs_vfpcc ptr @__cxa_begin_catch(ptr [[EXN:%.*]]) [[NUW:#[0-9]+]]
+// MINGW-ARMV7-NEXT: [[T1:%.*]] = getelementptr i8, ptr [[EXN]], i32 48
// X86-64: attributes [[NUW]] = { nounwind }
// X86-32: attributes [[NUW]] = { nounwind }
// ARM-DARWIN: attributes [[NUW]] = { nounwind }
// ARM-EABI: attributes [[NUW]] = { nounwind }
// MIPS: attributes [[NUW]] = { nounwind }
+// MINGW-X86-64: attributes [[NUW]] = { nounwind }
+// MINGW-ARMV7: attributes [[NUW]] = { nounwind }
diff --git a/clang/test/CodeGenHLSL/basic-target.c b/clang/test/CodeGenHLSL/basic-target.c
index c700e06..b9482df 100644
--- a/clang/test/CodeGenHLSL/basic-target.c
+++ b/clang/test/CodeGenHLSL/basic-target.c
@@ -6,5 +6,5 @@
// RUN: %clang -cc1 -triple dxil-pc-shadermodel6.0-domain -emit-llvm -o - %s | FileCheck %s
// RUN: %clang -cc1 -triple dxil-pc-shadermodel6.0-geometry -emit-llvm -o - %s | FileCheck %s
-// CHECK: target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
+// CHECK: target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64-v48:16:16-v96:32:32-v192:64:64"
// CHECK: target triple = "dxilv1.0-pc-shadermodel6.0-{{[a-z]+}}"
diff --git a/clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl b/clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl
new file mode 100644
index 0000000..f23ac7c
--- /dev/null
+++ b/clang/test/CodeGenHLSL/vk-features/maximal_reconvergence.hlsl
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple spirv1.6-unknown-vulkan1.3-compute -fspv-enable-maximal-reconvergence -emit-llvm -o - -O0 %s | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_cc1 -triple spirv1.6-unknown-vulkan1.3-compute -hlsl-entry test -fspv-enable-maximal-reconvergence -emit-llvm -o - -O0 %s | FileCheck %s --check-prefixes=CHECK-ENTRY
+
+[numthreads(1,1,1)]
+void main() {
+// CHECK: define void @main() [[attributeNumber:#[0-9]+]] {
+}
+
+// CHECK: attributes [[attributeNumber]] = {{.*}} "enable-maximal-reconvergence"="true" {{.*}}
+
+
+[numthreads(1,1,1)]
+void test() {
+// CHECK-ENTRY: define void @test() [[attributeNumber:#[0-9]+]] {
+}
+
+// CHECK-ENTRY: attributes [[attributeNumber]] = {{.*}} "enable-maximal-reconvergence"="true" {{.*}}
diff --git a/clang/test/DebugInfo/CXX/versioned-language.cpp b/clang/test/DebugInfo/CXX/versioned-language.cpp
new file mode 100644
index 0000000..4cb2b29
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/versioned-language.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=5 -std=c++98 \
+// RUN: | FileCheck %s --implicit-check-not "sourceLanguageName" --implicit-check-not "sourceLanguageVersion"
+//
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++98 | FileCheck %s --check-prefix=CHECK-CPP98
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++03 | FileCheck %s --check-prefix=CHECK-CPP03
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++11 | FileCheck %s --check-prefix=CHECK-CPP11
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++14 | FileCheck %s --check-prefix=CHECK-CPP14
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++17 | FileCheck %s --check-prefix=CHECK-CPP17
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++20 | FileCheck %s --check-prefix=CHECK-CPP20
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++23 | FileCheck %s --check-prefix=CHECK-CPP23
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c++2c | FileCheck %s --check-prefix=CHECK-CPP2C
+
+struct Foo {} globalVar;
+
+// CHECK-CPP98: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 199711
+// FIXME: C++03 technically has no official standard version code. From Clang's point of view C++03 and C++98 are interchangable.
+// CHECK-CPP03: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 199711
+// CHECK-CPP11: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 201103
+// CHECK-CPP14: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 201402
+// CHECK-CPP17: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 201703
+// CHECK-CPP20: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 202002
+// CHECK-CPP23: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 202302
+// CHECK-CPP2C: !DICompileUnit(sourceLanguageName: DW_LNAME_C_plus_plus, sourceLanguageVersion: 202400
diff --git a/clang/test/DebugInfo/Generic/versioned-language.c b/clang/test/DebugInfo/Generic/versioned-language.c
new file mode 100644
index 0000000..1faa7b4
--- /dev/null
+++ b/clang/test/DebugInfo/Generic/versioned-language.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=5 -std=c99 \
+// RUN: | FileCheck %s --implicit-check-not "sourceLanguageName" --implicit-check-not "sourceLanguageVersion"
+//
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c89 | FileCheck %s --check-prefix=CHECK-C89 --implicit-check-not "sourceLanguageVersion"
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c99 | FileCheck %s --check-prefix=CHECK-C99
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c17 | FileCheck %s --check-prefix=CHECK-C17
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c23 | FileCheck %s --check-prefix=CHECK-C23
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 -std=c2y | FileCheck %s --check-prefix=CHECK-C2Y
+
+int globalVar = 10;
+
+// CHECK-C89: !DICompileUnit(sourceLanguageName: DW_LNAME_C,
+// CHECK-C99: !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 199901
+// CHECK-C11: !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 201112
+// CHECK-C17: !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 201710
+// CHECK-C23: !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 202311
+// CHECK-C2Y: !DICompileUnit(sourceLanguageName: DW_LNAME_C, sourceLanguageVersion: 202400
diff --git a/clang/test/DebugInfo/ObjC/versioned-language.m b/clang/test/DebugInfo/ObjC/versioned-language.m
new file mode 100644
index 0000000..178c47b
--- /dev/null
+++ b/clang/test/DebugInfo/ObjC/versioned-language.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=5 \
+// RUN: | FileCheck %s --implicit-check-not "sourceLanguageName" --implicit-check-not "sourceLanguageVersion"
+//
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 \
+// RUN: | FileCheck %s --implicit-check-not "sourceLanguageVersion" --check-prefix=CHECK-OBJC
+
+int globalVar = 10;
+
+// CHECK-OBJC: !DICompileUnit(sourceLanguageName: DW_LNAME_ObjC,
diff --git a/clang/test/DebugInfo/ObjCXX/versioned-language.mm b/clang/test/DebugInfo/ObjCXX/versioned-language.mm
new file mode 100644
index 0000000..bfdce46
--- /dev/null
+++ b/clang/test/DebugInfo/ObjCXX/versioned-language.mm
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=5 \
+// RUN: | FileCheck %s --implicit-check-not "sourceLanguageName" --implicit-check-not "sourceLanguageVersion"
+//
+// RUN: %clang_cc1 -emit-llvm %s -o - -debug-info-kind=limited -dwarf-version=6 \
+// RUN: | FileCheck %s --implicit-check-not "sourceLanguageVersion" --check-prefix=CHECK-OBJCXX
+
+int globalVar = 10;
+
+// CHECK-OBJCXX: !DICompileUnit(sourceLanguageName: DW_LNAME_ObjC_plus_plus,
diff --git a/clang/test/Driver/gpu-libc-headers.c b/clang/test/Driver/gpu-libc-headers.c
deleted file mode 100644
index 1802919..0000000
--- a/clang/test/Driver/gpu-libc-headers.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx90a --sysroot=%S/Inputs/basic_gpu_tree \
-// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-AMDGPU
-// RUN: %clang -### --target=nvptx64-nvidia-cuda -march=sm_89 --sysroot=%S/Inputs/basic_gpu_tree \
-// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-NVPTX
-// CHECK-HEADERS-AMDGPU: "-cc1"{{.*}}"-isysroot"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}amdgcn-amd-amdhsa"
-// CHECK-HEADERS-NVPTX: "-cc1"{{.*}}"-isysroot"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}nvptx64-nvidia-cuda"
-
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
-// RUN: -nogpuinc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
-// RUN: -nostdinc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED
-// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
-// RUN: -nobuiltininc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED
-// CHECK-HEADERS-DISABLED-NOT: "-cc1"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}gpu-none-llvm"
diff --git a/clang/test/Driver/gpu-libc.c b/clang/test/Driver/gpu-libc.c
new file mode 100644
index 0000000..88f346f3
--- /dev/null
+++ b/clang/test/Driver/gpu-libc.c
@@ -0,0 +1,32 @@
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx90a --sysroot=%S/Inputs/basic_gpu_tree \
+// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-AMDGPU
+// RUN: %clang -### --target=nvptx64-nvidia-cuda -march=sm_89 --sysroot=%S/Inputs/basic_gpu_tree \
+// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-NVPTX
+// CHECK-HEADERS-AMDGPU: "-cc1"{{.*}}"-isysroot"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}amdgcn-amd-amdhsa"
+// CHECK-HEADERS-NVPTX: "-cc1"{{.*}}"-isysroot"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}nvptx64-nvidia-cuda"
+
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
+// RUN: -nogpuinc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
+// RUN: -nostdinc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx1030 -nogpulib \
+// RUN: -nobuiltininc %s 2>&1 | FileCheck %s --check-prefix=CHECK-HEADERS-DISABLED
+// CHECK-HEADERS-DISABLED-NOT: "-cc1"{{.*}}"-internal-isystem" "{{.*}}include{{.*}}gpu-none-llvm"
+
+
+// RUN: %clang -### -fopenmp=libomp --target=x86_64-unknown-linux-gnu \
+// RUN: --offload-arch=gfx908 --rocm-path=%S/Inputs/rocm --sysroot=%S/Inputs/basic_gpu_tree \
+// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin %s 2>&1 | FileCheck %s --check-prefix=OPENMP-AMDGPU
+// OPENMP-AMDGPU: clang-linker-wrapper{{.*}}"--device-linker=amdgcn-amd-amdhsa=-lc"
+// RUN: %clang -### -fopenmp=libomp --target=x86_64-unknown-linux-gnu -foffload-lto \
+// RUN: --offload-arch=sm_52 --cuda-path=%S/Inputs/CUDA_111/usr/local/cuda --sysroot=%S/Inputs/basic_gpu_tree \
+// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin %s 2>&1 | FileCheck %s --check-prefix=OPENMP-NVPTX
+// OPENMP-NVPTX: clang-linker-wrapper{{.*}}"--device-linker=nvptx64-nvidia-cuda=-lc"
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx908 \
+// RUN: --offload-new-driver --rocm-path=%S/Inputs/rocm --sysroot=%S/Inputs/basic_gpu_tree \
+// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin -x hip %s 2>&1 | FileCheck %s --check-prefix=HIP
+// HIP-NOT: "--device-linker=amdgcn-amd-amdhsa=-lc"
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fgpu-rdc --offload-arch=sm_52 \
+// RUN: --cuda-path=%S/Inputs/CUDA_111/usr/local/cuda --sysroot=%S/Inputs/basic_gpu_tree \
+// RUN: -ccc-install-dir %S/Inputs/basic_gpu_tree/bin -x cuda %s 2>&1 | FileCheck %s --check-prefix=CUDA
+// CUDA-NOT: "--device-linker=nvptx64-nvidia-cuda=-lc"
diff --git a/clang/test/Parser/DelayedTemplateParsing.cpp b/clang/test/Parser/DelayedTemplateParsing.cpp
index bcd286a..072c7ce 100644
--- a/clang/test/Parser/DelayedTemplateParsing.cpp
+++ b/clang/test/Parser/DelayedTemplateParsing.cpp
@@ -43,10 +43,10 @@ void undeclared()
}
-template <class T> void foo5() {} //expected-note {{previous definition is here}}
+template <class T> void foo5() {} //expected-note {{previous definition is here}}
template <class T> void foo5() {} // expected-error {{redefinition of 'foo5'}}
-
+
namespace PR11931 {
@@ -195,3 +195,12 @@ template <typename> struct PR38460_2 {
}
};
template struct PR38460_2<int>;
+
+namespace LateParsedAttrs {
+ template <class>
+ void f(int a) __attribute__((__diagnose_if__(a > 0, "foo", "error"))) {}
+ // expected-note@-1 {{from 'diagnose_if' attribute on 'f<int>'}}
+ void g() {
+ f<int>(1); // expected-error {{foo}}
+ }
+} // namespace LateParsedAttrs
diff --git a/clang/test/Preprocessor/embed___has_embed_parsing_errors.c b/clang/test/Preprocessor/embed___has_embed_parsing_errors.c
index 9c512a48..8ab53f6 100644
--- a/clang/test/Preprocessor/embed___has_embed_parsing_errors.c
+++ b/clang/test/Preprocessor/embed___has_embed_parsing_errors.c
@@ -250,3 +250,35 @@
#if __has_embed("") // expected-error {{empty filename}}
#endif
+
+// expected-error@+3 {{missing ')' after '__has_embed'}} \
+ expected-error@+3 {{expected value in expression}} \
+ expected-note@+3 {{to match this '('}}
+#if __has_embed (__FILE__ foo limit(1)
+#endif
+
+//--- test3.c
+// expected-error@+3 {{missing ')' after '__has_embed'}} \
+ expected-error@+3 {{expected value in expression}} \
+ expected-note@+3 {{to match this '('}}
+#if __has_embed (__FILE__ foo
+#endif
+
+// expected-error@+3 {{missing ')' after '__has_embed'}} \
+ expected-error@+3 {{expected value in expression}} \
+ expected-note@+3 {{to match this '('}}
+#if __has_embed ("a" foo()
+#endif
+
+// expected-error@+3 {{missing ')' after '__has_embed'}} \
+ expected-error@+3 {{expected value in expression}} \
+ expected-note@+3 {{to match this '('}}
+#if __has_embed ("a" bar() foo
+#endif
+
+// expected-error@+3 {{missing ')' after '__has_embed'}} \
+ expected-error@+3 {{expected value in expression}} \
+ expected-note@+3 {{to match this '('}}
+#if __has_embed (__FILE__ limit(1) foo
+int a = __has_embed (__FILE__);
+#endif
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index ef79e45..50da2f8 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -417,7 +417,8 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) {
}
static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
- DiagnosticsEngine &Diags) {
+ DiagnosticsEngine &Diags,
+ IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
// Get the target specific parser.
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
@@ -440,6 +441,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
// Record the location of the include directories so that the lexer can find
// it later.
SrcMgr.setIncludeDirs(Opts.IncludePaths);
+ SrcMgr.setVirtualFileSystem(VFS);
std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
assert(MRI && "Unable to create target register info!");
@@ -632,8 +634,9 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
}
static bool ExecuteAssembler(AssemblerInvocation &Opts,
- DiagnosticsEngine &Diags) {
- bool Failed = ExecuteAssemblerImpl(Opts, Diags);
+ DiagnosticsEngine &Diags,
+ IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
+ bool Failed = ExecuteAssemblerImpl(Opts, Diags, VFS);
// Delete output file if there were errors.
if (Failed) {
@@ -714,7 +717,7 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
}
// Execute the invocation, unless there were parsing errors.
- bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags);
+ bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags, VFS);
// If any timers were active but haven't been destroyed yet, print their
// results now.
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index d18c45e..fc27fd2 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1644,9 +1644,9 @@ bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
return true;
if (TL.isDefinition())
- return Visit(MakeCXCursor(TL.getOriginalDecl(), TU, RegionOfInterest));
+ return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
- return Visit(MakeCursorTypeRef(TL.getOriginalDecl(), TL.getNameLoc(), TU));
+ return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}
bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
@@ -1852,7 +1852,7 @@ bool CursorVisitor::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {
}
bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- return Visit(MakeCursorTypeRef(TL.getOriginalDecl(), TL.getNameLoc(), TU));
+ return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}
bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp
index 6d14f28..81448b4 100644
--- a/clang/tools/libclang/CIndexCodeCompletion.cpp
+++ b/clang/tools/libclang/CIndexCodeCompletion.cpp
@@ -617,7 +617,7 @@ namespace {
if (!baseType.isNull()) {
// Get the declaration for a class/struct/union/enum type
if (const TagType *Tag = baseType->getAs<TagType>())
- D = Tag->getOriginalDecl();
+ D = Tag->getDecl();
// Get the @interface declaration for a (possibly-qualified) Objective-C
// object pointer type, e.g., NSString*
else if (const ObjCObjectPointerType *ObjPtr =
@@ -629,7 +629,7 @@ namespace {
// Get the class for a C++ injected-class-name
else if (const InjectedClassNameType *Injected =
baseType->getAs<InjectedClassNameType>())
- D = Injected->getOriginalDecl();
+ D = Injected->getDecl();
}
if (D != nullptr) {
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index 56f113c..0a43d73 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -1338,7 +1338,7 @@ CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
if (const TagType *Tag = Ty->getAs<TagType>())
- return MakeCursorTypeRef(Tag->getOriginalDecl(), Loc, TU);
+ return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp
index 932201a..c97aefa 100644
--- a/clang/tools/libclang/CXIndexDataConsumer.cpp
+++ b/clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -357,7 +357,7 @@ CXIndexDataConsumer::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
TST = T->getAs<TemplateSpecializationType>()) {
BaseD = TST->getTemplateName().getAsTemplateDecl();
} else if (const RecordType *RT = T->getAs<RecordType>()) {
- BaseD = RT->getOriginalDecl();
+ BaseD = RT->getDecl();
}
if (BaseD)
diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp
index d21ac7c..3feb563 100644
--- a/clang/tools/libclang/CXType.cpp
+++ b/clang/tools/libclang/CXType.cpp
@@ -546,11 +546,11 @@ try_again:
break;
case Type::Record:
case Type::Enum:
- D = cast<TagType>(TP)->getOriginalDecl();
+ D = cast<TagType>(TP)->getDecl();
break;
case Type::TemplateSpecialization:
if (const RecordType *Record = TP->getAs<RecordType>())
- D = Record->getOriginalDecl();
+ D = Record->getDecl();
else
D = cast<TemplateSpecializationType>(TP)->getTemplateName()
.getAsTemplateDecl();
@@ -564,7 +564,7 @@ try_again:
break;
case Type::InjectedClassName:
- D = cast<InjectedClassNameType>(TP)->getOriginalDecl();
+ D = cast<InjectedClassNameType>(TP)->getDecl();
break;
// FIXME: Template type parameters!
@@ -1037,7 +1037,7 @@ static long long visitRecordForValidation(const RecordDecl *RD) {
return CXTypeLayoutError_Dependent;
// recurse
if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
- if (const RecordDecl *Child = ChildType->getOriginalDecl()) {
+ if (const RecordDecl *Child = ChildType->getDecl()) {
long long ret = visitRecordForValidation(Child);
if (ret < 0)
return ret;
diff --git a/clang/unittests/AST/ASTContextParentMapTest.cpp b/clang/unittests/AST/ASTContextParentMapTest.cpp
index 4a8aa48..545eaf3 100644
--- a/clang/unittests/AST/ASTContextParentMapTest.cpp
+++ b/clang/unittests/AST/ASTContextParentMapTest.cpp
@@ -132,8 +132,7 @@ TEST(GetParents, FriendTypeLoc) {
TypeLoc FrALoc = FrA.getFriendType()->getTypeLoc();
TypeLoc FrBLoc = FrB.getFriendType()->getTypeLoc();
bool FrAOwnsTag = FrALoc.getTypePtr()->getAs<TagType>()->isTagOwned();
- TagDecl *FrATagDecl =
- FrALoc.getTypePtr()->getAs<TagType>()->getOriginalDecl();
+ TagDecl *FrATagDecl = FrALoc.getTypePtr()->getAs<TagType>()->getDecl();
bool FrBOwnsTag = FrBLoc.getTypePtr()->getAs<TagType>()->isTagOwned();
EXPECT_THAT(Ctx.getParents(A), ElementsAre(DynTypedNode::create(TU)));
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index e7160bc..4c7ea5e 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -29,7 +29,7 @@ using internal::Matcher;
static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) {
QualType Ty = FD->getFriendType()->getType().getCanonicalType();
- return cast<RecordType>(Ty)->getOriginalDecl();
+ return cast<RecordType>(Ty)->getDecl();
}
struct ImportExpr : TestImportBase {};
@@ -4614,7 +4614,7 @@ TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl());
QualType FT = Friend->getFriendType()->getType();
FT = FromTU0->getASTContext().getCanonicalType(FT);
- auto *Fwd = cast<TagType>(FT)->getOriginalDecl();
+ auto *Fwd = cast<TagType>(FT)->getDecl();
auto *ImportedFwd = Import(Fwd, Lang_CXX03);
Decl *FromTU1 = getTuDecl(
R"(
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index bee288d..24e20c7 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -719,13 +719,11 @@ TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
TU, indirectFieldDecl(hasName("a")));
auto *FA = cast<FieldDecl>(A->chain().front());
- RecordDecl *RA =
- cast<RecordType>(FA->getType().getTypePtr())->getOriginalDecl();
+ RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
TU, indirectFieldDecl(hasName("b")));
auto *FB = cast<FieldDecl>(B->chain().front());
- RecordDecl *RB =
- cast<RecordType>(FB->getType().getTypePtr())->getOriginalDecl();
+ RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
ASSERT_NE(RA, RB);
EXPECT_TRUE(testStructuralMatch(RA, RA));
@@ -754,15 +752,13 @@ TEST_F(StructuralEquivalenceRecordTest,
auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
TU, indirectFieldDecl(hasName("a")));
auto *FA = cast<FieldDecl>(A->chain().front());
- RecordDecl *RA =
- cast<RecordType>(FA->getType().getTypePtr())->getOriginalDecl();
+ RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
auto *TU1 = get<1>(t);
auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
TU1, indirectFieldDecl(hasName("a")));
auto *FA1 = cast<FieldDecl>(A1->chain().front());
- RecordDecl *RA1 =
- cast<RecordType>(FA1->getType().getTypePtr())->getOriginalDecl();
+ RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
RecordDecl *X =
FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
diff --git a/clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp b/clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp
index c280921..d3dee58 100644
--- a/clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/MockHeaders.cpp
@@ -27,6 +27,9 @@ using nullptr_t = decltype(nullptr);
} // namespace std
+typedef decltype(sizeof(char)) size_t;
+typedef decltype(sizeof(char*)) ptrdiff_t;
+
#endif // CSTDDEF_H
)";
@@ -479,12 +482,38 @@ struct conjunction<T, Ts...>
template <typename T>
struct conjunction<T> : T {};
+template <typename... Ts>
+struct disjunction : std::false_type {};
+
+template <typename T, typename... Ts>
+struct disjunction<T, Ts...>
+ : std::conditional<T::value, T, disjunction<Ts...>>::type {};
+
+template <typename T>
+struct disjunction<T> : T {};
+
template <typename T>
struct negation : std::integral_constant<bool, !T::value> {};
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
+
+template <bool B, typename T, typename F>
+using conditional_t = typename std::conditional<B, T, F>::type;
+
+template <typename T>
+using remove_cv_t = typename std::remove_cv<T>::type;
+
+template <typename T>
+using remove_reference_t = typename std::remove_reference<T>::type;
+
+template <typename T>
+using decay_t = typename std::decay<T>::type;
+
+struct in_place_t {};
+
+constexpr in_place_t in_place;
} // namespace absl
#endif // ABSL_TYPE_TRAITS_H
@@ -499,8 +528,16 @@ namespace std {
struct string {
string(const char*);
~string();
+ const char *c_str() const;
+ bool empty();
+};
+
+struct string_view {
+ string_view(const char*);
+ ~string_view();
bool empty();
};
+
bool operator!=(const string &LHS, const char *RHS);
} // namespace std
@@ -792,9 +829,6 @@ struct nullopt_t {
};
constexpr nullopt_t nullopt;
-struct in_place_t {};
-constexpr in_place_t in_place;
-
template <typename T>
class optional;
@@ -1240,6 +1274,964 @@ constexpr bool operator!=(const T &value, const Optional<U> &opt);
} // namespace base
)";
+constexpr const char StatusDefsHeader[] =
+ R"cc(
+#ifndef STATUS_H_
+#define STATUS_H_
+
+#include "absl_type_traits.h"
+#include "std_initializer_list.h"
+#include "std_string.h"
+#include "std_type_traits.h"
+#include "std_utility.h"
+
+namespace absl {
+struct SourceLocation {
+ static constexpr SourceLocation current();
+ static constexpr SourceLocation
+ DoNotInvokeDirectlyNoSeriouslyDont(int line, const char *file_name);
+};
+} // namespace absl
+namespace absl {
+enum class StatusCode : int {
+ kOk,
+ kCancelled,
+ kUnknown,
+ kInvalidArgument,
+ kDeadlineExceeded,
+ kNotFound,
+ kAlreadyExists,
+ kPermissionDenied,
+ kResourceExhausted,
+ kFailedPrecondition,
+ kAborted,
+ kOutOfRange,
+ kUnimplemented,
+ kInternal,
+ kUnavailable,
+ kDataLoss,
+ kUnauthenticated,
+};
+} // namespace absl
+
+namespace absl {
+enum class StatusToStringMode : int {
+ kWithNoExtraData = 0,
+ kWithPayload = 1 << 0,
+ kWithSourceLocation = 1 << 1,
+ kWithEverything = ~kWithNoExtraData,
+ kDefault = kWithPayload,
+};
+class Status {
+public:
+ Status();
+ template <typename Enum> Status(Enum code, std::string_view msg);
+ Status(absl::StatusCode code, std::string_view msg,
+ absl::SourceLocation loc = SourceLocation::current());
+ Status(const Status &base_status, absl::SourceLocation loc);
+ Status(Status &&base_status, absl::SourceLocation loc);
+ ~Status() {}
+
+ Status(const Status &);
+ Status &operator=(const Status &x);
+
+ Status(Status &&) noexcept;
+ Status &operator=(Status &&);
+
+ friend bool operator==(const Status &, const Status &);
+ friend bool operator!=(const Status &, const Status &);
+
+ bool ok() const { return true; }
+ void CheckSuccess() const;
+ void IgnoreError() const;
+ int error_code() const;
+ absl::Status ToCanonical() const;
+ std::string
+ ToString(StatusToStringMode m = StatusToStringMode::kDefault) const;
+ void Update(const Status &new_status);
+ void Update(Status &&new_status);
+};
+
+bool operator==(const Status &lhs, const Status &rhs);
+bool operator!=(const Status &lhs, const Status &rhs);
+
+Status OkStatus();
+Status InvalidArgumentError(char *);
+
+#endif // STATUS_H
+)cc";
+
+constexpr const char StatusOrDefsHeader[] = R"cc(
+#ifndef STATUSOR_H_
+#define STATUSOR_H_
+#include "absl_type_traits.h"
+#include "status_defs.h"
+#include "std_initializer_list.h"
+#include "std_type_traits.h"
+#include "std_utility.h"
+
+template <typename T> struct StatusOr;
+
+namespace internal_statusor {
+
+template <typename T, typename U, typename = void>
+struct HasConversionOperatorToStatusOr : std::false_type {};
+
+template <typename T, typename U>
+void test(char (*)[sizeof(std::declval<U>().operator absl::StatusOr<T>())]);
+
+template <typename T, typename U>
+struct HasConversionOperatorToStatusOr<T, U, decltype(test<T, U>(0))>
+ : std::true_type {};
+
+template <typename T, typename U>
+using IsConstructibleOrConvertibleFromStatusOr =
+ absl::disjunction<std::is_constructible<T, StatusOr<U> &>,
+ std::is_constructible<T, const StatusOr<U> &>,
+ std::is_constructible<T, StatusOr<U> &&>,
+ std::is_constructible<T, const StatusOr<U> &&>,
+ std::is_convertible<StatusOr<U> &, T>,
+ std::is_convertible<const StatusOr<U> &, T>,
+ std::is_convertible<StatusOr<U> &&, T>,
+ std::is_convertible<const StatusOr<U> &&, T>>;
+
+template <typename T, typename U>
+using IsConstructibleOrConvertibleOrAssignableFromStatusOr =
+ absl::disjunction<IsConstructibleOrConvertibleFromStatusOr<T, U>,
+ std::is_assignable<T &, StatusOr<U> &>,
+ std::is_assignable<T &, const StatusOr<U> &>,
+ std::is_assignable<T &, StatusOr<U> &&>,
+ std::is_assignable<T &, const StatusOr<U> &&>>;
+
+template <typename T, typename U>
+struct IsDirectInitializationAmbiguous
+ : public absl::conditional_t<
+ std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>,
+ U>::value,
+ std::false_type,
+ IsDirectInitializationAmbiguous<
+ T, absl::remove_cv_t<absl::remove_reference_t<U>>>> {};
+
+template <typename T, typename V>
+struct IsDirectInitializationAmbiguous<T, absl::StatusOr<V>>
+ : public IsConstructibleOrConvertibleFromStatusOr<T, V> {};
+
+template <typename T, typename U>
+using IsDirectInitializationValid = absl::disjunction<
+ // Short circuits if T is basically U.
+ std::is_same<T, absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ absl::negation<absl::disjunction<
+ std::is_same<absl::StatusOr<T>,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ std::is_same<absl::Status,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ std::is_same<absl::in_place_t,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ IsDirectInitializationAmbiguous<T, U>>>>;
+
+template <typename T, typename U>
+struct IsForwardingAssignmentAmbiguous
+ : public absl::conditional_t<
+ std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>,
+ U>::value,
+ std::false_type,
+ IsForwardingAssignmentAmbiguous<
+ T, absl::remove_cv_t<absl::remove_reference_t<U>>>> {};
+
+template <typename T, typename U>
+struct IsForwardingAssignmentAmbiguous<T, absl::StatusOr<U>>
+ : public IsConstructibleOrConvertibleOrAssignableFromStatusOr<T, U> {};
+
+template <typename T, typename U>
+using IsForwardingAssignmentValid = absl::disjunction<
+ // Short circuits if T is basically U.
+ std::is_same<T, absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ absl::negation<absl::disjunction<
+ std::is_same<absl::StatusOr<T>,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ std::is_same<absl::Status,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ std::is_same<absl::in_place_t,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ IsForwardingAssignmentAmbiguous<T, U>>>>;
+
+template <typename T, typename U>
+using IsForwardingAssignmentValid = absl::disjunction<
+ // Short circuits if T is basically U.
+ std::is_same<T, absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ absl::negation<absl::disjunction<
+ std::is_same<absl::StatusOr<T>,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ std::is_same<absl::Status,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ std::is_same<absl::in_place_t,
+ absl::remove_cv_t<absl::remove_reference_t<U>>>,
+ IsForwardingAssignmentAmbiguous<T, U>>>>;
+
+template <typename T> struct OperatorBase {
+ const T &value() const &;
+ T &value() &;
+ const T &&value() const &&;
+ T &&value() &&;
+
+ const T &operator*() const &;
+ T &operator*() &;
+ const T &&operator*() const &&;
+ T &&operator*() &&;
+
+ // To test that analyses are okay if there is a use of operator*
+ // within this base class.
+ const T *operator->() const { return __builtin_addressof(**this); }
+ T *operator->() { return __builtin_addressof(**this); }
+};
+
+} // namespace internal_statusor
+
+template <typename T>
+struct StatusOr : private internal_statusor::OperatorBase<T> {
+ explicit StatusOr();
+
+ StatusOr(const StatusOr &) = default;
+ StatusOr &operator=(const StatusOr &) = default;
+
+ StatusOr(StatusOr &&) = default;
+ StatusOr &operator=(StatusOr &&) = default;
+
+ template <
+ typename U,
+ absl::enable_if_t<
+ absl::conjunction<
+ absl::negation<std::is_same<T, U>>,
+ std::is_constructible<T, const U &>,
+ std::is_convertible<const U &, T>,
+ absl::negation<
+ internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
+ T, U>>>::value,
+ int> = 0>
+ StatusOr(const StatusOr<U> &);
+
+ template <
+ typename U,
+ absl::enable_if_t<
+ absl::conjunction<
+ absl::negation<std::is_same<T, U>>,
+ std::is_constructible<T, const U &>,
+ absl::negation<std::is_convertible<const U &, T>>,
+ absl::negation<
+ internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
+ T, U>>>::value,
+ int> = 0>
+ explicit StatusOr(const StatusOr<U> &);
+
+ template <
+ typename U,
+ absl::enable_if_t<
+ absl::conjunction<
+ absl::negation<std::is_same<T, U>>,
+ std::is_constructible<T, U &&>, std::is_convertible<U &&, T>,
+ absl::negation<
+ internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
+ T, U>>>::value,
+ int> = 0>
+ StatusOr(StatusOr<U> &&);
+
+ template <
+ typename U,
+ absl::enable_if_t<
+ absl::conjunction<
+ absl::negation<std::is_same<T, U>>,
+ std::is_constructible<T, U &&>,
+ absl::negation<std::is_convertible<U &&, T>>,
+ absl::negation<
+ internal_statusor::IsConstructibleOrConvertibleFromStatusOr<
+ T, U>>>::value,
+ int> = 0>
+ explicit StatusOr(StatusOr<U> &&);
+
+ template <
+ typename U,
+ absl::enable_if_t<
+ absl::conjunction<
+ absl::negation<std::is_same<T, U>>,
+ std::is_constructible<T, const U &>,
+ std::is_assignable<T, const U &>,
+ absl::negation<
+ internal_statusor::
+ IsConstructibleOrConvertibleOrAssignableFromStatusOr<
+ T, U>>>::value,
+ int> = 0>
+ StatusOr &operator=(const StatusOr<U> &);
+
+ template <
+ typename U,
+ absl::enable_if_t<
+ absl::conjunction<
+ absl::negation<std::is_same<T, U>>,
+ std::is_constructible<T, U &&>, std::is_assignable<T, U &&>,
+ absl::negation<
+ internal_statusor::
+ IsConstructibleOrConvertibleOrAssignableFromStatusOr<
+ T, U>>>::value,
+ int> = 0>
+ StatusOr &operator=(StatusOr<U> &&);
+
+ template <
+ typename U = absl::Status,
+ absl::enable_if_t<
+ absl::conjunction<
+ std::is_convertible<U &&, absl::Status>,
+ std::is_constructible<absl::Status, U &&>,
+ absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>,
+ absl::negation<std::is_same<absl::decay_t<U>, T>>,
+ absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>,
+ absl::negation<internal_statusor::HasConversionOperatorToStatusOr<
+ T, U &&>>>::value,
+ int> = 0>
+ StatusOr(U &&);
+
+ template <
+ typename U = absl::Status,
+ absl::enable_if_t<
+ absl::conjunction<
+ absl::negation<std::is_convertible<U &&, absl::Status>>,
+ std::is_constructible<absl::Status, U &&>,
+ absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>,
+ absl::negation<std::is_same<absl::decay_t<U>, T>>,
+ absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>,
+ absl::negation<internal_statusor::HasConversionOperatorToStatusOr<
+ T, U &&>>>::value,
+ int> = 0>
+ explicit StatusOr(U &&);
+
+ template <
+ typename U = absl::Status,
+ absl::enable_if_t<
+ absl::conjunction<
+ std::is_convertible<U &&, absl::Status>,
+ std::is_constructible<absl::Status, U &&>,
+ absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>,
+ absl::negation<std::is_same<absl::decay_t<U>, T>>,
+ absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>,
+ absl::negation<internal_statusor::HasConversionOperatorToStatusOr<
+ T, U &&>>>::value,
+ int> = 0>
+ StatusOr &operator=(U &&);
+
+ template <
+ typename U = T,
+ typename = typename std::enable_if<absl::conjunction<
+ std::is_constructible<T, U &&>, std::is_assignable<T &, U &&>,
+ absl::disjunction<
+ std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, T>,
+ absl::conjunction<
+ absl::negation<std::is_convertible<U &&, absl::Status>>,
+ absl::negation<
+ internal_statusor::HasConversionOperatorToStatusOr<
+ T, U &&>>>>,
+ internal_statusor::IsForwardingAssignmentValid<T, U &&>>::value>::
+ type>
+ StatusOr &operator=(U &&);
+
+ template <typename... Args> explicit StatusOr(absl::in_place_t, Args &&...);
+
+ template <typename U, typename... Args>
+ explicit StatusOr(absl::in_place_t, std::initializer_list<U>, Args &&...);
+
+ template <
+ typename U = T,
+ absl::enable_if_t<
+ absl::conjunction<
+ internal_statusor::IsDirectInitializationValid<T, U &&>,
+ std::is_constructible<T, U &&>, std::is_convertible<U &&, T>,
+ absl::disjunction<
+ std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>,
+ T>,
+ absl::conjunction<
+ absl::negation<std::is_convertible<U &&, absl::Status>>,
+ absl::negation<
+ internal_statusor::HasConversionOperatorToStatusOr<
+ T, U &&>>>>>::value,
+ int> = 0>
+ StatusOr(U &&);
+
+ template <
+ typename U = T,
+ absl::enable_if_t<
+ absl::conjunction<
+ internal_statusor::IsDirectInitializationValid<T, U &&>,
+ absl::disjunction<
+ std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>,
+ T>,
+ absl::conjunction<
+ absl::negation<std::is_constructible<absl::Status, U &&>>,
+ absl::negation<
+ internal_statusor::HasConversionOperatorToStatusOr<
+ T, U &&>>>>,
+ std::is_constructible<T, U &&>,
+ absl::negation<std::is_convertible<U &&, T>>>::value,
+ int> = 0>
+ explicit StatusOr(U &&);
+
+ bool ok() const;
+
+ const Status &status() const & { return status_; }
+ Status status() &&;
+
+ using StatusOr::OperatorBase::value;
+
+ const T &ValueOrDie() const &;
+ T &ValueOrDie() &;
+ const T &&ValueOrDie() const &&;
+ T &&ValueOrDie() &&;
+
+ using StatusOr::OperatorBase::operator*;
+ using StatusOr::OperatorBase::operator->;
+
+ template <typename U> T value_or(U &&default_value) const &;
+ template <typename U> T value_or(U &&default_value) &&;
+
+ template <typename... Args> T &emplace(Args &&...args);
+
+ template <
+ typename U, typename... Args,
+ absl::enable_if_t<std::is_constructible<T, std::initializer_list<U> &,
+ Args &&...>::value,
+ int> = 0>
+ T &emplace(std::initializer_list<U> ilist, Args &&...args);
+
+private:
+ absl::Status status_;
+};
+
+template <typename T>
+bool operator==(const StatusOr<T> &lhs, const StatusOr<T> &rhs);
+
+template <typename T>
+bool operator!=(const StatusOr<T> &lhs, const StatusOr<T> &rhs);
+
+} // namespace absl
+
+#endif // STATUSOR_H_
+)cc";
+
+static constexpr char StdVectorHeader[] = R"cc(
+#ifndef STD_VECTOR_H
+#define STD_VECTOR_H
+namespace std {
+template <class T> struct allocator {
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T *pointer;
+ typedef const T *const_pointer;
+ typedef T value_type;
+
+ T *allocate(size_t n);
+};
+
+template <class Alloc> struct allocator_traits {
+ typedef Alloc allocator_type;
+ typedef typename allocator_type::value_type value_type;
+ typedef typename allocator_type::pointer pointer;
+ typedef typename allocator_type::const_pointer const_pointer;
+ typedef typename allocator_type::difference_type difference_type;
+ typedef typename allocator_type::size_type size_type;
+};
+
+template <typename T, class Allocator = allocator<T>> class vector {
+public:
+ using value_type = T;
+ using size_type = typename allocator_traits<Allocator>::size_type;
+
+ // Constructors.
+ vector() {}
+ vector(size_type, const Allocator & = Allocator()) {}
+ vector(initializer_list<T> initializer_list,
+ const Allocator & = Allocator()) {}
+ vector(const vector &vector) {}
+ ~vector();
+
+ // Modifiers.
+ void push_back(const T &value);
+ void push_back(T &&value);
+ template <typename... Args> T &emplace_back(Args &&...args);
+
+ // Iterators
+ class InputIterator {
+ public:
+ InputIterator(const InputIterator &);
+ ~InputIterator();
+ InputIterator &operator=(const InputIterator &);
+ InputIterator &operator++();
+ T &operator*() const;
+ bool operator!=(const InputIterator &) const;
+ bool operator==(const InputIterator &) const;
+ };
+ typedef InputIterator iterator;
+ typedef const InputIterator const_iterator;
+ iterator begin() noexcept;
+ const_iterator begin() const noexcept;
+ const_iterator cbegin() const noexcept;
+ iterator end() noexcept;
+ const_iterator end() const noexcept;
+ const_iterator cend() const noexcept;
+ T *data() noexcept;
+ const T *data() const noexcept;
+ T &operator[](int n);
+ const T &operator[](int n) const;
+ T &at(int n);
+ const T &at(int n) const;
+ size_t size() const;
+};
+} // namespace std
+#endif // STD_VECTOR_H
+)cc";
+
+static constexpr char StdPairHeader[] = R"cc(
+#ifndef STD_PAIR_H
+#define STD_PAIR_H
+namespace std {
+template <class T1, class T2> struct pair {
+ T1 first;
+ T2 second;
+
+ typedef T1 first_type;
+ typedef T2 second_type;
+
+ constexpr pair();
+
+ template <class U1, class U2> pair(pair<U1, U2> &&p);
+
+ template <class U1, class U2> pair(U1 &&x, U2 &&y);
+};
+
+template <class T1, class T2> pair<T1, T2> make_pair(T1 &&t1, T2 &&t2);
+} // namespace std
+#endif // STD_PAIR_H
+)cc";
+
+constexpr const char AbslLogHeader[] = R"cc(
+#ifndef ABSL_LOG_H
+#define ABSL_LOG_H
+
+#include "std_pair.h"
+
+namespace absl {
+
+#define ABSL_PREDICT_FALSE(x) (__builtin_expect(false || (x), false))
+#define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true))
+
+namespace log_internal {
+class LogMessage {
+public:
+ LogMessage();
+ LogMessage &stream();
+ LogMessage &InternalStream();
+ LogMessage &WithVerbosity(int verboselevel);
+ template <typename T> LogMessage &operator<<(const T &);
+};
+class LogMessageFatal : public LogMessage {
+public:
+ LogMessageFatal();
+ ~LogMessageFatal() __attribute__((noreturn));
+};
+class LogMessageQuietlyFatal : public LogMessage {
+public:
+ LogMessageQuietlyFatal();
+ ~LogMessageQuietlyFatal() __attribute__((noreturn));
+};
+class Voidify final {
+public:
+ // This has to be an operator with a precedence lower than << but higher
+ // than
+ // ?:
+ template <typename T> void operator&&(const T &) const && {}
+};
+} // namespace log_internal
+} // namespace absl
+
+#ifndef NULL
+#define NULL __null
+#endif
+extern "C" void abort() {}
+#define ABSL_LOG_INTERNAL_LOG_INFO ::absl::log_internal::LogMessage()
+#define ABSL_LOG_INTERNAL_LOG_WARNING ::absl::log_internal::LogMessage()
+#define ABSL_LOG_INTERNAL_LOG_ERROR ::absl::log_internal::LogMessage()
+#define ABSL_LOG_INTERNAL_LOG_FATAL ::absl::log_internal::LogMessageFatal()
+#define ABSL_LOG_INTERNAL_LOG_QFATAL \
+ ::absl::log_internal::LogMessageQuietlyFatal()
+#define LOG(severity) ABSL_LOG_INTERNAL_LOG_##severity.InternalStream()
+
+#define PREDICT_FALSE(x) (__builtin_expect(x, 0))
+#define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(lit) lit
+
+#define ABSL_LOG_INTERNAL_STATELESS_CONDITION(condition) \
+ switch (0) \
+ case 0: \
+ default: \
+ !(condition) ? (void)0 : ::absl::log_internal::Voidify() &&
+
+#define ABSL_LOG_INTERNAL_CONDITION_INFO(type, condition) \
+ ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
+
+#define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition) \
+ ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
+
+#define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition) \
+ ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
+
+#define ABSL_CHECK_IMPL(condition, condition_text) \
+ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, \
+ ABSL_PREDICT_FALSE(!(condition))) \
+ ABSL_LOG_INTERNAL_CHECK(condition_text).InternalStream()
+
+#define ABSL_QCHECK_IMPL(condition, condition_text) \
+ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, \
+ ABSL_PREDICT_FALSE(!(condition))) \
+ ABSL_LOG_INTERNAL_QCHECK(condition_text).InternalStream()
+
+#define CHECK(condition) ABSL_CHECK_IMPL((condition), #condition)
+#define DCHECK(condition) CHECK(condition)
+#define QCHECK(condition) ABSL_QCHECK_IMPL((condition), #condition)
+
+#define ABSL_LOG_INTERNAL_MAX_LOG_VERBOSITY_CHECK(x)
+
+namespace absl {
+
+template <typename T> class StatusOr;
+class Status;
+
+namespace status_internal {
+std::string *MakeCheckFailString(const absl::Status *status,
+ const char *prefix);
+} // namespace status_internal
+
+namespace log_internal {
+template <class T> const T &GetReferenceableValue(const T &t);
+char GetReferenceableValue(char t);
+unsigned char GetReferenceableValue(unsigned char t);
+signed char GetReferenceableValue(signed char t);
+short GetReferenceableValue(short t);
+unsigned short GetReferenceableValue(unsigned short t);
+int GetReferenceableValue(int t);
+unsigned int GetReferenceableValue(unsigned int t);
+long GetReferenceableValue(long t);
+unsigned long GetReferenceableValue(unsigned long t);
+long long GetReferenceableValue(long long t);
+unsigned long long GetReferenceableValue(unsigned long long t);
+const absl::Status *AsStatus(const absl::Status &s);
+template <typename T> const absl::Status *AsStatus(const absl::StatusOr<T> &s);
+} // namespace log_internal
+} // namespace absl
+// TODO(tkd): this still doesn't allow operator<<, unlike the real CHECK_
+// macros.
+#define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val2) \
+ while (char *_result = ::absl::log_internal::name##Impl( \
+ ::absl::log_internal::GetReferenceableValue(val1), \
+ ::absl::log_internal::GetReferenceableValue(val2), \
+ #val1 " " #op " " #val2)) \
+ (void)0
+#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val2) \
+ while (char *_result = ::absl::log_internal::name##Impl( \
+ ::absl::log_internal::GetReferenceableValue(val1), \
+ ::absl::log_internal::GetReferenceableValue(val2), \
+ #val1 " " #op " " #val2)) \
+ (void)0
+namespace absl {
+namespace log_internal {
+template <class T1, class T2>
+char *Check_NEImpl(const T1 &v1, const T2 &v2, const char *names);
+template <class T1, class T2>
+char *Check_EQImpl(const T1 &v1, const T2 &v2, const char *names);
+template <class T1, class T2>
+char *Check_LTImpl(const T1 &v1, const T2 &v2, const char *names);
+
+#define CHECK_EQ(a, b) ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, ==, a, b)
+#define CHECK_NE(a, b) ABSL_LOG_INTERNAL_CHECK_OP(Check_NE, !=, a, b)
+#define CHECK_LT(a, b) ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, <, a, b)
+
+#define QCHECK_EQ(a, b) ABSL_LOG_INTERNAL_QCHECK_OP(Check_EQ, ==, a, b)
+#define QCHECK_NE(a, b) ABSL_LOG_INTERNAL_QCHECK_OP(Check_NE, !=, a, b)
+} // namespace log_internal
+} // namespace absl
+
+#define CHECK_NOTNULL(x) CHECK((x) != nullptr)
+
+#define ABSL_LOG_INTERNAL_CHECK(failure_message) \
+ ::absl::log_internal::LogMessageFatal()
+#define ABSL_LOG_INTERNAL_QCHECK(failure_message) \
+ ::absl::log_internal::LogMessageQuietlyFatal()
+#define ABSL_LOG_INTERNAL_CHECK_OK(val) \
+ for (::std::pair<const ::absl::Status *, ::std::string *> \
+ absl_log_internal_check_ok_goo; \
+ absl_log_internal_check_ok_goo.first = \
+ ::absl::log_internal::AsStatus(val), \
+ absl_log_internal_check_ok_goo.second = \
+ ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
+ ? nullptr \
+ : ::absl::status_internal::MakeCheckFailString( \
+ absl_log_internal_check_ok_goo.first, \
+ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#val " is OK")), \
+ !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \
+ ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_ok_goo.second) \
+ .InternalStream()
+#define ABSL_LOG_INTERNAL_QCHECK_OK(val) \
+ for (::std::pair<const ::absl::Status *, ::std::string *> \
+ absl_log_internal_check_ok_goo; \
+ absl_log_internal_check_ok_goo.first = \
+ ::absl::log_internal::AsStatus(val), \
+ absl_log_internal_check_ok_goo.second = \
+ ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
+ ? nullptr \
+ : ::absl::status_internal::MakeCheckFailString( \
+ absl_log_internal_check_ok_goo.first, \
+ ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(#val " is OK")), \
+ !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \
+ ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_check_ok_goo.second) \
+ .InternalStream()
+
+#define CHECK_OK(val) ABSL_LOG_INTERNAL_CHECK_OK(val)
+#define DCHECK_OK(val) ABSL_LOG_INTERNAL_CHECK_OK(val)
+#define QCHECK_OK(val) ABSL_LOG_INTERNAL_QCHECK_OK(val)
+
+#endif // ABSL_LOG_H
+)cc";
+
+constexpr const char TestingDefsHeader[] = R"cc(
+#pragma clang system_header
+
+#ifndef TESTING_DEFS_H
+#define TESTING_DEFS_H
+
+#include "absl_type_traits.h"
+#include "std_initializer_list.h"
+#include "std_string.h"
+#include "std_type_traits.h"
+#include "std_utility.h"
+
+namespace testing {
+struct AssertionResult {
+ template <typename T>
+ explicit AssertionResult(const T &res, bool enable_if = true) {}
+ ~AssertionResult();
+ operator bool() const;
+ template <typename T> AssertionResult &operator<<(const T &value);
+ const char *failure_message() const;
+};
+
+class TestPartResult {
+public:
+ enum Type { kSuccess, kNonFatalFailure, kFatalFailure, kSkip };
+};
+
+class Test {
+public:
+ virtual ~Test() = default;
+
+protected:
+ virtual void SetUp() {}
+};
+
+class Message {
+public:
+ template <typename T> Message &operator<<(const T &val);
+};
+
+namespace internal {
+class AssertHelper {
+public:
+ AssertHelper(TestPartResult::Type type, const char *file, int line,
+ const char *message);
+ void operator=(const Message &message) const;
+};
+
+class EqHelper {
+public:
+ template <typename T1, typename T2>
+ static AssertionResult Compare(const char *lhx, const char *rhx,
+ const T1 &lhs, const T2 &rhs);
+};
+
+#define GTEST_IMPL_CMP_HELPER_(op_name) \
+ template <typename T1, typename T2> \
+ AssertionResult CmpHelper##op_name(const char *expr1, const char *expr2, \
+ const T1 &val1, const T2 &val2);
+
+GTEST_IMPL_CMP_HELPER_(NE)
+GTEST_IMPL_CMP_HELPER_(LE)
+GTEST_IMPL_CMP_HELPER_(LT)
+GTEST_IMPL_CMP_HELPER_(GE)
+GTEST_IMPL_CMP_HELPER_(GT)
+
+#undef GTEST_IMPL_CMP_HELPER_
+
+std::string GetBoolAssertionFailureMessage(
+ const AssertionResult &assertion_result, const char *expression_text,
+ const char *actual_predicate_value, const char *expected_predicate_value);
+
+template <typename M> class PredicateFormatterFromMatcher {
+public:
+ template <typename T>
+ AssertionResult operator()(const char *value_text, const T &x) const;
+};
+
+template <typename M>
+inline PredicateFormatterFromMatcher<M>
+MakePredicateFormatterFromMatcher(M matcher) {
+ return PredicateFormatterFromMatcher<M>();
+}
+} // namespace internal
+
+namespace status {
+namespace internal_status {
+class IsOkMatcher {};
+
+class StatusIsMatcher {};
+
+class CanonicalStatusIsMatcher {};
+
+template <typename M> class IsOkAndHoldsMatcher {};
+
+} // namespace internal_status
+
+internal_status::IsOkMatcher IsOk();
+
+template <typename StatusCodeMatcher>
+internal_status::StatusIsMatcher StatusIs(StatusCodeMatcher &&code_matcher);
+
+template <typename StatusCodeMatcher>
+internal_status::CanonicalStatusIsMatcher
+CanonicalStatusIs(StatusCodeMatcher &&code_matcher);
+
+template <typename InnerMatcher>
+internal_status::IsOkAndHoldsMatcher<InnerMatcher> IsOkAndHolds(InnerMatcher m);
+} // namespace status
+
+class IsTrueMatcher {};
+IsTrueMatcher IsTrue();
+
+class IsFalseMatcher {};
+IsFalseMatcher IsFalse();
+
+} // namespace testing
+
+namespace absl_testing {
+namespace status_internal {
+class IsOkMatcher {};
+template <typename M> class IsOkAndHoldsMatcher {};
+class StatusIsMatcher {};
+class CanonicalStatusIsMatcher {};
+} // namespace status_internal
+status_internal::IsOkMatcher IsOk();
+template <typename InnerMatcher>
+status_internal::IsOkAndHoldsMatcher<InnerMatcher> IsOkAndHolds(InnerMatcher m);
+template <typename StatusCodeMatcher>
+status_internal::StatusIsMatcher StatusIs(StatusCodeMatcher &&code_matcher);
+
+template <typename StatusCodeMatcher>
+status_internal::CanonicalStatusIsMatcher
+CanonicalStatusIs(StatusCodeMatcher &&code_matcher);
+} // namespace absl_testing
+
+using testing::AssertionResult;
+#define EXPECT_TRUE(x) \
+ switch (0) \
+ case 0: \
+ default: \
+ if (const AssertionResult gtest_ar_ = AssertionResult(x)) { \
+ } else /* NOLINT */ \
+ ::testing::Message()
+#define EXPECT_FALSE(x) EXPECT_TRUE(!(x))
+
+#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ switch (0) \
+ case 0: \
+ default:
+
+#define GTEST_ASSERT_(expression, on_failure) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const ::testing::AssertionResult gtest_ar = (expression)) \
+ ; \
+ else \
+ on_failure(gtest_ar.failure_message())
+#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \
+ GTEST_ASSERT_(pred_format(#v1, v1), on_failure)
+#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \
+ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
+#define GTEST_MESSAGE_AT_(file, line, message, result_type) \
+ ::testing::internal::AssertHelper(result_type, file, line, message) = \
+ ::testing::Message()
+#define GTEST_MESSAGE_(message, result_type) \
+ GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
+#define GTEST_FATAL_FAILURE_(message) \
+ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
+#define GTEST_NONFATAL_FAILURE_(message) \
+ GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
+
+#define ASSERT_PRED_FORMAT1(pred_format, v1) \
+ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
+#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
+ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
+
+#define ASSERT_THAT(value, matcher) \
+ ASSERT_PRED_FORMAT1( \
+ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
+#define ASSERT_OK(x) ASSERT_THAT(x, ::testing::status::IsOk())
+
+#define EXPECT_PRED_FORMAT1(pred_format, v1) \
+ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
+ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_THAT(value, matcher) \
+ EXPECT_PRED_FORMAT1( \
+ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
+#define EXPECT_OK(expression) EXPECT_THAT(expression, ::testing::status::IsOk())
+
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const ::testing::AssertionResult gtest_ar_ = \
+ ::testing::AssertionResult(expression)) \
+ ; \
+ else \
+ fail(::testing::internal::GetBoolAssertionFailureMessage( \
+ gtest_ar_, text, #actual, #expected) \
+ .c_str())
+#define GTEST_ASSERT_TRUE(condition) \
+ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_FATAL_FAILURE_)
+#define GTEST_ASSERT_FALSE(condition) \
+ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
+ GTEST_FATAL_FAILURE_)
+#define ASSERT_TRUE(condition) GTEST_ASSERT_TRUE(condition)
+#define ASSERT_FALSE(condition) GTEST_ASSERT_FALSE(condition)
+
+#define EXPECT_EQ(x, y) \
+ EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, x, y)
+#define EXPECT_NE(x, y) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, x, y)
+#define EXPECT_LT(x, y) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, x, y)
+#define EXPECT_GT(x, y) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, x, y)
+#define EXPECT_LE(x, y) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, x, y)
+#define EXPECT_GE(x, y) \
+ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, x, y)
+
+#define ASSERT_EQ(x, y) \
+ ASSERT_PRED_FORMAT2(testing::internal::EqHelper::Compare, x, y)
+#define ASSERT_NE(x, y) \
+ ASSERT_PRED_FORMAT2(testing::internal::CmpHelperNE, x, y)
+#define ASSERT_LT(x, y) \
+ ASSERT_PRED_FORMAT2(testing::internal::CmpHelperLT, x, y)
+#define ASSERT_GT(x, y) \
+ ASSERT_PRED_FORMAT2(testing::internal::CmpHelperGT, x, y)
+#define ASSERT_LE(x, y) \
+ ASSERT_PRED_FORMAT2(testing::internal::CmpHelperLE, x, y)
+#define ASSERT_GE(x, y) \
+ ASSERT_PRED_FORMAT2(testing::internal::CmpHelperGE, x, y)
+
+#endif // TESTING_DEFS_H
+)cc";
+
std::vector<std::pair<std::string, std::string>> getMockHeaders() {
std::vector<std::pair<std::string, std::string>> Headers;
Headers.emplace_back("cstddef.h", CStdDefHeader);
@@ -1251,6 +2243,12 @@ std::vector<std::pair<std::string, std::string>> getMockHeaders() {
Headers.emplace_back("absl_type_traits.h", AbslTypeTraitsHeader);
Headers.emplace_back("absl_optional.h", AbslOptionalHeader);
Headers.emplace_back("base_optional.h", BaseOptionalHeader);
+ Headers.emplace_back("std_vector.h", StdVectorHeader);
+ Headers.emplace_back("std_pair.h", StdPairHeader);
+ Headers.emplace_back("status_defs.h", StatusDefsHeader);
+ Headers.emplace_back("statusor_defs.h", StatusOrDefsHeader);
+ Headers.emplace_back("absl_log.h", AbslLogHeader);
+ Headers.emplace_back("testing_defs.h", TestingDefsHeader);
return Headers;
}
diff --git a/clang/unittests/Basic/CMakeLists.txt b/clang/unittests/Basic/CMakeLists.txt
index 8c8baa5..f20c8db 100644
--- a/clang/unittests/Basic/CMakeLists.txt
+++ b/clang/unittests/Basic/CMakeLists.txt
@@ -6,6 +6,7 @@ add_distinct_clang_unittest(BasicTests
DiagnosticTest.cpp
FileEntryTest.cpp
FileManagerTest.cpp
+ LangOptionsTest.cpp
LineOffsetMappingTest.cpp
OffloadArchTest.cpp
SanitizersTest.cpp
diff --git a/clang/unittests/Basic/LangOptionsTest.cpp b/clang/unittests/Basic/LangOptionsTest.cpp
new file mode 100644
index 0000000..0d7d5ec
--- /dev/null
+++ b/clang/unittests/Basic/LangOptionsTest.cpp
@@ -0,0 +1,56 @@
+//===- unittests/Basic/LangOptionsTest.cpp --------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/LangOptions.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+TEST(LangOptsTest, CStdLang) {
+ LangOptions opts;
+ EXPECT_FALSE(opts.getCLangStd());
+ opts.GNUMode = 0;
+ opts.Digraphs = 1;
+ EXPECT_EQ(opts.getCLangStd(), 199409);
+ opts.C99 = 1;
+ EXPECT_EQ(opts.getCLangStd(), 199901);
+ opts.C11 = 1;
+ EXPECT_EQ(opts.getCLangStd(), 201112);
+ opts.C17 = 1;
+ EXPECT_EQ(opts.getCLangStd(), 201710);
+ opts.C23 = 1;
+ EXPECT_EQ(opts.getCLangStd(), 202311);
+ opts.C2y = 1;
+ EXPECT_EQ(opts.getCLangStd(), 202400);
+
+ EXPECT_FALSE(opts.getCPlusPlusLangStd());
+}
+
+TEST(LangOptsTest, CppStdLang) {
+ LangOptions opts;
+ EXPECT_FALSE(opts.getCPlusPlusLangStd());
+ opts.CPlusPlus = 1;
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 199711);
+ opts.CPlusPlus11 = 1;
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 201103);
+ opts.CPlusPlus14 = 1;
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 201402);
+ opts.CPlusPlus17 = 1;
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 201703);
+ opts.CPlusPlus20 = 1;
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 202002);
+ opts.CPlusPlus23 = 1;
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 202302);
+ opts.CPlusPlus26 = 1;
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 202400);
+
+ EXPECT_FALSE(opts.getCLangStd());
+}
+} // namespace
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 450c34f..b9ad930 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -19539,6 +19539,15 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
"int j = 2;",
Alignment);
+ verifyFormat("int abcdefghijk = 111;\n"
+ "auto lambda = [] {\n"
+ " int c = call(1, //\n"
+ " 2, //\n"
+ " 3, //\n"
+ " 4);\n"
+ "};",
+ Alignment);
+
verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n"
" typename B = very_long_type_name_1,\n"
" typename T_2 = very_long_type_name_2>\n"
@@ -19577,6 +19586,12 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
Alignment);
verifyFormat("auto aaaaaaaaaaaaaaaaaaaaa = {};\n"
"auto b = g([] {\n"
+ " return \"Hello \"\n"
+ " \"World\";\n"
+ "});",
+ Alignment);
+ verifyFormat("auto aaaaaaaaaaaaaaaaaaaaa = {};\n"
+ "auto b = g([] {\n"
" f();\n"
" return;\n"
"});",
@@ -19599,12 +19614,11 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
" ccc ? aaaaa : bbbbb,\n"
" dddddddddddddddddddddddddd);",
Alignment);
- // FIXME: https://llvm.org/PR53497
- // verifyFormat("auto aaaaaaaaaaaa = f();\n"
- // "auto b = f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n"
- // " ccc ? aaaaa : bbbbb,\n"
- // " dddddddddddddddddddddddddd);",
- // Alignment);
+ verifyFormat("auto aaaaaaaaaaaa = f();\n"
+ "auto b = f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " ccc ? aaaaa : bbbbb,\n"
+ " dddddddddddddddddddddddddd);",
+ Alignment);
// Confirm proper handling of AlignConsecutiveAssignments with
// BinPackArguments.
@@ -20192,6 +20206,11 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
" i = 3 //\n"
"};",
Alignment);
+ // When assignments are nested, each level should be aligned.
+ verifyFormat("float i2 = 0;\n"
+ "auto v = type{i2 = 1, //\n"
+ " i = 3};",
+ Alignment);
Alignment.AlignConsecutiveAssignments.Enabled = false;
verifyFormat(
@@ -20681,6 +20700,21 @@ TEST_F(FormatTest, AlignWithLineBreaks) {
"}",
Style);
+ verifyFormat("void foo() {\n"
+ " int myVar = 5;\n"
+ " double x = 3.14;\n"
+ " auto str = (\"Hello \"\n"
+ " \"World\");\n"
+ " auto s = (\"Hello \"\n"
+ " \"Again\");\n"
+ "}",
+ Style);
+
+ verifyFormat("A B = {\"Hello \"\n"
+ " \"World\"};\n"
+ "BYTE payload = 2;",
+ Style);
+
// clang-format off
verifyFormat("void foo() {\n"
" const int capacityBefore = Entries.capacity();\n"
@@ -20763,6 +20797,28 @@ TEST_F(FormatTest, AlignWithInitializerPeriods) {
"}",
Style);
+ // The lines inside the braces are supposed to be indented by
+ // BracedInitializerIndentWidth from the start of the line. They should not
+ // move with the opening brace.
+ verifyFormat("void foo2(void) {\n"
+ " BYTE p[1] = 1;\n"
+ " A B = {\n"
+ " .one_foooooooooooooooo = 2,\n"
+ " .two_fooooooooooooo = 3,\n"
+ " .three_fooooooooooooo = 4,\n"
+ " };\n"
+ " BYTE payload = 2;\n"
+ "}",
+ Style);
+
+ verifyFormat("auto aaaaaaaaaaaaaaaaaaaaa = {};\n"
+ "auto b = g([] {\n"
+ " x = {.one_foooooooooooooooo = 2, //\n"
+ " .two_fooooooooooooo = 3, //\n"
+ " .three_fooooooooooooo = 4};\n"
+ "});",
+ Style);
+
Style.AlignConsecutiveAssignments.Enabled = false;
Style.AlignConsecutiveDeclarations.Enabled = true;
verifyFormat("void foo3(void) {\n"
diff --git a/clang/unittests/StaticAnalyzer/SValTest.cpp b/clang/unittests/StaticAnalyzer/SValTest.cpp
index 1f4a18b..db4b01b 100644
--- a/clang/unittests/StaticAnalyzer/SValTest.cpp
+++ b/clang/unittests/StaticAnalyzer/SValTest.cpp
@@ -302,13 +302,13 @@ void foo(int x) {
ASSERT_FALSE(B.getType(Context).isNull());
const auto *BRecordType = dyn_cast<RecordType>(B.getType(Context));
ASSERT_NE(BRecordType, nullptr);
- EXPECT_EQ("TestStruct", BRecordType->getOriginalDecl()->getName());
+ EXPECT_EQ("TestStruct", BRecordType->getDecl()->getName());
SVal C = getByName("c");
ASSERT_FALSE(C.getType(Context).isNull());
const auto *CRecordType = dyn_cast<RecordType>(C.getType(Context));
ASSERT_NE(CRecordType, nullptr);
- EXPECT_EQ("TestUnion", CRecordType->getOriginalDecl()->getName());
+ EXPECT_EQ("TestUnion", CRecordType->getDecl()->getName());
auto D = getByName("d").getAs<nonloc::CompoundVal>();
ASSERT_TRUE(D.has_value());
@@ -322,7 +322,7 @@ void foo(int x) {
ASSERT_FALSE(LDT.isNull());
const auto *DRecordType = dyn_cast<RecordType>(LDT);
ASSERT_NE(DRecordType, nullptr);
- EXPECT_EQ("TestStruct", DRecordType->getOriginalDecl()->getName());
+ EXPECT_EQ("TestStruct", DRecordType->getDecl()->getName());
}
SVAL_TEST(GetStringType, R"(
@@ -351,7 +351,7 @@ void TestClass::foo() {
ASSERT_NE(APtrTy, nullptr);
const auto *ARecordType = dyn_cast<RecordType>(APtrTy->getPointeeType());
ASSERT_NE(ARecordType, nullptr);
- EXPECT_EQ("TestClass", ARecordType->getOriginalDecl()->getName());
+ EXPECT_EQ("TestClass", ARecordType->getDecl()->getName());
}
SVAL_TEST(GetFunctionPtrType, R"(
diff --git a/clang/unittests/Tooling/LookupTest.cpp b/clang/unittests/Tooling/LookupTest.cpp
index 4c49ebe..ed6f5d4 100644
--- a/clang/unittests/Tooling/LookupTest.cpp
+++ b/clang/unittests/Tooling/LookupTest.cpp
@@ -200,9 +200,9 @@ TEST(LookupTest, replaceNestedClassName) {
Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
// Filter Types by name since there are other `RecordTypeLoc` in the test
// file.
- if (Type.getOriginalDecl()->getQualifiedNameAsString() == "a::b::Foo") {
- EXPECT_EQ("x::Bar", replaceTypeLoc(Type.getOriginalDecl(),
- Type.getBeginLoc(), "::a::x::Bar"));
+ if (Type.getDecl()->getQualifiedNameAsString() == "a::b::Foo") {
+ EXPECT_EQ("x::Bar", replaceTypeLoc(Type.getDecl(), Type.getBeginLoc(),
+ "::a::x::Bar"));
}
};
Visitor.runOver("namespace a { namespace b {\n"
@@ -227,9 +227,9 @@ TEST(LookupTest, replaceNestedClassName) {
// `x::y::Foo` in c.cc [1], it should not make "Foo" at [0] ambiguous because
// it's not visible at [0].
Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
- if (Type.getOriginalDecl()->getQualifiedNameAsString() == "x::y::Old") {
- EXPECT_EQ("Foo", replaceTypeLoc(Type.getOriginalDecl(),
- Type.getBeginLoc(), "::x::Foo"));
+ if (Type.getDecl()->getQualifiedNameAsString() == "x::y::Old") {
+ EXPECT_EQ("Foo",
+ replaceTypeLoc(Type.getDecl(), Type.getBeginLoc(), "::x::Foo"));
}
};
Visitor.runOver(R"(
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
index 88cebb7..587a00d 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
@@ -24,7 +24,7 @@ public:
bool VisitRecordTypeLoc(RecordTypeLoc RTL) override {
if (!RTL)
return true;
- Match(RTL.getOriginalDecl()->getName(), RTL.getNameLoc());
+ Match(RTL.getDecl()->getName(), RTL.getNameLoc());
return true;
}
};
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
index 4181cd2..120b14b 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
@@ -18,7 +18,7 @@ public:
bool VisitRecordTypeLoc(RecordTypeLoc RTL) override {
if (!RTL)
return true;
- Match(RTL.getOriginalDecl()->getName(), RTL.getNameLoc());
+ Match(RTL.getDecl()->getName(), RTL.getNameLoc());
return true;
}